Merge m-c to inbound a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Thu, 20 Nov 2014 18:03:29 -0800
changeset 241124 b6946c2e8558a64884e02e9564283fce8f67df30
parent 241123 a90abd3ade72b4935526fa6d005550aa8f66e162 (current diff)
parent 241079 893013d8d71480a18ee3a475ceaff46a1937477b (diff)
child 241125 bbc87380fd6a1ef4c16cf619e8ba56a97241ba1e
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone36.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 m-c to inbound a=merge CLOSED TREE
toolkit/components/places/tests/unit/history/head_history.js
toolkit/components/places/tests/unit/history/test_remove.js
toolkit/components/places/tests/unit/history/xpcshell.ini
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
@@ -106,17 +106,17 @@
   <project name="platform/frameworks/native" path="frameworks/native" revision="b6018ccb81af66e0523a4bfdc45f0bd2ab472b55"/>
   <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="dbbe673145107e99883f62bafd70c5f43f11065c"/>
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="aac6c4bb59a6577c97cbda68699829b507b7490d"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="fbeca55f4695dd07c0291213403533b8fbca4885"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="a8449b1de00c313a4ca90d55af44c9b706b17926"/>
   <project name="platform/libcore" path="libcore" revision="e195beab082c09217318fc19250caeaf4c1bd800"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="feeb36c2bd4adfe285f98f5de92e0f3771b2c115"/>
   <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
-  <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="ee724654c72825f8d732ba45caf75ca59e06975d"/>
+  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="0e7c060db684b409616fe67ea433ef19f5634c60"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
   <project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>
   <project name="platform/system/media" path="system/media" revision="7ff72c2ea2496fa50b5e8a915e56e901c3ccd240"/>
   <project name="platform/system/netd" path="system/netd" revision="3ae56364946d4a5bf5a5f83f12f9a45a30398e33"/>
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
--- 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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a47dd04f8f66e42fd331711140f2c3e2fed0767d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
@@ -106,17 +106,17 @@
   <project name="platform/frameworks/native" path="frameworks/native" revision="2176649bcda07ff82ba6e83f3b5ee8b80f2c5cb1"/>
   <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="7a2d17bd2190556c9c804721ad7b19d45948bb1f"/>
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="eb6077f10ae6255a72337124188f0e08dcd10e3e"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="3b80c725cea54132df05d208930d91e00d19f999"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="01f436c51dc68aec7cc1c85fda6e6792b2a95066"/>
   <project name="platform/libcore" path="libcore" revision="9877ade9617bb0db6e59aa2a54719a9bc92600f3"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="46c96ace65eb1ccab05bf15b9bf8e53e443039af"/>
   <project name="platform/ndk" path="ndk" revision="cb5519af32ae7b4a9c334913a612462ecd04c5d0"/>
-  <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="99c9a644e84a1b0e0a5d240406753b6bc4caca54"/>
+  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="0e7c060db684b409616fe67ea433ef19f5634c60"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="6aa61f8557a22039a30b42b7f283996381fd625d"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
   <project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
   <project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
   <project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
   <project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
--- 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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a47dd04f8f66e42fd331711140f2c3e2fed0767d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
@@ -106,17 +106,17 @@
   <project name="platform/frameworks/native" path="frameworks/native" revision="5be7d8ca7bb5e193e092c39fd4f164189527b895"/>
   <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="dbbe673145107e99883f62bafd70c5f43f11065c"/>
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="f0c3b4edf597c40aae4ea311575f39c8bcf203df"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="9a60e685a9fb38a716f18a89cd872942f75b4706"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="adb52b35ecb523bd332854945c09828ee887e575"/>
   <project name="platform/libcore" path="libcore" revision="baf7d8068dd501cfa338d3a8b1b87216d6ce0571"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="50c4430e32849530ced32680fd6ee98963b3f7ac"/>
   <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
-  <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="a094aa8f160e211fb4994fdfaaac8a78aa6cc897"/>
+  <project name="platform_prebuilts_misc" path="prebuilts/misc" remote="b2g" revision="0e7c060db684b409616fe67ea433ef19f5634c60"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
   <project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
   <project name="platform/system/media" path="system/media" revision="20c2fb4c896aa59f2e8379d755f439dc59a5cf9b"/>
   <project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "936d69a5e13f39fcf9cc99bceb50c8c0de6aa0fa", 
+    "revision": "830d094e31350d07d6354deafbd58a19b2ac0236", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="1abe09b4925547699dfdb2d358aed019137c3aa6"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="d695e7cdcd162e779e15594054931c84dec34a95"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6a8f8bd05043e7b8f8e26ad390c82021b995ee4d"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3460,17 +3460,17 @@
           if (!event.isTrusted)
             return;
 
           var contentWin = event.target.defaultView;
           if (contentWin != contentWin.top)
             return;
 
           var tab = this._getTabForContentWindow(contentWin);
-          if (tab.hasAttribute("pending"))
+          if (!tab || tab.hasAttribute("pending"))
             return;
 
           var titleChanged = this.setTabTitle(tab);
           if (titleChanged && !tab.selected && !tab.hasAttribute("busy"))
             tab.setAttribute("titlechanged", "true");
         ]]>
       </handler>
       <handler event="oop-browser-crashed">
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -174,27 +174,25 @@ skip-if = e10s # Bug 866413 - PageInfo d
 skip-if = toolkit == "cocoa" || e10s # Bug 1102017 - middle-button mousedown on selected tab2 does not activate tab - Didn't expect [object XULElement], but got it
 [browser_bug462673.js]
 skip-if = e10s # Bug 1093404 - test expects sync window opening from content and is disappointed in that expectation
 [browser_bug477014.js]
 skip-if = e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al for e10s
 [browser_bug479408.js]
 skip-if = buildapp == 'mulet'
 [browser_bug481560.js]
-skip-if = e10s # Bug 1102018 - This bug attaches an event listener directly to the content, which then never gets called.
 [browser_bug484315.js]
 skip-if = e10s
 [browser_bug491431.js]
 skip-if = buildapp == 'mulet'
 [browser_bug495058.js]
 skip-if = e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al (and thus replaceTabWithWindow) for e10s
 [browser_bug517902.js]
 skip-if = e10s # Bug 866413 - PageInfo doesn't work in e10s
 [browser_bug519216.js]
-skip-if = e10s # Bug ?????? - some weird timing issue with progress listeners that fails intermittently
 [browser_bug520538.js]
 [browser_bug521216.js]
 [browser_bug533232.js]
 [browser_bug537013.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al for e10s (test calls replaceTabWithWindow)
 [browser_bug537474.js]
 skip-if = e10s # Bug 1102020 - test tries to use browserDOMWindow.openURI to open a link, and gets a null rv where it expects a window
 [browser_bug550565.js]
@@ -242,44 +240,41 @@ skip-if = true # Bug 1094312 - Disabling
 skip-if = e10s # Bug 653065 - Make the lightweight theme web installer ready for e10s
 [browser_bug594131.js]
 [browser_bug595507.js]
 skip-if = e10s # Bug 1093677 - automated form submission from the test doesn't seem to quite work yet
 [browser_bug596687.js]
 [browser_bug597218.js]
 [browser_bug609700.js]
 [browser_bug623155.js]
-skip-if = e10s # Bug ?????? - URLBar issues (apparently issues with redirection)
 [browser_bug623893.js]
 [browser_bug624734.js]
 [browser_bug633691.js]
-skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
 [browser_bug647886.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1093373 - Relies on browser.sessionHistory
 [browser_bug655584.js]
 skip-if = e10s
 [browser_bug664672.js]
 [browser_bug676619.js]
 skip-if = buildapp == 'mulet' || os == "mac" # mac: Intermittent failures, bug 925225
 [browser_bug678392.js]
-skip-if = e10s # Bug ?????? - Obscure non-windows failures ("Snapshot array has correct length of 1 after loading one page. - Got 0, expected 1" and more)
+skip-if = e10s # bug 1102331 - does focus things on the content window which break in e10s mode
 [browser_bug710878.js]
 skip-if = e10s # Bug 1100653 - test uses waitForFocus on content
 [browser_bug719271.js]
 skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug724239.js]
 [browser_bug734076.js]
 skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug735471.js]
 [browser_bug749738.js]
 skip-if = e10s # Bug 921935 - focusmanager issues with e10s
 [browser_bug763468_perwindowpb.js]
 skip-if = e10s
 [browser_bug767836_perwindowpb.js]
-skip-if = e10s # Bug ?????? - test reports a leaked nsGlobalWindow with e10s enabled.
 [browser_bug771331.js]
 [browser_bug783614.js]
 [browser_bug816527.js]
 skip-if = e10s # Bug 1093373 - relies on browser.sessionHistory
 [browser_bug817947.js]
 [browser_bug822367.js]
 [browser_bug832435.js]
 [browser_bug839103.js]
@@ -324,17 +319,16 @@ skip-if = buildapp == 'mulet' || e10s ||
 [browser_fxa_oauth.js]
 [browser_gestureSupport.js]
 skip-if = e10s # Bug 863514 - no gesture support.
 [browser_getshortcutoruri.js]
 [browser_hide_removing.js]
 [browser_homeDrop.js]
 skip-if = buildapp == 'mulet'
 [browser_identity_UI.js]
-skip-if = e10s # Bug ?????? - this test fails for obscure reasons on non-windows builds only.
 [browser_keywordBookmarklets.js]
 skip-if = e10s # Bug 1102025 - different principals for the bookmarklet only in e10s mode (unclear if test or 'real' issue)
 [browser_keywordSearch.js]
 skip-if = e10s # Bug 921957 - remote webprogress doesn't supply cancel method on the request object
 [browser_keywordSearch_postData.js]
 [browser_lastAccessedTab.js]
 skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bug 969405)
 [browser_locationBarCommand.js]
@@ -403,19 +397,17 @@ skip-if = buildapp == 'mulet' || e10s # 
 [browser_save_video_frame.js]
 [browser_scope.js]
 [browser_searchSuggestionUI.js]
 skip-if = e10s
 support-files =
   searchSuggestionUI.html
   searchSuggestionUI.js
 [browser_selectTabAtIndex.js]
-skip-if = e10s # Bug ?????? - no idea! "Accel+9 selects expected tab - Got 0, expected 9"
 [browser_star_hsts.js]
-skip-if = e10s # Bug ?????? - timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
 [browser_subframe_favicons_not_used.js]
 [browser_tabDrop.js]
 skip-if = buildapp == 'mulet' || e10s
 [browser_tabMatchesInAwesomebar_perwindowpb.js]
 skip-if = e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al for e10s (test calls gBrowser.swapBrowsersAndCloseOther)
 [browser_tab_drag_drop_perwindow.js]
 skip-if = buildapp == 'mulet'
 [browser_tab_dragdrop.js]
@@ -425,17 +417,16 @@ skip-if = buildapp == 'mulet' || e10s # 
 [browser_tabbar_big_widgets.js]
 skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux
                                        # Disabled on OS X because of bug 967917
 [browser_tabfocus.js]
 skip-if = e10s # Bug 921935 - focusmanager issues with e10s (test calls getFocusedElementForWindow with a content window)
 [browser_tabkeynavigation.js]
 skip-if = e10s
 [browser_tabopen_reflows.js]
-skip-if = e10s # Bug ?????? - test needs to be updated for e10s (captures a stack that isn't correct in e10s)
 [browser_tabs_isActive.js]
 skip-if = e10s # Bug 1100664 - test relies on linkedBrowser.docShell
 [browser_tabs_owner.js]
 [browser_trackingUI.js]
 support-files =
   trackingPage.html
   benignPage.html
 [browser_typeAheadFind.js]
--- a/browser/base/content/test/general/browser_bug481560.js
+++ b/browser/base/content/test/general/browser_bug481560.js
@@ -1,27 +1,21 @@
 function test() {
   waitForExplicitFinish();
 
-  var win = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
-
-  win.addEventListener("load", function () {
-    win.removeEventListener("load", arguments.callee, false);
-
-    win.content.addEventListener("focus", function () {
-      win.content.removeEventListener("focus", arguments.callee, false);
-
+  whenNewWindowLoaded(null, function (win) {
+    waitForFocus(function () {
       function onTabClose() {
         ok(false, "shouldn't have gotten the TabClose event for the last tab");
       }
       var tab = win.gBrowser.selectedTab;
       tab.addEventListener("TabClose", onTabClose, false);
 
       EventUtils.synthesizeKey("w", { accelKey: true }, win);
 
       ok(win.closed, "accel+w closed the window immediately");
 
       tab.removeEventListener("TabClose", onTabClose, false);
 
       finish();
-    }, false);
-  }, false);
+    }, win);
+  });
 }
--- a/browser/base/content/test/general/browser_bug633691.js
+++ b/browser/base/content/test/general/browser_bug633691.js
@@ -1,22 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 function test() {
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   // Open a html page with about:certerror in an iframe
-  window.content.addEventListener("load", testIframeCert, true);
+  gBrowser.selectedBrowser.addEventListener("load", testIframeCert, true);
   content.location = "data:text/html,<iframe width='700' height='700' src='about:certerror'></iframe>";
 }
 
-function testIframeCert() {
-  window.content.removeEventListener("load", testIframeCert, true);
+function testIframeCert(e) {
+  if (e.target.location.href == "about:blank") {
+    return;
+  }
+  gBrowser.selectedBrowser.removeEventListener("load", testIframeCert, true);
   // Confirm that the expert section is hidden
   var doc = gBrowser.contentDocument.getElementsByTagName('iframe')[0].contentDocument;
   var eC = doc.getElementById("expertContent");
   ok(eC, "Expert content should exist")
   ok(eC.hasAttribute("hidden"), "Expert content should be hidded by default");
 
   // Clean up
   gBrowser.removeCurrentTab();
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -101,17 +101,17 @@ function setJSONPref(aName, aValue) {
 }
 
 function getJSONPref(aName) {
   let value = Services.prefs.getCharPref(aName);
   return !!value ? JSON.parse(value) : null;
 }
 
 let gHawkClient = null;
-let gLocalizedStrings = null;
+let gLocalizedStrings = new Map();
 let gFxAEnabled = true;
 let gFxAOAuthClientPromise = null;
 let gFxAOAuthClient = null;
 let gErrors = new Map();
 let gLastWindowId = 0;
 let gConversationWindowData = new Map();
 
 /**
@@ -290,22 +290,22 @@ let MozLoopServiceInternal = {
     } else if (error.code >= 500 && error.code < 600) {
       messageString = "service_not_available";
       detailsString = "try_again_later";
       detailsButtonLabelString = "retry_button";
     } else {
       messageString = "generic_failure_title";
     }
 
-    error.friendlyMessage = this.localizedStrings[messageString].textContent;
+    error.friendlyMessage = this.localizedStrings.get(messageString);
     error.friendlyDetails = detailsString ?
-                              this.localizedStrings[detailsString].textContent :
+                              this.localizedStrings.get(detailsString) :
                               null;
     error.friendlyDetailsButtonLabel = detailsButtonLabelString ?
-                                         this.localizedStrings[detailsButtonLabelString].textContent :
+                                         this.localizedStrings.get(detailsButtonLabelString) :
                                          null;
 
     error.friendlyDetailsButtonCallback = actionCallback || detailsButtonCallback || null;
 
     gErrors.set(errorType, error);
     this.notifyStatusChanged();
   },
 
@@ -677,43 +677,32 @@ let MozLoopServiceInternal = {
         throw error;
       });
   },
 
   /**
    * A getter to obtain and store the strings for loop. This is structured
    * for use by l10n.js.
    *
-   * @returns {Object} a map of element ids with attributes to set.
+   * @returns {Map} a map of element ids with localized string values
    */
   get localizedStrings() {
-    if (gLocalizedStrings)
+    if (gLocalizedStrings.size)
       return gLocalizedStrings;
 
-    var stringBundle =
-      Services.strings.createBundle('chrome://browser/locale/loop/loop.properties');
-
-    var map = {};
-    var enumerator = stringBundle.getSimpleEnumeration();
-    while (enumerator.hasMoreElements()) {
-      var string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
+    let stringBundle =
+      Services.strings.createBundle("chrome://browser/locale/loop/loop.properties");
 
-      // 'textContent' is the default attribute to set if none are specified.
-      var key = string.key, property = 'textContent';
-      var i = key.lastIndexOf('.');
-      if (i >= 0) {
-        property = key.substring(i + 1);
-        key = key.substring(0, i);
-      }
-      if (!(key in map))
-        map[key] = {};
-      map[key][property] = string.value;
+    let enumerator = stringBundle.getSimpleEnumeration();
+    while (enumerator.hasMoreElements()) {
+      let string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
+      gLocalizedStrings.set(string.key, string.value);
     }
 
-    return gLocalizedStrings = map;
+    return gLocalizedStrings;
   },
 
   /**
    * Saves loop logs to the saved-telemetry-pings folder.
    *
    * @param {Object} pc The peerConnection in question.
    */
   stageForTelemetryUpload: function(window, pc) {
@@ -1147,31 +1136,30 @@ this.MozLoopService = {
    * @param {Integer} expiryTimeSeconds The seconds since epoch of the expiry time
    *                                    of the url.
    */
   noteCallUrlExpiry: function(expiryTimeSeconds) {
     MozLoopServiceInternal.expiryTimeSeconds = expiryTimeSeconds;
   },
 
   /**
-   * Returns the strings for the specified element. Designed for use
-   * with l10n.js.
+   * Returns the strings for the specified element. Designed for use with l10n.js.
    *
    * @param {key} The element id to get strings for.
-   * @return {String} A JSON string containing the localized
-   *                  attribute/value pairs for the element.
+   * @return {String} A JSON string containing the localized attribute/value pairs
+   *                  for the element.
    */
   getStrings: function(key) {
-      var stringData = MozLoopServiceInternal.localizedStrings;
-      if (!(key in stringData)) {
-        log.error("No string found for key: ", key);
-        return "";
-      }
+    var stringData = MozLoopServiceInternal.localizedStrings;
+    if (!stringData.has(key)) {
+      log.error("No string found for key: ", key);
+      return "";
+    }
 
-      return JSON.stringify(stringData[key]);
+    return JSON.stringify({ textContent: stringData.get(key) });
   },
 
   /**
    * Returns a new GUID (UUID) in curly braces format.
    */
   generateUUID: function() {
     return uuidgen.generateUUID().toString();
   },
--- a/browser/components/loop/content/shared/css/contacts.css
+++ b/browser/components/loop/content/shared/css/contacts.css
@@ -37,30 +37,30 @@
   display: flex;
   flex-direction: row;
   align-items: center;
   color: #666;
 }
 
 .contact-separator {
   height: 24px;
-  background: #eee;
+  background-color: #eee;
   color: #888;
 }
 
 .contact:not(:first-child) {
   border-top: 1px solid #ddd;
 }
 
 .contact-separator:not(:first-child) {
   border-top: 1px solid #ccc;
 }
 
 .contact:hover {
-  background: #eee;
+  background-color: #eee;
 }
 
 .contact:hover > .icons {
   display: block;
   z-index: 1;
 }
 
 .contact > .details {
@@ -75,17 +75,17 @@
    * a flex value equivalent to the maximum pixel value to avoid the resizing
    * to happen. Consider this a hack. */
   flex: 190;
 }
 
 .contact > .avatar {
   width: 40px;
   height: 40px;
-  background: #ccc;
+  background-color: #ccc;
   border-radius: 50%;
   margin-right: 10px;
   overflow: hidden;
   box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
   background-image: url("../img/audio-call-avatar.svg");
   background-repeat: no-repeat;
   background-color: #4ba6e7;
   background-size: contain;
@@ -140,19 +140,19 @@
   font-size: 11px;
   line-height: 16px;
 }
 
 .icons {
   cursor: pointer;
   display: none;
   margin-left: auto;
-  padding: 12px 10px;
+  padding: 10px;
   border-radius: 2px;
-  background: #5bc0a4;
+  background-color: #5bc0a4;
   color: #fff;
   -moz-user-select: none;
 }
 
 .icons:hover {
   background-color: #47b396;
 }
 
--- a/browser/components/loop/jar.mn
+++ b/browser/components/loop/jar.mn
@@ -86,22 +86,24 @@ browser.jar:
 #else
   content/browser/loop/shared/libs/react-0.11.2.js    (content/shared/libs/react-0.11.2-prod.js)
 #endif
   content/browser/loop/shared/libs/lodash-2.4.1.js    (content/shared/libs/lodash-2.4.1.js)
   content/browser/loop/shared/libs/jquery-2.1.0.js    (content/shared/libs/jquery-2.1.0.js)
   content/browser/loop/shared/libs/backbone-1.1.2.js  (content/shared/libs/backbone-1.1.2.js)
 
   # Shared sounds
-  content/browser/loop/shared/sounds/ringtone.ogg     (content/shared/sounds/ringtone.ogg)
-  content/browser/loop/shared/sounds/connecting.ogg   (content/shared/sounds/connecting.ogg)
-  content/browser/loop/shared/sounds/connected.ogg    (content/shared/sounds/connected.ogg)
-  content/browser/loop/shared/sounds/terminated.ogg   (content/shared/sounds/terminated.ogg)
-  content/browser/loop/shared/sounds/room-joined.ogg  (content/shared/sounds/room-joined.ogg)
-  content/browser/loop/shared/sounds/failure.ogg      (content/shared/sounds/failure.ogg)
+  content/browser/loop/shared/sounds/ringtone.ogg       (content/shared/sounds/ringtone.ogg)
+  content/browser/loop/shared/sounds/connecting.ogg     (content/shared/sounds/connecting.ogg)
+  content/browser/loop/shared/sounds/connected.ogg      (content/shared/sounds/connected.ogg)
+  content/browser/loop/shared/sounds/terminated.ogg     (content/shared/sounds/terminated.ogg)
+  content/browser/loop/shared/sounds/room-joined.ogg    (content/shared/sounds/room-joined.ogg)
+  content/browser/loop/shared/sounds/room-joined-in.org (content/shared/sounds/room-joined-in.ogg)
+  content/browser/loop/shared/sounds/room-left.org      (content/shared/sounds/room-left.ogg)
+  content/browser/loop/shared/sounds/failure.ogg        (content/shared/sounds/failure.ogg)
 
   # Partner SDK assets
   content/browser/loop/libs/sdk.js                                                    (content/shared/libs/sdk.js)
   content/browser/loop/sdk-content/css/ot.css                                 (content/shared/libs/sdk-content/css/ot.css)
   content/browser/loop/sdk-content/js/dynamic_config.min.js                   (content/shared/libs/sdk-content/js/dynamic_config.min.js)
   content/browser/loop/sdk-content/images/rtc/access-denied-chrome.png        (content/shared/libs/sdk-content/images/rtc/access-denied-chrome.png)
   content/browser/loop/sdk-content/images/rtc/access-denied-copy-firefox.png  (content/shared/libs/sdk-content/images/rtc/access-denied-copy-firefox.png)
   content/browser/loop/sdk-content/images/rtc/access-denied-firefox.png       (content/shared/libs/sdk-content/images/rtc/access-denied-firefox.png)
--- a/browser/components/loop/test/mochitest/head.js
+++ b/browser/components/loop/test/mochitest/head.js
@@ -183,17 +183,17 @@ function promiseOAuthGetRegistration(bas
     xhr.responseType = "json";
     xhr.addEventListener("load", () => resolve(xhr));
     xhr.addEventListener("error", reject);
     xhr.send();
   });
 }
 
 function getLoopString(stringID) {
-  return MozLoopServiceInternal.localizedStrings[stringID].textContent;
+  return MozLoopServiceInternal.localizedStrings.get(stringID);
 }
 
 /**
  * This is used to fake push registration and notifications for
  * MozLoopService tests. There is only one object created per test instance, as
  * once registration has taken place, the object cannot currently be changed.
  */
 let mockPushHandler = {
--- a/browser/components/loop/test/xpcshell/head.js
+++ b/browser/components/loop/test/xpcshell/head.js
@@ -68,17 +68,17 @@ function waitForCondition(aConditionFn, 
   }
   let deferred = Promise.defer();
   let tries = 0;
   tryAgain();
   return deferred.promise;
 }
 
 function getLoopString(stringID) {
-  return MozLoopServiceInternal.localizedStrings[stringID].textContent;
+  return MozLoopServiceInternal.localizedStrings.get(stringID);
 }
 
 /**
  * This is used to fake push registration and notifications for
  * MozLoopService tests. There is only one object created per test instance, as
  * once registration has taken place, the object cannot currently be changed.
  */
 let mockPushHandler = {
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -69,16 +69,26 @@ const FMM_MESSAGES = [
   // SSTabRestored at this time.
   "SessionStore:restoreDocumentComplete",
 
   // A tab that is being restored was reloaded. We call restoreTabContent to
   // finish restoring it right away.
   "SessionStore:reloadPendingTab",
 ];
 
+// The list of messages we accept from <xul:browser>s that have no tab
+// assigned. Those are for example the ones that preload about:newtab pages.
+const FMM_NOTAB_MESSAGES = new Set([
+  // For a description see above.
+  "SessionStore:setupSyncHandler",
+
+  // For a description see above.
+  "SessionStore:update",
+]);
+
 // Messages that will be received via the Parent Process Message Manager.
 const PPMM_MESSAGES = [
   // A tab is being revived from the crashed state. The sender of this
   // message should actually be running in the parent process, since this
   // will be the crashed tab interface. We use the Child and Parent Process
   // Message Managers because the message is sent during framescript unload
   // when the Frame Message Manager is not available.
   "SessionStore:RemoteTabRevived",
@@ -600,19 +610,22 @@ let SessionStoreInternal = {
       return;
     }
 
     // If we got here, that means we're dealing with a frame message
     // manager message, so the target will be a <xul:browser>.
     var browser = aMessage.target;
     var win = browser.ownerDocument.defaultView;
     let tab = win.gBrowser.getTabForBrowser(browser);
-    if (!tab) {
-      // Ignore messages from <browser> elements that are not tabs.
-      return;
+
+    // Ensure we receive only specific messages from <xul:browser>s that
+    // have no tab assigned, e.g. the ones that preload aobut:newtab pages.
+    if (!tab && !FMM_NOTAB_MESSAGES.has(aMessage.name)) {
+      throw new Error(`received unexpected message '${aMessage.name}' ` +
+                      `from a browser that has no tab`);
     }
 
     switch (aMessage.name) {
       case "SessionStore:setupSyncHandler":
         TabState.setSyncHandler(browser, aMessage.objects.handler);
         break;
       case "SessionStore:update":
         if (this._crashedBrowsers.has(browser.permanentKey)) {
@@ -686,17 +699,17 @@ let SessionStoreInternal = {
       case "SessionStore:reloadPendingTab":
         if (this.isCurrentEpoch(browser, aMessage.data.epoch)) {
           if (tab && browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE) {
             this.restoreTabContent(tab);
           }
         }
         break;
       default:
-        debug(`received unknown message '${aMessage.name}'`);
+        throw new Error(`received unknown message '${aMessage.name}'`);
         break;
     }
   },
 
   /**
    * Record telemetry measurements stored in an object.
    * @param telemetry
    *        {histogramID: value, ...} An object mapping histogramIDs to the
--- a/browser/devtools/framework/toolbox-options.js
+++ b/browser/devtools/framework/toolbox-options.js
@@ -288,23 +288,17 @@ OptionsPanel.prototype = {
   /**
    * Similar to `populatePrefs`, except we want more
    * special rules for the browser theme button.
    */
   setupBrowserThemeButton: function() {
     let checkbox = this.panelDoc.getElementById("devtools-browser-theme");
 
     checkbox.addEventListener("command", function() {
-      let data = {
-        pref: DEVEDITION_THEME_PREF,
-        newValue: this.checked
-      };
-      data.oldValue = GetPref(data.pref);
-      SetPref(data.pref, data.newValue);
-      gDevTools.emit("pref-changed", data);
+      setPrefAndEmit(DEVEDITION_THEME_PREF, this.checked);
     }.bind(checkbox));
 
     this.updateBrowserThemeButton();
   },
 
   /**
    * Called on theme changed via observer of "devedition-theme-state-changed".
    */
@@ -337,68 +331,46 @@ OptionsPanel.prototype = {
     CustomizeMode.prototype.toggleDevEditionTheme.call(this, enabled);
   },
 
   populatePreferences: function() {
     let prefCheckboxes = this.panelDoc.querySelectorAll("checkbox[data-pref]");
     for (let checkbox of prefCheckboxes) {
       checkbox.checked = GetPref(checkbox.getAttribute("data-pref"));
       checkbox.addEventListener("command", function() {
-        let data = {
-          pref: this.getAttribute("data-pref"),
-          newValue: this.checked
-        };
-        data.oldValue = GetPref(data.pref);
-        SetPref(data.pref, data.newValue);
-        gDevTools.emit("pref-changed", data);
+        setPrefAndEmit(this.getAttribute("data-pref"), this.checked);
       }.bind(checkbox));
     }
     let prefRadiogroups = this.panelDoc.querySelectorAll("radiogroup[data-pref]");
     for (let radiogroup of prefRadiogroups) {
       let selectedValue = GetPref(radiogroup.getAttribute("data-pref"));
       for (let radio of radiogroup.childNodes) {
         radiogroup.selectedIndex = -1;
         if (radio.getAttribute("value") == selectedValue) {
           radiogroup.selectedItem = radio;
           break;
         }
       }
       radiogroup.addEventListener("select", function() {
-        let data = {
-          pref: this.getAttribute("data-pref"),
-          newValue: this.selectedItem.getAttribute("value")
-        };
-
-        data.oldValue = GetPref(data.pref);
-        SetPref(data.pref, data.newValue);
-
-        if (data.newValue != data.oldValue) {
-          gDevTools.emit("pref-changed", data);
-        }
+        setPrefAndEmit(this.getAttribute("data-pref"), this.selectedItem.getAttribute("value"));
       }.bind(radiogroup));
     }
     let prefMenulists = this.panelDoc.querySelectorAll("menulist[data-pref]");
     for (let menulist of prefMenulists) {
       let pref = GetPref(menulist.getAttribute("data-pref"));
       let menuitems = menulist.querySelectorAll("menuitem");
       for (let menuitem of menuitems) {
         let value = menuitem.value;
         if (value == pref) { // non strict check to allow int values.
           menulist.selectedItem = menuitem;
           break;
         }
       }
       menulist.addEventListener("command", function() {
-        let data = {
-          pref: this.getAttribute("data-pref"),
-          newValue: this.value
-        };
-        data.oldValue = GetPref(data.pref);
-        SetPref(data.pref, data.newValue);
-        gDevTools.emit("pref-changed", data);
+        setPrefAndEmit(this.getAttribute("data-pref"), this.value);
       }.bind(menulist));
     }
 
     this.target.client.attachTab(this.target.activeTab._actor, (response) => {
       this._origJavascriptEnabled = response.javascriptEnabled;
 
       this._populateDisableJSCheckbox();
     });
@@ -493,8 +465,22 @@ OptionsPanel.prototype = {
       deferred.resolve();
     }, true);
 
     Services.obs.removeObserver(this, kDeveditionChangedNotification);
 
     return deferred.promise;
   }
 };
+
+/* Set a pref and emit the pref-changed event if needed. */
+function setPrefAndEmit(prefName, newValue) {
+  let data = {
+    pref: prefName,
+    newValue: newValue
+  };
+  data.oldValue = GetPref(data.pref);
+  SetPref(data.pref, data.newValue);
+
+  if (data.newValue != data.oldValue) {
+    gDevTools.emit("pref-changed", data);
+  }
+}
--- a/browser/devtools/styleinspector/computed-view.js
+++ b/browser/devtools/styleinspector/computed-view.js
@@ -569,17 +569,20 @@ CssHtmlTree.prototype = {
     CssHtmlTree.propertyNames = [];
 
     // Here we build and cache a list of css properties supported by the browser
     // We could use any element but let's use the main document's root element
     let styles = this.styleWindow.getComputedStyle(this.styleDocument.documentElement);
     let mozProps = [];
     for (let i = 0, numStyles = styles.length; i < numStyles; i++) {
       let prop = styles.item(i);
-      if (prop.charAt(0) == "-") {
+      if (prop.startsWith("--")) {
+        // Skip any CSS variables used inside of browser CSS files
+        continue;
+      } else if (prop.startsWith("-")) {
         mozProps.push(prop);
       } else {
         CssHtmlTree.propertyNames.push(prop);
       }
     }
 
     CssHtmlTree.propertyNames.sort();
     CssHtmlTree.propertyNames.push.apply(CssHtmlTree.propertyNames,
--- a/browser/themes/shared/devtools/canvasdebugger.inc.css
+++ b/browser/themes/shared/devtools/canvasdebugger.inc.css
@@ -10,26 +10,18 @@
 %define gutterWidth 3em
 %define gutterPaddingStart 22px
 
 /* Reload and waiting notices */
 
 .notice-container {
   margin-top: -50vh;
   font-size: 120%;
-}
-
-.theme-dark .notice-container {
-  background-color: #343c45; /* Toolbars */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .notice-container {
-  background-color: #f0f1f2; /* Toolbars */
-  color: #585959; /* Grey foreground text */
+  background-color: var(--theme-toolbar-background);
+  color: var(--theme-body-color-alt);
 }
 
 #empty-notice > button {
   min-width: 30px;
   min-height: 28px;
   margin: 0;
   list-style-image: url(profiler-stopwatch.svg);
 }
@@ -107,24 +99,19 @@
   font-size: 80%;
 }
 
 .snapshot-item-save {
   padding-bottom: 2px;
   font-size: 90%;
 }
 
-.theme-dark .snapshot-item-calls,
-.theme-dark .snapshot-item-save {
-  color: #b6babf; /* Foreground (Text) - Grey */
-}
-
-.theme-light .snapshot-item-calls,
-.theme-light .snapshot-item-save {
-  color: #585959; /* Foreground (Text) - Grey */
+.snapshot-item-calls,
+.snapshot-item-save {
+  color: var(--theme-body-color-alt);
 }
 
 .snapshot-item-save {
   text-decoration: underline;
   cursor: pointer;
 }
 
 .snapshot-item-save[disabled=true] {
@@ -277,76 +264,57 @@
 }
 
 @media (min-resolution: 2dppx) {
   .selected .call-item-gutter {
     background-image: url("editor-debug-location@2x.png");
   }
 }
 
-.theme-dark .call-item-gutter {
-  background-color: #181d20;
-  color: #5f7387;
-  border-color: #000;
-}
-
-.theme-light .call-item-gutter {
-  background-color: #f7f7f7;
-  color: #667380;
-  border-color: #aaa;
+.call-item-gutter {
+  background-color: var(--theme-sidebar-background);
+  color: var(--theme-content-color3);
+  border-color: var(--theme-splitter-color);
 }
 
 .call-item-index {
   text-align: end;
 }
 
-.theme-dark .call-item-context {
-  color: #eb5368; /* Highlight Orange */
+.call-item-context {
+  color: var(--theme-highlight-orange);
 }
 
-.theme-light .call-item-context {
-  color: #f13c00; /* Highlight Orange */
-}
-
-.theme-dark .call-item-name {
-  color: #46afe3; /* Highlight Blue */
-}
-
-.theme-light .call-item-name {
-  color: #0088cc; /* Highlight Blue */
+.call-item-name {
+  color: var(--theme-highlight-blue);
 }
 
 .call-item-location {
   -moz-padding-start: 2px;
   -moz-padding-end: 6px;
   text-align: end;
   cursor: pointer;
+  color: var(--theme-highlight-bluegrey);
 }
 
-.theme-dark .call-item-location:hover {
-  color: #0088cc; /* Highlight Blue */
-}
-
-.theme-light .call-item-location:hover {
-  color: #46afe3; /* Highlight Blue */
+.call-item-location:hover {
+  color: var(--theme-highlight-blue);
 }
 
 .call-item-view:hover .call-item-location,
 .call-item-view[expanded] .call-item-location {
   text-decoration: underline;
 }
 
 .theme-dark .call-item-location {
   border-color: #111;
-  color: #5e88b0; /* Highlight Blue-Grey */
 }
 
 .theme-light .call-item-location {
   border-color: #eee;
-  color: #5f88b0; /* Highlight Blue-Grey */
 }
 
 .call-item-stack {
   -moz-padding-start: calc(@gutterWidth@ + @gutterPaddingStart@);
   padding-bottom: 10px;
 }
 
 .theme-dark .call-item-stack {
@@ -365,38 +333,26 @@
 .call-item-stack-fn-location {
   -moz-padding-start: 2px;
   -moz-padding-end: 6px;
   text-align: end;
   cursor: pointer;
   text-decoration: underline;
 }
 
-.theme-dark .call-item-stack-fn-name {
-  color: #a9bacb; /* Content (Text) - Light */
-}
-
-.theme-light .call-item-stack-fn-name {
-  color: #667380; /* Content (Text) - Dark Grey */
+.call-item-stack-fn-name {
+  color: var(--theme-content-color3);
 }
 
-.theme-dark .call-item-stack-fn-location {
-  color: #5e88b0; /* Highlight Blue-Grey */
+.call-item-stack-fn-location {
+  color: var(--theme-highlight-bluegrey);
 }
 
-.theme-light .call-item-stack-fn-location {
-  color: #5e88b0; /* Highlight Blue-Grey */
-}
-
-.theme-dark .call-item-stack-fn-location:hover {
-  color: #0088cc; /* Highlight Blue */
-}
-
-.theme-light .call-item-stack-fn-location:hover {
-  color: #46afe3; /* Highlight Blue */
+.call-item-stack-fn-location:hover {
+  color: var(--theme-highlight-blue);
 }
 
 #calls-list .selected .call-item-contents > label:not(.call-item-gutter) {
   /* Text inside a selected item should not be custom colored. */
   color: inherit !important;
 }
 
 /* Rendering preview */
@@ -460,22 +416,22 @@
 /* Snapshot filmstrip */
 
 #snapshot-filmstrip {
   overflow: hidden;
 }
 
 .theme-dark #snapshot-filmstrip {
   border-top: 1px solid #000;
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-light #snapshot-filmstrip {
   border-top: 1px solid #aaa;
-  color: #585959; /* Grey foreground text */
+  color: var(--theme-body-color-alt);
 }
 
 .filmstrip-thumbnail {
   image-rendering: -moz-crisp-edges;
   background-image: @checkerboardPattern@;
   background-size: 12px 12px, 12px 12px;
   background-position: 0px -1px, 6px 5px;
   background-repeat: repeat, repeat;
@@ -493,31 +449,19 @@
 .theme-dark .filmstrip-thumbnail {
   background-color: @darkCheckerboardBackground@;
 }
 
 .theme-light .filmstrip-thumbnail {
   background-color: @lightCheckerboardBackground@;
 }
 
-.theme-dark .filmstrip-thumbnail {
-  -moz-border-end: 1px solid #000;
+.filmstrip-thumbnail {
+  -moz-border-end: 1px solid var(--theme-splitter-color)
 }
 
-.theme-light .filmstrip-thumbnail {
-  -moz-border-end: 1px solid #aaa;
-}
-
-.theme-dark #snapshot-filmstrip > .filmstrip-thumbnail:hover,
-.theme-dark #snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
-  border: 1px solid #46afe3; /* Highlight Blue */
+#snapshot-filmstrip > .filmstrip-thumbnail:hover,
+#snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
+  border: 1px solid var(--theme-highlight-blue);
   margin: 0 0 0 -1px;
   padding: 0;
   opacity: 0.66;
 }
-
-.theme-light #snapshot-filmstrip > .filmstrip-thumbnail:hover,
-.theme-light #snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
-  border: 1px solid #0088cc; /* Highlight Blue */
-  margin: 0 0 0 -1px;
-  padding: 0;
-  opacity: 0.66;
-}
--- a/browser/themes/shared/devtools/dark-theme.css
+++ b/browser/themes/shared/devtools/dark-theme.css
@@ -1,105 +1,130 @@
 /* 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/. */
 
 /* According to:
  * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
  */
+:root {
+  --theme-body-background: #14171a;
+  --theme-sidebar-background: #181d20;
+  --theme-contrast-background: #b28025;
+
+  --theme-tab-toolbar-background: #252c33;
+  --theme-toolbar-background: #343c45;
+  --theme-selection-background: #1d4f73;
+  --theme-selection-color: #f5f7fa;
+  --theme-splitter-color: black;
+  --theme-comment: #5c6773;
+
+  --theme-body-color: #a9bacb;
+  --theme-body-color-alt: #b6babf;
+  --theme-content-color1: #a9bacb;
+  --theme-content-color2: #8fa1b2;
+  --theme-content-color3: #667380;
+
+  --theme-highlight-green: #5c9966;
+  --theme-highlight-blue: #3689b2;
+  --theme-highlight-bluegrey: #5e88b0;
+  --theme-highlight-purple: #6270b2;
+  --theme-highlight-lightorange: #a18650;
+  --theme-highlight-orange: #b26b47;
+  --theme-highlight-red: #bf5656;
+  --theme-highlight-pink: #a673bf;
+}
+
 .theme-body {
-  background: #14171a;
-  color: #a9bacb;
+  background: var(--theme-body-background);
+  color: var(--theme-body-color);
 }
 
 .theme-sidebar {
-  background: #181d20;
-  color: #a9bacb;
+  background: var(--theme-sidebar-background);
+  color: var(--theme-content-color1);
 }
 
 ::-moz-selection {
-  background-color: #1d4f73;
-  color: #f5f7fa;
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 .theme-bg-darker {
   background-color: rgba(0,0,0,0.5);
 }
 
 .theme-selected,
 .CodeMirror-hint-active {
-  background-color: #1d4f73;
-  color: #f5f7fa; /* Light foreground text */
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 .theme-bg-contrast,
-.variable-or-property:not([overridden])[changed] { /* contrast bg color to attract attention on a container */
-  background: #B28025; /* Background - Attention */
+.variable-or-property:not([overridden])[changed] {
+  background: var(--theme-contrast-background);
 }
 
 .theme-link,
-.cm-s-mozilla .cm-link { /* blue */
-  color: #3689b2;
+.cm-s-mozilla .cm-link {
+  color: var(--theme-highlight-blue);
 }
 
 /*
  * FIXME: http://bugzil.la/575675 CSS links without :visited set cause assertion
  * failures in debug builds.
  */
 .theme-link:visited,
 .cm-s-mozilla .cm-link:visited,
-.CodeMirror-Tern-type { /* blue */
-  color: #3689b2;
+.CodeMirror-Tern-type {
+  color: var(--theme-highlight-blue);
 }
 
 
 .theme-comment,
 .cm-s-mozilla .cm-meta,
 .cm-s-mozilla .cm-hr,
 .cm-s-mozilla .cm-comment,
 .variable-or-property .token-undefined,
-.variable-or-property .token-null { /* grey */
-  color: #5c6773;
-}
-
+.variable-or-property .token-null,
 .CodeMirror-Tern-completion-unknown:before {
-  background-color: #5c6773;
+  color: var(--theme-comment);
 }
 
 .theme-gutter {
   background-color: #0f171f;
-  color: #667380;
+  color: var(--theme-content-color3);
   border-color: #303b47;
 }
 
 .theme-separator { /* grey */
   border-color: #303b47;
 }
 
 .theme-fg-color1,
 .cm-s-mozilla .cm-number,
 .variable-or-property .token-number,
 .variable-or-property[return] > .title > .name,
-.variable-or-property[scope] > .title > .name { /* green */
-  color: #5c9966;
+.variable-or-property[scope] > .title > .name {
+  color: var(--theme-highlight-green);
 }
 
 .CodeMirror-Tern-completion-number:before {
   background-color: #5c9966;
 }
 
 .theme-fg-color2,
 .cm-s-mozilla .cm-attribute,
 .cm-s-mozilla .cm-variable,
 .cm-s-mozilla .cm-def,
 .cm-s-mozilla .cm-property,
 .cm-s-mozilla .cm-qualifier,
-.variables-view-variable > .title > .name { /* blue */
-  color: #3689b2;
+.variables-view-variable > .title > .name {
+  color: var(--theme-highlight-blue);
 }
 
 .CodeMirror-Tern-completion-object:before {
   background-color: #3689b2;
 }
 
 .cm-s-mozilla .cm-unused-line {
   text-decoration: line-through;
@@ -109,71 +134,71 @@
 .cm-s-mozilla .cm-executed-line {
   background-color: #133c26;
 }
 
 .theme-fg-color3,
 .cm-s-mozilla .cm-builtin,
 .cm-s-mozilla .cm-tag,
 .cm-s-mozilla .cm-header,
-.variables-view-property > .title > .name { /* pink/lavender */
-  color: #a673bf;
+.cm-s-mozilla .cm-bracket,
+.variables-view-property > .title > .name {
+  color: var(--theme-highlight-pink);
 }
 
 .CodeMirror-Tern-completion-array:before {
-  background-color: #a673bf;
+  background-color: var(--theme-highlight-bluegrey);
 }
 
-.theme-fg-color4 { /* purple/violet */
-  color: #6270b2;
+.theme-fg-color4 {
+  color: var(--theme-highlight-purple);
 }
 
 .theme-fg-color5,
-.cm-s-mozilla .cm-bracket,
-.cm-s-mozilla .cm-keyword { /* Yellow */
-  color: #a18650;
+.cm-s-mozilla .cm-keyword {
+  color: var(--theme-highlight-lightorange);
 }
 
 .theme-fg-color6,
 .cm-s-mozilla .cm-string,
 .cm-s-mozilla .cm-string-2,
 .variable-or-property .token-string,
-.CodeMirror-Tern-farg { /* Orange */
-  color: #b26b47;
+.CodeMirror-Tern-farg {
+  color: var(--theme-highlight-orange);
 }
 
 .CodeMirror-Tern-completion-string:before,
 .CodeMirror-Tern-completion-fn:before {
   background-color: #b26b47;
 }
 
 .theme-fg-color7,
 .cm-s-mozilla .cm-atom,
 .cm-s-mozilla .cm-quote,
 .cm-s-mozilla .cm-error,
 .variable-or-property .token-boolean,
 .variable-or-property .token-domnode,
-.variable-or-property[exception] > .title > .name { /* Red */
-  color: #bf5656;
+.variable-or-property[exception] > .title > .name {
+  color: var(--theme-highlight-red);
 }
 
 .CodeMirror-Tern-completion-bool:before {
   background-color: #bf5656;
 }
 
 .variable-or-property .token-domnode {
   font-weight: bold;
 }
 
 .theme-toolbar,
 .devtools-toolbar,
 .devtools-sidebar-tabs > tabs,
 .CodeMirror-dialog { /* General toolbar styling */
-  color: #b6babf;
-  background-color: #343c45;
+  color: var(--theme-body-color-alt);
+  background-color: var(--theme-toolbar-background);
   border-color: hsla(210,8%,5%,.6);
 }
 
 .theme-fg-contrast { /* To be used for text on theme-bg-contrast */
   color: black;
 }
 
 .ruleview-colorswatch,
@@ -191,18 +216,18 @@
   font-size: inherit;
   background: transparent;
 }
 
 .CodeMirror pre,
 .cm-s-mozilla .cm-variable-2,
 .cm-s-mozilla .cm-variable-3,
 .cm-s-mozilla .cm-operator,
-.cm-s-mozilla .cm-special { /* theme-body color */
-  color: #a9bacb;
+.cm-s-mozilla .cm-special {
+  color: var(--theme-content-color1);
 }
 
 .cm-s-mozilla .CodeMirror-lines .CodeMirror-cursor {
   border-left: solid 1px #fff;
 }
 
 .cm-s-mozilla.CodeMirror-focused .CodeMirror-selected { /* selected text (focused) */
   background: rgb(185, 215, 253);
@@ -243,22 +268,22 @@ div.CodeMirror span.marked-text {
 }
 
 /* Highlight for evaluating current statement. */
 div.CodeMirror span.eval-text {
   background-color: #556;
 }
 
 .cm-s-mozilla .CodeMirror-linenumber { /* line number text */
-  color: #5f7387;
+  color: var(--theme-content-color3);
 }
 
 .cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */
-  border-right-color: #343c45;
-  background-color: #181d20;
+  border-right-color: var(--theme-toolbar-background);
+  background-color: var(--theme-sidebar-background);
 }
 
 .cm-s-markup-view pre {
   line-height: 1.4em;
   min-height: 1.4em;
 }
 
 /* Twisty and checkbox controls */
@@ -354,35 +379,35 @@ div.CodeMirror span.eval-text {
   border-bottom: 1px solid #434850;
 }
 
 .theme-tooltip-panel .devtools-tooltip-simple-text:last-child {
   border-bottom: 0;
 }
 
 .devtools-horizontal-splitter {
-  border-bottom: 1px solid black;
+  border-bottom: 1px solid var(--theme-splitter-color);
 }
 
 .devtools-side-splitter {
-  -moz-border-end: 1px solid black;
-  border-color: black; /* Needed for responsive container at low width. */
+  -moz-border-end: 1px solid var(--theme-splitter-color);
+  border-color: var(--theme-splitter-color); /* Needed for responsive container at low width. */
 }
 
 .devtools-textinput,
 .devtools-searchinput {
   background-color: rgba(24, 29, 32, 1);
   color: rgba(184, 200, 217, 1);
 }
 
 .CodeMirror-Tern-fname {
   color: #f7f7f7;
 }
 
 .CodeMirror-hints,
 .CodeMirror-Tern-tooltip {
   box-shadow: 0 0 4px rgba(255, 255, 255, .3);
   background-color: #0f171f;
-  color: #8fa1b2;
+  color: var(--theme-body-color);
 }
 
 
 %include toolbars.inc.css
--- a/browser/themes/shared/devtools/debugger.inc.css
+++ b/browser/themes/shared/devtools/debugger.inc.css
@@ -13,24 +13,19 @@
   -moz-border-end: 1px solid;
 }
 
 #sources-pane .devtools-toolbar {
   border: none; /* Remove the devtools-toolbar bottom border. */
   -moz-border-end: 1px solid;
 }
 
-.theme-dark #sources-pane > tabs,
-.theme-dark #sources-pane .devtools-toolbar {
-  -moz-border-end-color: black; /* Match the splitter color. */
-}
-
-.theme-light #sources-pane > tabs,
-.theme-light #sources-pane .devtools-toolbar {
-  -moz-border-end-color: #aaa; /* Match the splitter color. */
+#sources-pane > tabs,
+#sources-pane .devtools-toolbar {
+  -moz-border-end-color: var(--theme-splitter-color);
 }
 
 /* Sources and breakpoints list */
 
 .dbg-source-item {
   padding: 2px 0px;
 }
 
@@ -184,38 +179,26 @@
   float: left;
 }
 
 .dbg-classic-stackframe-details-url {
   max-width: 90%;
   text-align: end;
 }
 
-.theme-dark .dbg-classic-stackframe-details-url {
-  color: #a9bacb; /* Light content text */
-}
-
-.theme-light .dbg-classic-stackframe-details-url {
-  color: #667380; /* Dark grey content text */
+.dbg-classic-stackframe-details-url {
+  color: var(--theme-content-color1);
 }
 
-.theme-dark .dbg-classic-stackframe-details-sep {
-  color: #b6babf; /* Grey foreground text */
+.dbg-classic-stackframe-details-sep {
+  color: var(--theme-body-color-alt)
 }
 
-.theme-light .dbg-classic-stackframe-details-sep {
-  color: #585959; /* Grey foreground text */
-}
-
-.theme-dark .dbg-classic-stackframe-details-line {
-  color: #5e88b0; /* Highlight blue grey */
-}
-
-.theme-light .dbg-classic-stackframe-details-line {
-  color: #5f88b0; /* Highlight blue grey */
+.dbg-classic-stackframe-details-line {
+  color: var(--theme-highlight-bluegrey);
 }
 
 #callstack-list .selected label {
   /* Text inside a selected item should not be custom colored. */
   color: inherit !important;
 }
 
 /* Tracer */
@@ -247,91 +230,69 @@
 
 .trace-name {
   -moz-padding-start: 4px;
 }
 
 /* Tracer dark theme */
 
 .theme-dark .trace-item {
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-dark .trace-item.black-boxed {
   color: rgba(128,128,128,0.4);
 }
 
 .theme-dark .trace-item.selected-matching {
   background-color: rgba(29,79,115,.4); /* Select highlight blue at 40% alpha */
 }
 
 .theme-dark .selected > .trace-item {
   background-color: rgba(29,79,115,.6); /* Select highlight blue at 60% alpha */
 }
 
-.theme-dark .trace-call {
-  color: #46afe3; /* Highlight blue */
+.trace-call {
+  color: var(--theme-highlight-blue);
 }
 
-.theme-dark .trace-return,
-.theme-dark .trace-yield {
-  color: #70bf53; /* Highlight green */
+.trace-return,
+.trace-yield {
+  color: var(--theme-highlight-green);
 }
 
-.theme-dark .trace-throw {
-  color: #eb5368; /* Highlight red */
+.trace-throw {
+  color: var(--theme-highlight-red);
 }
 
-.theme-dark .trace-param {
-  color: #a9bacb; /* Content text light */
+.trace-param {
+  color: var(--theme-content-color1);
 }
 
 .theme-dark .trace-syntax {
-  color: #8fa1b2; /* Content text grey */
+  color: var(--theme-content-color2);
 }
 
 /* Tracer light theme */
-
 .theme-light .trace-item {
-  color: #292e33; /* Dark foreground text */
+  color: var(--theme-content-color1);
 }
 
 .theme-light .trace-item.black-boxed {
   color: rgba(128,128,128,0.4);
 }
 
 .theme-light .trace-item.selected-matching {
   background-color: rgba(76,158,217,.4); /* Select highlight blue at 40% alpha */
 }
 
 .theme-light .selected > .trace-item {
   background-color: rgba(76,158,217,.6); /* Select highlight blue at 60% alpha */
 }
 
-.theme-light .trace-call {
-  color: #0088cc; /* Highlight blue */
-}
-
-.theme-light .trace-return,
-.theme-light .trace-yield {
-  color: #2cbb0f; /* Highlight green */
-}
-
-.theme-light .trace-throw {
-  color: #ed2655; /* Highlight red */
-}
-
-.theme-light .trace-param {
-  color: #667380; /* Content text dark grey  */
-}
-
-.theme-light .trace-syntax {
-  color: #8fa1b2; /* Content text grey */
-}
-
 #tracer-traces .selected label {
   /* Text inside a selected item should not be custom colored. */
   color: inherit !important;
 }
 
 /* Watch expressions view */
 
 #expressions {
@@ -366,52 +327,36 @@
 .dbg-expression-button {
   -moz-appearance: none;
   border: none;
   background: none;
   text-decoration: underline;
   cursor: pointer;
 }
 
-.theme-dark .dbg-expression-button {
-  color: #46afe3; /* Blue highlight color */
-}
-
-.theme-light .dbg-expression-button {
-  color: #0088cc; /* Blue highlight color */
+.dbg-expression-button {
+  color: var(--theme-highlight-blue);
 }
 
 /* Event listeners view */
 
 .dbg-event-listener-type {
   font-weight: 600;
 }
 
-.theme-dark .dbg-event-listener-location {
-  color: #a9bacb; /* Light content text */
-}
-
-.theme-light .dbg-event-listener-location {
-  color: #667380; /* Dark grey content text */
+.dbg-event-listener-location {
+  color: var(--theme-content-color1);
 }
 
-.theme-dark .dbg-event-listener-separator {
-  color: #b6babf; /* Grey foreground text */
+.dbg-event-listener-separator {
+  color: var(--theme-body-color-alt);
 }
 
-.theme-light .dbg-event-listener-separator {
-  color: #585959; /* Grey foreground text */
-}
-
-.theme-dark .dbg-event-listener-targets {
-  color: #5e88b0; /* Highlight blue grey */
-}
-
-.theme-light .dbg-event-listener-targets {
-  color: #5f88b0; /* Highlight blue grey */
+.dbg-event-listener-targets {
+  color: var(--theme-highlight-bluegrey);
 }
 
 .theme-dark #event-listeners .selected {
   /* Selected items shouldn't be displayed differently. */
   background: none;
   color: #fff;
 }
 
@@ -470,37 +415,29 @@
   font-weight: 600;
 }
 
 .results-panel-item-label-before {
   -moz-padding-end: 6px;
 }
 
 .theme-dark .results-panel-item-label {
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-light .results-panel-item-label {
-  color: #18191a; /* Dark foreground text */
-}
-
-.theme-dark .results-panel-item-label-before {
-  color: #5e88b0; /* Highlight blue grey */
+  color: var(--theme-body-color);
 }
 
-.theme-light .results-panel-item-label-before {
-  color: #5f88b0; /* Highlight blue grey */
+.results-panel-item-label-before {
+  color: var(--theme-highlight-bluegrey);
 }
 
-.theme-dark .results-panel-item-label-below {
-  color: #5f7387; /* Dark grey content text */
-}
-
-.theme-light .results-panel-item-label-below {
-  color: #667380; /* Dark grey content text */
+.results-panel-item-label-below {
+  color: var(--theme-content-color3);
 }
 
 #results-panel .selected label {
   /* Text inside a selected item should not be custom colored. */
   color: inherit !important;
 }
 
 /* Sources search view */
@@ -546,74 +483,59 @@
   transition: transform 0.3s ease-in-out;
 }
 
 .dbg-results-line-contents-string[match=true][focused] {
   transition-duration: 0.1s;
   transform: scale(1.75, 1.75);
 }
 
-.theme-dark .dbg-source-results:not(.selected):hover {
-  background-color: #181d20; /* Sidebar background */
+.dbg-source-results:not(.selected):hover {
+  background-color: var(--theme-sidebar-background);
 }
 
-.theme-light .dbg-source-results:not(.selected):hover {
-  background-color: #f7f7f7; /* Sidebar background */
+.dbg-results-header {
+  background-color: var(--theme-tab-toolbar-background);
 }
 
 .theme-dark .dbg-results-header {
-  background-color: #252c33; /* Tab toolbar */
-  color: #a9bacb; /* Light content text */
+  color: var(--theme-content-color1);
 }
 
 .theme-light .dbg-results-header {
-  background-color: #ebeced; /* Tab toolbar */
-  color: #667380; /* Dark grey content text */
+  color: var(--theme-content-color3);
 }
 
 .theme-dark .dbg-search-result:hover {
   background-color: rgba(29,79,115,.2); /* Select highlight blue at 40% alpha */
 }
 
 .theme-light .dbg-search-result:hover {
   background-color: rgba(76,158,217,.2); /* Select highlight blue at 40% alpha */
 }
 
-.theme-dark .dbg-results-header-match-count {
-  color: #5f7387; /* Dark grey content text */
-}
-
-.theme-light .dbg-results-header-match-count {
-  color: #667380; /* Dark grey content text */
+.dbg-results-header-match-count {
+  color: var(--theme-content-color3);
 }
 
-.theme-dark .dbg-results-line-number {
-  background-color: #252c33; /* Tab toolbars */
-  color: #b6babf; /* Grey foreground text */
+.dbg-results-line-number {
+  background-color: var(--theme-tab-toolbar-background);
+  color: var(--theme-body-color-alt);
 }
 
-.theme-light .dbg-results-line-number {
-  background-color: #ebeced; /* Tab toolbars */
-  color: #585959; /* Grey foreground text */
-}
-
-.theme-dark .dbg-results-line-contents-string {
-  color: #b6babf; /* Grey foreground text */
-}
-
-.theme-light .dbg-results-line-contents-string {
-  color: #585959; /* Grey foreground text */
+.dbg-results-line-contents-string {
+  color: var(--theme-body-color-alt);
 }
 
 .theme-dark .dbg-results-line-contents-string[match=true] {
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-light .dbg-results-line-contents-string[match=true] {
-  color: #18191a; /* Dark foreground text */
+  color: var(--theme-body-color);
 }
 
 /* Toolbar controls */
 
 #debugger-toolbar .devtools-toolbarbutton:not([label]) > .toolbarbutton-icon,
 #sources-toolbar .devtools-toolbarbutton:not([label]) > .toolbarbutton-icon {
   width: 16px;
   height: 16px;
--- a/browser/themes/shared/devtools/inspector.css
+++ b/browser/themes/shared/devtools/inspector.css
@@ -100,39 +100,31 @@
   -moz-margin-start: 5px;
   -moz-margin-end: 0;
 }
 
 .event-tooltip-source {
   margin-bottom: 0;
 }
 
-.theme-dark .event-tooltip-attributes-box {
-  background-color: #B6BABF;
-  color: #343C45;
-}
-
 .event-tooltip-attributes-container {
   display: flex;
   flex-shrink: 0;
   flex-grow: 1;
   justify-content: flex-end;
 }
 
 .event-tooltip-attributes-box {
   display: flex;
   flex-shrink: 0;
   align-items: center;
   border-radius: 3px;
   padding: 2px;
   -moz-margin-start: 5px;
+  background-color: var(--theme-body-color-alt);
+  color: var(--theme-toolbar-background);
 }
 
 .event-tooltip-attributes {
   margin: 0;
   font-size: 9px;
   padding-top: 2px;
 }
-
-.theme-light .event-tooltip-attributes-box {
-  background-color: #585959;
-  color: #F0F1F2;
-}
--- a/browser/themes/shared/devtools/light-theme.css
+++ b/browser/themes/shared/devtools/light-theme.css
@@ -1,162 +1,187 @@
 /* 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/. */
 
 /* According to:
  * https://bugzilla.mozilla.org/show_bug.cgi?id=715472#c17
  */
+:root {
+  --theme-body-background: #fcfcfc;
+  --theme-sidebar-background: #f7f7f7;
+  --theme-contrast-background: #e6b064;
+
+  --theme-tab-toolbar-background: #ebeced;
+  --theme-toolbar-background: #f0f1f2;
+  --theme-selection-background: #4c9ed9;
+  --theme-selection-color: #f5f7fa;
+  --theme-splitter-color: #aaaaaa;
+  --theme-comment: hsl(90,2%,46%);
+
+  --theme-body-color: #18191a;
+  --theme-body-color-alt: #585959;
+  --theme-content-color1: #292e33;
+  --theme-content-color2: #8fa1b2;
+  --theme-content-color3: #667380;
+
+  --theme-highlight-green: hsl(72,100%,27%);
+  --theme-highlight-blue: hsl(208,56%,40%);
+  --theme-highlight-bluegrey: hsl(208,81%,21%);
+  --theme-highlight-purple: #5b5fff;
+  --theme-highlight-lightorange: #a18650;
+  --theme-highlight-orange: hsl(24,85%,39%);
+  --theme-highlight-red: #bf5656;
+  --theme-highlight-pink: #b82ee5;
+}
+
 .theme-body {
-  background: #fcfcfc; /* Background - Editor */
-  color: #18191a;
+  background: var(--theme-body-background);
+  color: var(--theme-body-color);
 }
 
 .theme-sidebar {
-  background: #f7f7f7; /* Background - Sidebars */
-  color: #18191a;
+  background: var(--theme-sidebar-background);
+  color: var(--theme-body-color);
 }
 
 ::-moz-selection {
-  background-color: #4c9ed9;
-  color: #f5f7fa;
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 .theme-bg-darker {
   background: #EFEFEF;
 }
 
 .theme-selected,
 .CodeMirror-hint-active {
-  background-color: #4c9ed9;
-  color: #f5f7fa; /* Light foreground text */
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 .theme-bg-contrast,
-.variable-or-property:not([overridden])[changed] { /* contrast bg color to attract attention on a container */
-  background: #E8B671; /* Background - Attention */
+.variable-or-property:not([overridden])[changed] {
+  background: var(--theme-contrast-background);
 }
 
 .theme-link,
 .cm-s-mozilla .cm-link,
-.CodeMirror-Tern-type { /* blue */
-  color: hsl(208,56%,40%);
+.CodeMirror-Tern-type {
+  color: var(--theme-highlight-blue);
 }
 
 /*
  * FIXME: http://bugzil.la/575675 CSS links without :visited set cause assertion
  * failures in debug builds.
  */
 .theme-link:visited,
-.cm-s-mozilla .cm-link:visited { /* blue */
-  color: hsl(208,56%,40%);
+.cm-s-mozilla .cm-link:visited {
+  color: var(--theme-highlight-blue);
 }
 
 .theme-comment,
 .cm-s-mozilla .cm-meta,
 .cm-s-mozilla .cm-hr,
 .cm-s-mozilla .cm-comment,
 .variable-or-property .token-undefined,
-.variable-or-property .token-null { /* grey */
-  color: hsl(90,2%,46%);
-}
-
+.variable-or-property .token-null,
 .CodeMirror-Tern-completion-unknown:before {
-  background-color: hsl(90,2%,46%);
+  color: var(--theme-comment);
 }
 
 .theme-gutter {
   background-color: hsl(0,0%,90%);
-  color: #667380;
+  color: var(--theme-content-color3);
   border-color: hsl(0,0%,65%);
 }
 
 .theme-separator { /* grey */
   border-color: #cddae5;
 }
 
 .cm-s-mozilla .cm-unused-line {
   text-decoration: line-through;
-  text-decoration-color: #5f88b0;
+  text-decoration-color: var(--theme-highlight-bluegrey);
 }
 
 .cm-s-mozilla .cm-executed-line {
   background-color: #fcfffc;
 }
 
 .theme-fg-color1,
 .cm-s-mozilla .cm-number,
 .variable-or-property .token-number,
 .variable-or-property[return] > .title > .name,
-.variable-or-property[scope] > .title > .name { /* green */
-  color: hsl(72,100%,27%);
+.variable-or-property[scope] > .title > .name {
+  color: var(--theme-highlight-green);
 }
 
 .CodeMirror-Tern-completion-number:before {
   background-color: hsl(72,100%,27%);
 }
 
 .theme-fg-color2,
 .cm-s-mozilla .cm-attribute,
 .cm-s-mozilla .cm-builtin,
 .cm-s-mozilla .cm-def,
 .cm-s-mozilla .cm-property,
 .cm-s-mozilla .cm-qualifier,
-.variables-view-variable > .title > .name { /* blue */
-  color: hsl(208,56%,40%);
+.variables-view-variable > .title > .name {
+  color: var(--theme-highlight-blue);
 }
 
 .CodeMirror-Tern-completion-object:before {
   background-color: hsl(208,56%,40%);
 }
 
 .theme-fg-color3,
 .cm-s-mozilla .cm-variable,
 .cm-s-mozilla .cm-tag,
 .cm-s-mozilla .cm-header,
-.variables-view-property > .title > .name { /* dark blue */
-  color: hsl(208,81%,21%);
+.cm-s-mozilla .cm-bracket,
+.variables-view-property > .title > .name {
+  color: var(--theme-highlight-bluegrey);
 }
 
-.CodeMirror-Tern-completion-array:before { /* dark blue */
-  background-color: hsl(208,81%,21%);
+.CodeMirror-Tern-completion-array:before {
+  background-color: var(--theme-highlight-bluegrey);
 }
 
-.theme-fg-color4 { /* Orange */
-  color: hsl(24,85%,39%);
+.theme-fg-color4 {
+  color: var(--theme-highlight-orange);
 }
 
 .theme-fg-color5,
-.cm-s-mozilla .cm-bracket,
-.cm-s-mozilla .cm-keyword { /* Yellow */
-  color: #a18650;
+.cm-s-mozilla .cm-keyword {
+  color: var(--theme-highlight-lightorange);
 }
 
 .theme-fg-color6,
 .cm-s-mozilla .cm-string,
 .cm-s-mozilla .cm-string-2,
 .variable-or-property .token-string,
-.CodeMirror-Tern-farg { /* Orange */
-  color: hsl(24,85%,39%);
+.CodeMirror-Tern-farg {
+  color: var(--theme-highlight-orange);
 }
 
 .CodeMirror-Tern-completion-string:before,
 .CodeMirror-Tern-completion-fn:before {
   background-color: hsl(24,85%,39%);
 }
 
 .theme-fg-color7,
 .cm-s-mozilla .cm-atom,
 .cm-s-mozilla .cm-quote,
 .cm-s-mozilla .cm-error,
 .variable-or-property .token-boolean,
 .variable-or-property .token-domnode,
-.variable-or-property[exception] > .title > .name { /* Red */
-  color: #bf5656;
+.variable-or-property[exception] > .title > .name {
+  color: var(--theme-highlight-red);
 }
 
 .CodeMirror-Tern-completion-bool:before {
   background-color: #bf5656;
 }
 
 .variable-or-property .token-domnode {
   font-weight: bold;
@@ -165,19 +190,19 @@
 .theme-fg-contrast { /* To be used for text on theme-bg-contrast */
   color: black;
 }
 
 .theme-toolbar,
 .devtools-toolbar,
 .devtools-sidebar-tabs > tabs,
 .CodeMirror-dialog { /* General toolbar styling */
-  color: #585959;
-  background-color: #f0f1f2;
-  border-color: #aaa;
+  color: var(--theme-body-color-alt);
+  background-color: var(--theme-toolbar-background);
+  border-color: var(--theme-splitter-color);
 }
 
 .ruleview-colorswatch,
 .computedview-colorswatch,
 .ruleview-bezierswatch {
   box-shadow: 0 0 0 1px #c4c4c4;
 }
 
@@ -190,18 +215,18 @@
   font-size: inherit;
   background: transparent;
 }
 
 .CodeMirror pre,
 .cm-s-mozilla .cm-variable-2,
 .cm-s-mozilla .cm-variable-3,
 .cm-s-mozilla .cm-operator,
-.cm-s-mozilla .cm-special { /* theme-body color */
-  color: black;
+.cm-s-mozilla .cm-special {
+  color: var(--theme-body-color);
 }
 
 .cm-s-mozilla .CodeMirror-lines .CodeMirror-cursor {
   border-left: solid 1px black;
 }
 
 .cm-s-mozilla.CodeMirror-focused .CodeMirror-selected { /* selected text (focused) */
   background: rgb(185, 215, 253);
@@ -242,22 +267,22 @@ div.CodeMirror span.marked-text {
 }
 
 /* Highlight for evaluating current statement. */
 div.CodeMirror span.eval-text {
   background-color: #ccd;
 }
 
 .cm-s-mozilla .CodeMirror-linenumber { /* line number text */
-  color: #667380;
+  color: var(--theme-content-color3);
 }
 
 .cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */
-  border-right-color: #a6a6a6;
-  background-color: #f7f7f7;
+  border-right-color: var(--theme-splitter-color);
+  background-color: var(--theme-sidebar-background);
 }
 
 .cm-s-markup-view pre {
   line-height: 1.4em;
   min-height: 1.4em;
 }
 
 /* Twisty and checkbox controls */
@@ -363,24 +388,24 @@ div.CodeMirror span.eval-text {
   border-bottom: 1px solid #d9e1e8;
 }
 
 .theme-tooltip-panel .devtools-tooltip-simple-text:last-child {
   border-bottom: 0;
 }
 
 .devtools-horizontal-splitter {
-  border-bottom: 1px solid #aaa;
+  border-bottom: 1px solid var(--theme-splitter-color);
 }
 
 .devtools-side-splitter {
-  -moz-border-end: 1px solid #aaa;
-  border-color: #aaa; /* Needed for responsive container at low width. */
+  -moz-border-end: 1px solid var(--theme-splitter-color);
+  border-color: var(--theme-splitter-color); /* Needed for responsive container at low width. */
 }
 
 .CodeMirror-hints,
 .CodeMirror-Tern-tooltip {
   box-shadow: 0 0 4px rgba(128, 128, 128, .5);
-  background-color: #f7f7f7;
+  background-color: var(--theme-sidebar-background);
 }
 
 
 %include toolbars.inc.css
--- a/browser/themes/shared/devtools/markup-view.css
+++ b/browser/themes/shared/devtools/markup-view.css
@@ -22,17 +22,17 @@
 .theme-selected ~ .editor,
 .theme-selected ~ .editor .theme-fg-color1,
 .theme-selected ~ .editor .theme-fg-color2,
 .theme-selected ~ .editor .theme-fg-color3,
 .theme-selected ~ .editor .theme-fg-color4,
 .theme-selected ~ .editor .theme-fg-color5,
 .theme-selected ~ .editor .theme-fg-color6,
 .theme-selected ~ .editor .theme-fg-color7 {
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 /* In case a node isn't displayed in the page, we fade the syntax highlighting */
 .not-displayed .open,
 .not-displayed .close {
   opacity: .7;
 }
 
@@ -48,24 +48,19 @@
   right: 0;
   width: 90px;
   background: black;
   border-left: 1px solid;
   border-bottom: 1px solid;
   overflow: hidden;
 }
 
-.theme-dark #previewbar {
-  background: #252c33; /* Tab Toolbar */
-  border-color: #000; /* Splitters */
-}
-
-.theme-light #previewbar {
-  background: #ebeced; /* Tab Toolbar */
-  border-color: #aaa; /* Splitters */
+#previewbar {
+  background: var(--theme-tab-toolbar-background);
+  border-color: var(--theme-splitter-color);
 }
 
 #preview {
   position: absolute;
   top: 0;
   right: 5px;
   width: 80px;
   height: 100%;
@@ -94,17 +89,12 @@
   font-weight: bold;
   line-height: 10px;
   border-radius: 3px;
   padding: 0px 2px;
   -moz-margin-start: 5px;
   -moz-user-select: none;
 }
 
-.theme-dark .markupview-events {
-  background-color: #b6babf;
-  color: #14171a;
+.markupview-events {
+  background-color: var(--theme-body-color-alt);
+  color: var(--theme-body-background);
 }
-
-.theme-light .markupview-events {
-  background-color: #585959;
-  color: #fcfcfc;
-}
--- a/browser/themes/shared/devtools/netmonitor.inc.css
+++ b/browser/themes/shared/devtools/netmonitor.inc.css
@@ -4,24 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #requests-menu-empty-notice {
   margin: 0;
   padding: 12px;
   font-size: 120%;
 }
 
-.theme-dark #requests-menu-empty-notice {
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light #requests-menu-empty-notice {
-  color: #585959; /* Grey foreground text */
-}
-
 #notice-perf-message {
   margin-top: 2px;
 }
 
 #requests-menu-perf-notice-button {
   min-width: 30px;
   min-height: 26px;
   margin: 0;
@@ -283,40 +275,40 @@ label.requests-menu-status-code {
   transform-origin: left center;
 }
 
 .requests-menu-timings-division:-moz-locale-dir(rtl) {
   transform-origin: right center;
 }
 
 .theme-dark .requests-menu-timings-division[division-scale=millisecond] {
-  -moz-border-start-color: #f5f7fa !important; /* Light foreground text */
+  -moz-border-start-color: var(--theme-selection-color) !important;
 }
 
 .theme-light .requests-menu-timings-division[division-scale=millisecond] {
-  -moz-border-start-color: #585959 !important; /* Grey foreground text */
+  -moz-border-start-color: var(--theme-body-color-alt) !important;
 }
 
 .theme-dark .requests-menu-timings-division[division-scale=second] {
-  -moz-border-start-color: #f5f7fa !important; /* Light foreground text */
+  -moz-border-start-color: var(--theme-selection-color) !important;
   font-weight: 600;
 }
 
 .theme-light .requests-menu-timings-division[division-scale=second] {
-  -moz-border-start-color: #585959 !important; /* Grey foreground text */
+  -moz-border-start-color: var(--theme-body-color-alt) !important;
   font-weight: 600;
 }
 
 .theme-dark .requests-menu-timings-division[division-scale=minute] {
-  -moz-border-start-color: #f5f7fa !important; /* Light foreground text */
+  -moz-border-start-color: var(--theme-selection-color) !important;
   font-weight: 600;
 }
 
 .theme-light .requests-menu-timings-division[division-scale=minute] {
-  -moz-border-start-color: #585959 !important; /* Grey foreground text */
+  -moz-border-start-color: var(--theme-body-color-alt) !important;
   font-weight: 600;
 }
 
 /* Network requests table: waterfall items */
 
 .requests-menu-subitem.requests-menu-waterfall {
   -moz-padding-start: 0px;
   -moz-padding-end: 4px;
@@ -444,18 +436,18 @@ label.requests-menu-status-code {
   #details-pane-toggle:active {
     -moz-image-region: rect(0px,64px,32px,32px);
   }
 }
 
 /* Network request details tabpanels */
 
 .theme-dark .tabpanel-content {
-  background-color: #343c45; /* Toolbars */
-  color: #f5f7fa; /* Light foreground text */
+  background-color: var(--theme-toolbar-background);
+  color: var(--theme-selection-color);
 }
 
 /* Summary tabpanel */
 
 .tabpanel-summary-container {
   padding: 1px;
 }
 
@@ -494,26 +486,18 @@ label.requests-menu-status-code {
   height: 50vh;
 }
 
 /* Response tabpanel */
 
 #response-content-info-header {
   margin: 0;
   padding: 3px 8px;
-}
-
-.theme-dark  #response-content-info-header {
-  background-color: #eb5368; /* Red highlight */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light  #response-content-info-header {
-  background-color: #ed2655; /* Red highlight */
-  color: #f5f7fa; /* Light foreground text */
+  background-color: var(--theme-highlight-red);
+  color: var(--theme-selection-color);
 }
 
 #response-content-image-box {
   padding-top: 10px;
   padding-bottom: 10px;
 }
 
 #response-content-image {
@@ -567,41 +551,41 @@ label.requests-menu-status-code {
   width: 4.5em;
 }
 
 /* Footer */
 
 .theme-dark #requests-menu-footer {
   border-top: 1px solid @table_itemDarkStartBorder@;
   box-shadow: 0 1px 0 @table_itemDarkEndBorder@ inset;
-  background-color: #343c45; /* Toolbars */
+  background-color: var(--theme-toolbar-background);
 }
 
 .theme-light #requests-menu-footer {
   border-top: 1px solid @table_itemLightStartBorder@;
   box-shadow: 0 1px 0 @table_itemLightEndBorder@ inset;
-  background-color: #f0f1f2; /* Toolbars */
+  background-color: var(--theme-toolbar-background);
 }
 
 .requests-menu-footer-button,
 .requests-menu-footer-label {
   min-width: 1em;
   margin: 0;
   border: none;
   padding: 2px 1vw;
 }
 
 .theme-dark .requests-menu-footer-button,
 .theme-dark .requests-menu-footer-label {
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-light .requests-menu-footer-button,
 .theme-light .requests-menu-footer-label {
-  color: #18191a; /* Dark foreground text */
+  color: var(--theme-body-color);
 }
 
 .requests-menu-footer-spacer {
   min-width: 2px;
 }
 
 .theme-dark .requests-menu-footer-spacer:not(:first-child),
 .theme-dark .requests-menu-footer-button:not(:first-child) {
@@ -691,112 +675,68 @@ label.requests-menu-status-code {
   cursor: default;
   pointer-events: none;
 }
 
 #network-statistics-charts {
   min-height: 1px;
 }
 
-.theme-dark #network-statistics-charts {
-  background-color: #343c45; /* Toolbars */
-}
-
-.theme-light #network-statistics-charts {
-  background-color: #f0f1f2; /* Toolbars */
+#network-statistics-charts {
+  background-color: var(--theme-toolbar-background);
 }
 
 #network-statistics-charts .pie-chart-container {
   -moz-margin-start: 3vw;
   -moz-margin-end: 1vw;
 }
 
 #network-statistics-charts .table-chart-container {
   -moz-margin-start: 1vw;
   -moz-margin-end: 3vw;
 }
 
-.theme-dark .chart-colored-blob[name=html] {
-  fill: #5e88b0; /* Blue-Grey highlight */
-  background: #5e88b0;
-}
-
-.theme-light .chart-colored-blob[name=html] {
-  fill: #5f88b0; /* Blue-Grey highlight */
-  background: #5f88b0;
-}
-
-.theme-dark .chart-colored-blob[name=css] {
-  fill: #46afe3; /* Blue highlight */
-  background: #46afe3;
+.chart-colored-blob[name=html] {
+  fill: var(--theme-highlight-bluegrey);
+  background: var(--theme-highlight-bluegrey);
 }
 
-.theme-light .chart-colored-blob[name=css] {
-  fill: #0088cc; /* Blue highlight */
-  background: #0088cc;
+.chart-colored-blob[name=css] {
+  fill: var(--theme-highlight-blue);
+  background: var(--theme-highlight-blue);
 }
 
-.theme-dark .chart-colored-blob[name=js] {
-  fill: #d99b28; /* Light Orange highlight */
-  background: #d99b28;
-}
-
-.theme-light .chart-colored-blob[name=js] {
-  fill: #d97e00; /* Light Orange highlight */
-  background: #d97e00;
-}
-
-.theme-dark .chart-colored-blob[name=xhr] {
-  fill: #d96629; /* Orange highlight */
-  background: #d96629;
+.chart-colored-blob[name=js] {
+  fill: var(--theme-highlight-lightorange);
+  background: var(--theme-highlight-lightorange);
 }
 
-.theme-light .chart-colored-blob[name=xhr] {
-  fill: #f13c00; /* Orange highlight */
-  background: #f13c00;
+.chart-colored-blob[name=xhr] {
+  fill: var(--theme-highlight-orange);
+  background: var(--theme-highlight-orange);
 }
 
-.theme-dark .chart-colored-blob[name=fonts] {
-  fill: #6b7abb; /* Purple highlight */
-  background: #6b7abb;
-}
-
-.theme-light .chart-colored-blob[name=fonts] {
-  fill: #5b5fff; /* Purple highlight */
-  background: #5b5fff;
-}
-
-.theme-dark .chart-colored-blob[name=images] {
-  fill: #df80ff; /* Pink highlight */
-  background: #df80ff;
+.chart-colored-blob[name=fonts] {
+  fill: var(--theme-highlight-purple);
+  background: var(--theme-highlight-purple);
 }
 
-.theme-light .chart-colored-blob[name=images] {
-  fill: #b82ee5; /* Pink highlight */
-  background: #b82ee5;
-}
-
-.theme-dark .chart-colored-blob[name=media] {
-  fill: #70bf53; /* Green highlight */
-  background: #70bf53;
+.chart-colored-blob[name=images] {
+  fill: var(--theme-highlight-pink);
+  background: var(--theme-highlight-pink);
 }
 
-.theme-light .chart-colored-blob[name=media] {
-  fill: #2cbb0f; /* Green highlight */
-  background: #2cbb0f;
+.chart-colored-blob[name=media] {
+  fill: var(--theme-highlight-green);
+  background: var(--theme-highlight-green);
 }
 
-.theme-dark .chart-colored-blob[name=flash] {
-  fill: #eb5368; /* Red highlight */
-  background: #eb5368;
-}
-
-.theme-light .chart-colored-blob[name=flash] {
-  fill: #ed2655; /* Red highlight */
-  background: #ed2655;
+.chart-colored-blob[name=flash] {
+  fill: var(--theme-highlight-red);
+  background: var(--theme-highlight-red);
 }
 
 .table-chart-row-label[name=cached] {
   display: none;
 }
 
 .table-chart-row-label[name=count] {
   width: 3em;
--- a/browser/themes/shared/devtools/profiler.inc.css
+++ b/browser/themes/shared/devtools/profiler.inc.css
@@ -3,26 +3,18 @@
  * 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/. */
 
 /* Reload and waiting notices */
 
 .notice-container {
   margin-top: -50vh;
   font-size: 120%;
-}
-
-.theme-dark .notice-container {
-  background: #343c45; /* Toolbars */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .notice-container {
-  background: #f0f1f2; /* Toolbars */
-  color: #585959; /* Grey foreground text */
+  background-color: var(--theme-toolbar-background);
+  color: var(--theme-body-color-alt);
 }
 
 #empty-notice button,
 #recording-notice button {
   min-width: 30px;
   min-height: 28px;
   margin: 0;
   list-style-image: url(profiler-stopwatch.svg);
@@ -50,24 +42,19 @@
 
 /* Recordings pane */
 
 #recordings-pane > tabs,
 #recordings-pane .devtools-toolbar {
   -moz-border-end-width: 1px;
 }
 
-.theme-dark #recordings-pane > tabs,
-.theme-dark #recordings-pane .devtools-toolbar {
-  -moz-border-end-color: #000; /* Splitters */
-}
-
-.theme-light #recordings-pane > tabs,
-.theme-light #recordings-pane .devtools-toolbar {
-  -moz-border-end-color: #aaa; /* Splitters */
+#recordings-pane > tabs,
+#recordings-pane .devtools-toolbar {
+  -moz-border-end-color: var(--theme-splitter-color);
 }
 
 #record-button {
   list-style-image: url(profiler-stopwatch.svg);
 }
 
 #record-button[checked] {
   list-style-image: url(profiler-stopwatch-checked.svg);
@@ -92,24 +79,19 @@
   font-size: 90%;
 }
 
 .recording-item-save {
   text-decoration: underline;
   cursor: pointer;
 }
 
-.theme-dark .recording-item-duration,
-.theme-dark .recording-item-save {
-  color: #b6babf; /* Foreground (Text) - Grey */
-}
-
-.theme-light .recording-item-duration,
-.theme-light .recording-item-save {
-  color: #585959; /* Foreground (Text) - Grey */
+.recording-item-duration,
+.recording-item-save {
+  color: var(--theme-body-color-alt);
 }
 
 #recordings-list .selected label {
   /* Text inside a selected item should not be custom colored. */
   color: inherit !important;
 }
 
 /* Profile pane */
@@ -127,59 +109,45 @@
   border-radius: 0;
   padding: 0;
   text-shadow: none;
   transition-duration: 0.25s;
   transition-timing-function: ease-in-out;
   transition-property: opacity, transform;
 }
 
-.theme-dark #profile-content tab {
-  color: #8fa1b2; /* Body Text */
-}
-
-.theme-light #profile-content tab {
-  color: #18191a; /* Body Text */
+#profile-content tab {
+  color: var(--theme-body-color);
 }
 
 #profile-content tab:not([selected]) {
   cursor: pointer;
 }
 
 #profile-content tab[covered] {
   opacity: 0;
   transform: translateY(100%);
 }
 
-.theme-dark #profile-content tab {
+#profile-content tab {
   -moz-appearance: none;
-  -moz-border-end: 1px solid #000; /* Splitters */
-}
-
-.theme-light #profile-content tab {
-  -moz-appearance: none;
-  -moz-border-end: 1px solid #aaa; /* Splitters */
+  -moz-border-end: 1px solid var(--theme-splitter-color);
 }
 
 .theme-dark #profile-content tab:hover {
   background-color: rgba(0,0,0,0.3);
 }
 
 .theme-light #profile-content tab:hover {
   background-color: rgba(255,255,255,0.8);
 }
 
-.theme-dark #profile-content tab[selected] {
-  background-color: #1d4f73; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light #profile-content tab[selected] {
-  background-color: #4c9ed9; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
+#profile-content tab[selected] {
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 #profile-content tabpanel {
   -moz-box-orient: vertical;
   transform: translateZ(1px); /* Make sure the tabpanel appears above the tab */
 }
 
 #profile-newtab-button {
@@ -224,22 +192,18 @@
 }
 
 #profile-newtab-button:hover:active {
   background-position: 22px 2px;
 }
 
 /* Profile call tree */
 
-.theme-dark .call-tree-headers-container {
-  border-top: 1px solid #000;
-}
-
-.theme-light .call-tree-headers-container {
-  border-top: 1px solid #aaa;
+.call-tree-headers-container {
+  border-top: 1px solid var(--theme-splitter-color);
 }
 
 .call-tree-cells-container {
   /* Hack: force hardware acceleration */
   transform: translateZ(1px);
   overflow: auto;
 }
 
@@ -271,49 +235,44 @@
   -moz-box-flex: 1;
 }
 
 .call-tree-header,
 .call-tree-cell {
   -moz-box-align: center;
   overflow: hidden;
   padding: 1px 4px;
+  color: var(--theme-body-color);
 }
 
 .call-tree-header:not(:last-child),
 .call-tree-cell:not(:last-child) {
   -moz-border-end: 1px solid;
 }
 
 .theme-dark .call-tree-header,
 .theme-dark .call-tree-cell {
   -moz-border-end-color: rgba(255,255,255,0.15);
-  color: #8fa1b2; /* Body Text */
 }
 
 .theme-light .call-tree-header,
 .theme-light .call-tree-cell {
   -moz-border-end-color: rgba(0,0,0,0.15);
-  color: #18191a; /* Body Text */
 }
 
 .call-tree-header:not(:last-child) {
   text-align: center;
 }
 
 .call-tree-cell:not(:last-child) {
   text-align: end;
 }
 
-.theme-dark .call-tree-header {
-  background-color: #252c33; /* Tab Toolbar */
-}
-
-.theme-light .call-tree-header {
-  background-color: #ebeced; /* Tab Toolbar */
+.call-tree-header {
+  background-color: var(--theme-tab-toolbar-background);
 }
 
 .theme-dark .call-tree-item:last-child:not(:focus) {
   border-bottom: 1px solid rgba(255,255,255,0.15);
 }
 
 .theme-light .call-tree-item:last-child:not(:focus) {
   border-bottom: 1px solid rgba(0,0,0,0.15);
@@ -330,26 +289,22 @@
 .theme-dark .call-tree-item:hover {
   background-color: rgba(29,79,115,0.25);
 }
 
 .theme-light .call-tree-item:hover {
   background-color: rgba(76,158,217,0.2);
 }
 
-.theme-dark .call-tree-item:focus {
-  background-color: #1d4f73; /* Select Highlight Blue */
-}
-
-.theme-light .call-tree-item:focus {
-  background-color: #4c9ed9; /* Select Highlight Blue */
+.call-tree-item:focus {
+  background-color: var(--theme-selection-background);
 }
 
 .call-tree-item:focus label {
-  color: #f5f7fa !important; /* Light foreground text */
+  color: var(--theme-selection-color) !important;
 }
 
 .theme-dark .call-tree-item:focus .call-tree-cell {
   -moz-border-end-color: rgba(0,0,0,0.3);
 }
 
 .theme-light .call-tree-item:focus .call-tree-cell {
   -moz-border-end-color: rgba(255,255,255,0.5);
@@ -366,43 +321,29 @@
   -moz-margin-start: 4px !important;
   cursor: pointer;
 }
 
 .call-tree-url:hover {
   text-decoration: underline;
 }
 
-.theme-dark .call-tree-url {
-  color: #46afe3;
+.call-tree-url {
+  color: var(--theme-highlight-blue);
 }
 
-.theme-light .call-tree-url {
-  color: #0088cc;
-}
 
-.theme-dark .call-tree-line {
-  color: #d96629;
-}
-
-.theme-light .call-tree-line {
-  color: #f13c00;
+.call-tree-line {
+  color: var(--theme-highlight-orange);
 }
 
 .call-tree-host {
   -moz-margin-start: 8px !important;
   font-size: 90%;
-}
-
-.theme-dark .call-tree-host {
-  color: #8fa1b2;
-}
-
-.theme-light .call-tree-host {
-  color: #8fa1b2;
+  color: var(--theme-content-color2);
 }
 
 .call-tree-url[value=""],
 .call-tree-line[value=""],
 .call-tree-host[value=""] {
   display: none;
 }
 
--- a/browser/themes/shared/devtools/ruleview.css
+++ b/browser/themes/shared/devtools/ruleview.css
@@ -46,30 +46,26 @@
 }
 
 .ruleview-rule,
 #noResults {
   padding: 2px 4px;
 }
 
 /* User agent styles are not editable, display them differently */
-.theme-light .ruleview-rule[uneditable=true] {
-  background: #ebeced; /* Tab Toolbar */
-}
-
-.theme-dark .ruleview-rule[uneditable=true] {
-  background: #252c33; /* Tab Toolbar */
+.ruleview-rule[uneditable=true] {
+  background: var(--theme-tab-toolbar-background);
 }
 
 .ruleview-rule[uneditable=true] :focus {
   outline: none;
 }
 
 .ruleview-rule[uneditable=true] .theme-link {
-  color: #5f88b0; /* Blue - Grey */
+  color: var(--theme-highlight-bluegrey);
 }
 
 .ruleview-rule[uneditable=true] .ruleview-enableproperty {
   visibility: hidden;
 }
 
 .ruleview-rule[uneditable=true] .ruleview-colorswatch,
 .ruleview-rule[uneditable=true] .ruleview-bezierswatch {
@@ -193,39 +189,35 @@
   }
 }
 
 .ruleview-overridden {
   text-decoration: line-through;
 }
 
 .theme-light .ruleview-overridden {
-  text-decoration-color: #667380; /*  Content (Text) - Dark Grey */
+  text-decoration-color: var(--theme-content-color3);
 }
 
 .styleinspector-propertyeditor {
   border: 1px solid #CCC;
   padding: 0;
 }
 
 .ruleview-property {
   border-left: 3px solid transparent;
   clear: right;
 }
 
 .ruleview-property  > * {
   vertical-align: middle;
 }
 
-.theme-dark .ruleview-property[dirty] {
-  border-left-color: #70bf53; /* Green */
-}
-
-.theme-light .ruleview-property[dirty] {
-  border-left-color: #2cbb0f; /* Green */
+.ruleview-property[dirty] {
+  border-left-color: var(--theme-highlight-green);
 }
 
 .ruleview-namecontainer > .ruleview-propertyname,
 .ruleview-propertycontainer > .ruleview-propertyvalue {
   border-bottom: 1px dashed transparent;
 }
 
 .ruleview-namecontainer:hover > .ruleview-propertyname,
--- a/browser/themes/shared/devtools/shadereditor.inc.css
+++ b/browser/themes/shared/devtools/shadereditor.inc.css
@@ -1,26 +1,18 @@
 /* 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/. */
 
 /* Reload and waiting notices */
 
 .notice-container {
   margin-top: -50vh;
-}
-
-.theme-dark .notice-container {
-  background-color: #343c45; /* Toolbars */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .notice-container {
-  background-color: #f0f1f2; /* Toolbars */
-  color: #585959; /* Grey foreground text */
+  background-color: var(--theme-toolbar-background);
+  color: var(--theme-body-color-alt);
 }
 
 #reload-notice {
   font-size: 120%;
 }
 
 #waiting-notice {
   font-size: 110%;
@@ -94,36 +86,25 @@
 
 /* Shader source editors */
 
 .editor-label {
   padding: 1px 12px;
   border-top: 1px solid;
 }
 
-.theme-dark .editor-label {
-  background: #343c45; /* Dark toolbars */
-  border-color: #000; /* Match the splitter color. */
-  color: #f5f7fa; /* Light foreground text */
+.editor-label {
+  background: var(--theme-toolbar-background);
+  border-color: var(--theme-splitter-color);
+  color: var(--theme-body-color-alt);
 }
 
-.theme-light .editor-label {
-  background: #f0f1f2; /* Light toolbars */
-  border-color: #aaa; /* Match the splitter color. */
-  color: #585959; /* Grey foreground text */
-}
-
-.theme-dark .editor-label[selected] {
-  background-color: #1d4f73; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .editor-label[selected] {
-  background-color: #4c9ed9; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
+.editor-label[selected] {
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 /* Responsive sidebar */
 
 @media (max-width: 700px) {
   #shaders-pane {
     max-height: 60vh;
   }
--- a/browser/themes/shared/devtools/splitview.css
+++ b/browser/themes/shared/devtools/splitview.css
@@ -13,17 +13,17 @@
 
 .loading .splitview-nav-container {
   background-image: url(chrome://global/skin/icons/loading_16.png);
   background-repeat: no-repeat;
   background-position: center center;
 }
 
 .theme-dark .splitview-nav-container {
-  background-color: #343c45; /* Toolbars */
+  background-color: var(--theme-toolbar-background);
 }
 
 .splitview-nav {
   -moz-appearance: none;
   list-style-image: none;
   list-style: none;
   padding: 0;
   margin: 0;
--- a/browser/themes/shared/devtools/styleeditor.css
+++ b/browser/themes/shared/devtools/styleeditor.css
@@ -9,47 +9,47 @@
 }
 
 .stylesheet-name {
   font-size: 13px;
 }
 
 .theme-dark .stylesheet-title,
 .theme-dark .stylesheet-name {
-  color: #f5f7fa;
+  color: var(--theme-selection-color);
 }
 
 .theme-dark .stylesheet-rule-count,
 .theme-dark .stylesheet-linked-file,
 .theme-dark .stylesheet-saveButton {
-  color: #b6babf;
+  color: var(--theme-body-color-alt);
 }
 
 .theme-light .stylesheet-title,
 .theme-light .stylesheet-name {
-  color: #585959;
+  color: var(--theme-body-color-alt);
 }
 
 .theme-light .stylesheet-rule-count,
 .theme-light .stylesheet-linked-file,
 .theme-light .stylesheet-saveButton {
-  color: #18191a;
+  color: var(--theme-body-color);
 }
 
 .stylesheet-saveButton {
   text-decoration: underline;
   cursor: pointer;
 }
 
 .splitview-active .stylesheet-title,
 .splitview-active .stylesheet-name,
 .theme-light .splitview-active .stylesheet-rule-count,
 .theme-light .splitview-active .stylesheet-linked-file,
 .theme-light .splitview-active .stylesheet-saveButton {
-  color: #f5f7fa;
+  color: var(--theme-selection-color);
 }
 
 .splitview-nav:focus {
   outline: 0; /* focus ring is on the stylesheet name */
 }
 
 .splitview-nav > li.unsaved > hgroup .stylesheet-name {
   font-style: italic;
@@ -200,22 +200,18 @@ h3 {
     -moz-box-align: baseline;
   }
 
   .stylesheet-sidebar {
     width: 180px;
   }
 }
 
-.theme-light .csscoverage-report {
-  background-color: #f0f1f2; /* Toolbars */
-}
-
-.theme-dark .csscoverage-report {
-  background-color: #343c45; /* Toolbars */
+.csscoverage-report {
+  background-color: var(--theme-toolbar-background);
 }
 
 .csscoverage-report-container {
   height: 100vh;
   padding: 0 30px;
 }
 
 .csscoverage-report-content {
@@ -269,44 +265,29 @@ h3 {
   margin: 0;
   padding: 0;
   border-radius: 0;
   border-top: none;
   border-bottom: none;
   -moz-border-start: none;
 }
 
-.theme-dark .chart-colored-blob[name="Used Preload"] {
-  fill: #df80ff; /* Pink highlight */
-  background: #df80ff;
-}
-
-.theme-light .chart-colored-blob[name="Used Preload"] {
-  fill: #b82ee5; /* Pink highlight */
-  background: #b82ee5;
+.chart-colored-blob[name="Used Preload"] {
+  fill: var(--theme-highlight-pink);
+  background: var(--theme-highlight-pink);;
 }
 
-.theme-dark .chart-colored-blob[name=Used] {
-  fill: #70bf53; /* Green highlight */
-  background: #70bf53;
+.chart-colored-blob[name=Used] {
+  fill: var(--theme-highlight-green);
+  background: var(--theme-highlight-green);
 }
 
-.theme-light .chart-colored-blob[name=Used] {
-  fill: #2cbb0f; /* Green highlight */
-  background: #2cbb0f;
-}
-
-.theme-dark .chart-colored-blob[name=Unused] {
-  fill: #d99b28; /* Light Orange highlight */
-  background: #d99b28;
-}
-
-.theme-light .chart-colored-blob[name=Unused] {
-  fill: #d97e00; /* Light Orange highlight */
-  background: #d97e00;
+.chart-colored-blob[name=Unused] {
+  fill: var(--theme-highlight-lightorange);
+  background: var(--theme-highlight-lightorange);
 }
 
 /* Undo 'largest' customization */
 .theme-dark .pie-chart-slice[largest] {
   stroke-width: 1px;
   stroke: rgba(0,0,0,0.2);
 }
 
--- a/browser/themes/shared/devtools/toolbars.inc.css
+++ b/browser/themes/shared/devtools/toolbars.inc.css
@@ -52,16 +52,18 @@
   min-height: 18px;
   padding: 1px;
   text-shadow: none;
   border: none;
   border-radius: 0;
   margin: 2px 3px;
   color: inherit;
   transition: background 0.05s ease-in-out;
+  color: var(--theme-content-color1);
+  background-color: var(--theme-toolbar-background);
 }
 
 .devtools-menulist:-moz-focusring,
 .devtools-toolbarbutton:-moz-focusring {
   outline: 1px dotted hsla(210,30%,85%,0.7);
   outline-offset: -4px;
 }
 
@@ -136,24 +138,20 @@
   -moz-appearance: none !important;
   list-style-image: url("chrome://browser/skin/devtools/dropmarker.svg");
   -moz-box-align: center;
   padding: 0 3px;
 }
 
 .theme-dark .devtools-menulist,
 .theme-dark .devtools-toolbarbutton {
-  color: #a9bacb; /* Body text - high contrast */
-  background-color: #343c45; /* Toolbars */
   border-color: rgba(0, 0, 0, .4); /* Splitters */
 }
 .theme-light .devtools-menulist,
 .theme-light .devtools-toolbarbutton {
-  color: #292e33; /* Body text - high contrast */
-  background-color: #f0f1f2; /* Toolbars */
   border-color: rgba(170, 170, 170, .5); /* Splitters */
 }
 
 /* Text-only buttons */
 .theme-light .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]),
 .theme-light #toolbox-buttons .devtools-toolbarbutton[text-as-image] {
   background-color: rgba(170, 170, 170, .2); /* Splitter */
 }
@@ -184,31 +182,31 @@
 .theme-light .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]):hover:active {
   background: rgba(170, 170, 170, .4); /* Splitters */
 }
 
 /* Menu type buttons and checked states */
 .theme-dark .devtools-toolbarbutton[checked=true],
 .theme-dark #toolbox-buttons .devtools-toolbarbutton[text-as-image][checked] {
   background: rgba(29, 79, 115, .7); /* Select highlight blue */
-  color: #f5f7fa;
+  color: var(--theme-selection-color);
 }
 
 .theme-light .devtools-toolbarbutton[checked=true],
 .theme-light #toolbox-buttons .devtools-toolbarbutton[text-as-image][checked] {
   background: rgba(76, 158, 217, .2); /* Select highlight blue */
 }
 
 .theme-dark .devtools-menulist[open=true],
 .theme-dark .devtools-toolbarbutton[open=true],
 .theme-dark .devtools-toolbarbutton[open=true]:hover,
 .theme-dark .devtools-toolbarbutton[open=true]:hover:active,
 .theme-dark .devtools-toolbarbutton[checked=true]:hover {
   background: rgba(29, 79, 115, .8); /* Select highlight blue */
-  color: #f5f7fa;
+  color: var(--theme-selection-color);
 }
 
 .theme-light .devtools-menulist[open=true],
 .theme-light .devtools-toolbarbutton[open=true],
 .theme-light .devtools-toolbarbutton[open=true]:hover,
 .theme-light .devtools-toolbarbutton[open=true]:hover:active,
 .theme-light .devtools-toolbarbutton[checked=true]:hover {
   background: rgba(76, 158, 217, .4); /* Select highlight blue */
@@ -254,26 +252,17 @@
   margin: 0 3px;
   border: 1px solid;
 %ifdef XP_MACOSX
   border-radius: 20px;
 %else
   border-radius: 2px;
 %endif
   padding: 4px 6px;
-}
-
-.theme-dark .devtools-textinput,
-.theme-dark .devtools-searchinput {
-  border-color: rgb(88, 94, 101);
-}
-
-.theme-light .devtools-textinput,
-.theme-light .devtools-searchinput {
-  border-color: #aaa; /* Match the splitter color */
+  border-color: var(--theme-splitter-color);
 }
 
 .devtools-searchinput {
   margin-top: 1px;
   margin-bottom: 1px;
   padding: 0;
   -moz-padding-start: 22px;
   -moz-padding-end: 12px;
@@ -305,17 +294,17 @@
   background-position: calc(100% - 8px) center;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-search-icons {
   display: none;
 }
 
 .devtools-no-search-result {
-  border-color: #eb5368 !important;
+  border-color: var(--theme-highlight-red) !important;
 }
 
 /* Close button */
 
 .devtools-closebutton {
   -moz-appearance: none;
   border: none;
   margin: 0 4px;
@@ -344,32 +333,31 @@
   display: none;
 }
 
 .devtools-closebutton:hover {
   opacity: 1;
 }
 
 /* In-tools sidebar */
-
 .devtools-sidebar-tabs {
   -moz-appearance: none;
   margin: 0;
 }
 
 .devtools-sidebar-tabs > tabpanels {
   -moz-appearance: none;
   background: transparent;
   padding: 0;
   border: 0;
 }
 
 .theme-light .devtools-sidebar-tabs > tabpanels {
-  background: #f7f7f7;
-  color: #18191a;
+  background: var(--theme-sidebar-background);
+  color: var(--theme-body-color);
 }
 
 .devtools-sidebar-tabs > tabs {
   position: static;
   font: inherit;
   margin-bottom: 0;
   overflow: hidden;
 }
@@ -429,17 +417,17 @@
 
 .theme-dark .devtools-sidebar-tabs > tabs > tab[selected] + tab:hover:active {
   background: hsla(206,37%,4%,.4);
   border-image: @solidSeparatorDark@ 1 1;
 }
 
 .theme-dark .devtools-sidebar-tabs > tabs > tab[selected],
 .theme-dark .devtools-sidebar-tabs > tabs > tab[selected]:hover:active {
-  color: #f5f7fa;
+  color: var(--theme-selection-color);
   background: #1d4f73;
   border-image: @solidSeparatorDark@ 1 1;
 }
 
 .theme-light .devtools-sidebar-tabs > tabs > tab {
   border-image: @smallSeparatorLight@ 1 1;
 }
 
@@ -459,17 +447,17 @@
 
 .theme-light .devtools-sidebar-tabs > tabs > tab[selected] + tab:hover {
   background: #ddd;
   border-image: @solidSeparatorLight@;
 }
 
 .theme-light .devtools-sidebar-tabs > tabs > tab[selected],
 .theme-light .devtools-sidebar-tabs > tabs > tab[selected]:hover:active {
-  color: #f5f7fa;
+  color: var(--theme-selection-color);
   background: #4c9ed9;
   border-image: @solidSeparatorLight@;
 }
 
 /* Toolbox - moved from toolbox.css.
  * Rules that apply to the global toolbox like command buttons,
  * devtools tabs, docking buttons, etc. */
 
@@ -658,28 +646,26 @@
 /* Tabs */
 
 .devtools-tabbar {
   -moz-appearance: none;
   min-height: 28px;
   border: 0px solid;
   border-bottom-width: 1px;
   padding: 0;
+  background: var(--theme-tab-toolbar-background);
+  border-bottom-color: var(--theme-splitter-color);
 }
 
 .theme-light .devtools-tabbar {
   box-shadow: 0 -2px 0 rgba(170,170,170,.1) inset;
-  background: #ebeced;
-  border-bottom-color: #aaa;
 }
 
 .theme-dark .devtools-tabbar {
   box-shadow: 0 -2px 0 rgba(0,0,0,.1) inset;
-  background: #252c33;
-  border-bottom-color: #000;
 }
 
 #toolbox-tabs {
   margin: 0;
 }
 
 .devtools-tab {
   -moz-appearance: none;
@@ -692,37 +678,37 @@
   padding: 0;
   border-style: solid;
   border-width: 0;
   -moz-border-start-width: 1px;
   -moz-box-align: center;
 }
 
 .theme-dark .devtools-tab {
-  color: #b6babf;
+  color: var(--theme-body-color-alt);
   border-color: #42484f;
 }
 
 .theme-light .devtools-tab {
-  color: #18191a;
-  border-color: #aaa;
+  color: var(--theme-body-color);
+  border-color: var(--theme-splitter-color);
 }
 
 .theme-dark .devtools-tab:hover {
   background-color: hsla(206,37%,4%,.2);
   color: #ced3d9;
 }
 
 .theme-light .devtools-tab:hover {
   background-color: rgba(170,170,170,.2);
 }
 
 .theme-dark .devtools-tab:hover:active {
   background-color: hsla(206,37%,4%,.4);
-  color: #f5f7fa;
+  color: var(--theme-selection-color);
 }
 
 .theme-light .devtools-tab:hover:active {
   background-color: rgba(170,170,170,.4);
 }
 
 .theme-dark .devtools-tab:not([selected])[highlighted] {
   background-color: hsla(99,100%,14%,.2);
@@ -750,27 +736,28 @@
   opacity: 0.8;
 }
 
 .devtools-tab:active > image,
 .devtools-tab[selected] > image {
   opacity: 1;
 }
 
+.devtools-tabbar .devtools-tab[selected] {
+  color: var(--theme-selection-color);
+  background-color: var(--theme-selection-background);
+}
+
 .theme-dark .devtools-tabbar .devtools-tab[selected] {
-  color: #f5f7fa;
-  background-color: #1a4666;
   box-shadow: 0 2px 0 #d7f1ff inset,
               0 8px 3px -5px #2b82bf inset,
               0 -2px 0 rgba(0,0,0,.2) inset;
 }
 
 .theme-light .devtools-tabbar .devtools-tab[selected] {
-  color: #f5f7fa;
-  background-color: #4c9ed9;
   box-shadow: 0 2px 0 #d7f1ff inset,
               0 8px 3px -5px #2b82bf inset,
               0 -2px 0 rgba(0,0,0,.06) inset;
 }
 
 #toolbox-tabs .devtools-tab[selected],
 #toolbox-tabs .devtools-tab[highlighted] {
   border-width: 0;
--- a/browser/themes/shared/devtools/webaudioeditor.inc.css
+++ b/browser/themes/shared/devtools/webaudioeditor.inc.css
@@ -1,25 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Reload and waiting notices */
 .notice-container {
   margin-top: -50vh;
-}
-
-.theme-dark .notice-container {
-  background-color: #343c45; /* Toolbars */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .notice-container {
-  background-color: #f0f1f2; /* Toolbars */
-  color: #585959; /* Grey foreground text */
+  background-color: var(--theme-toolbar-background);
+  color: var(--theme-body-color-alt);
 }
 
 #reload-notice {
   font-size: 120%;
 }
 
 #waiting-notice {
   font-size: 110%;
@@ -70,62 +62,51 @@ g.edgePath.param-connection {
  * dotted lines. */
 .theme-dark g.edgeLabel rect {
   fill: #14171a;
 }
 .theme-light g.edgeLabel rect {
   fill: #fcfcfc; /* Background - Editor */
 }
 .theme-dark g.edgeLabel tspan {
-  fill: #b6babf; /* Grey foreground text */
+  fill: var(--theme-body-color-alt);
 }
 .theme-light g.edgeLabel tspan {
   fill: #585959; /* Grey foreground text */
 }
 
 /* Audio Nodes */
 .nodes rect {
   stroke-width: 1px;
   cursor: pointer;
 }
 
-.theme-dark .nodes rect {
-  stroke: #252c33; /* Tab toolbar */
-  fill: #343c45; /* Toolbars */
+.nodes rect {
+  stroke: var(--theme-tab-toolbar-background);
+  fill: var(--theme-toolbar-background);
 }
 
-.theme-light .nodes rect {
-  stroke: #ebeced; /* Tab toolbar */
-  fill: #f0f1f2; /* Toolbar */
-}
-
-.theme-dark .nodes g.selected rect {
-  fill: #1d4f73; /* Select Highlight Blue */
-}
-
-.theme-light .nodes g.selected rect {
-  fill: #4c9ed9; /* Select Highlight Blue */
+.nodes g.selected rect {
+  fill: var(--theme-selection-background);
 }
 
 /* Text in nodes and edges */
 text {
   cursor: default; /* override the "text" cursor */
   font-weight: 300;
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
   font-size: 14px;
 }
 
-.theme-dark text {
-  fill: #b6babf; /* Grey foreground text */
+text {
+  fill: var(--theme-body-color-alt);
 }
-.theme-light text {
-  fill: #585959; /* Grey foreground text */
-}
+
 .theme-light g.selected text {
-  fill: #f0f1f2; /* Toolbars */
+  fill: var(--theme-toolbar-background);
 }
 
 .nodes text {
   cursor: pointer;
 }
 
 /**
  * Inspector Styles
--- a/browser/themes/shared/devtools/webconsole.inc.css
+++ b/browser/themes/shared/devtools/webconsole.inc.css
@@ -155,22 +155,18 @@ a {
   -moz-margin-start: 7px;
   width: calc(100% - 7px);
 }
 
 #output-container.hideTimestamps > .message > .timestamp {
   display: none;
 }
 
-.theme-dark #output-container.hideTimestamps > .message > .indent {
-  background-color: #14171a; /* .theme-body */
-}
-
-.theme-light #output-container.hideTimestamps > .message > .indent {
-  background-color: #fcfcfc; /* .theme-body */
+#output-container.hideTimestamps > .message > .indent {
+  background-color: var(--theme-body-background);
 }
 
 .filtered-by-type,
 .filtered-by-string {
   display: none;
 }
 
 .hidden-message {
@@ -214,22 +210,18 @@ a {
 .theme-light .message[severity=error] {
   background-color: rgba(255, 150, 150, 0.3);
 }
 
 .theme-dark .message[severity=error] {
   background-color: rgba(235, 83, 104, 0.17);
 }
 
-.theme-dark .console-string {
-  color: #d99b28;
-}
-
-.theme-light .console-string {
-  color: hsl(24,85%,39%);
+.console-string {
+  color: var(--theme-highlight-lightorange);
 }
 
 .theme-selected .console-string,
 .theme-selected .cm-number,
 .theme-selected .cm-variable,
 .theme-selected .kind-ArrayLike {
   color: #f5f7fa !important; /* Selection Text Color */
 }
@@ -494,57 +486,49 @@ a {
 .open-inspector:hover {
   background-position: -32px 0;
 }
 
 .open-inspector:active {
   background-position: -16px 0;
 }
 
-/* Replace these values with CSS variables as available */
-.theme-dark .jsterm-input-container {
-  background-color: #252c33; /* tabToolbarBackgroundColor */
-  border-color: #14171a; /* mainBackgroundColor */
+.jsterm-input-container {
+  background-color: var(--theme-tab-toolbar-background);
+  border-color: var(--theme-body-background);
 }
 
-.theme-dark .jsterm-input-node {
-  color: #a9bacb; /* textColor */
+.jsterm-input-node {
+  color: var(--theme-content-color1);
 }
 
-.theme-dark .jsterm-complete-node {
-  color: #5c6773; /* commentColor */
+.jsterm-complete-node {
+  color: var(--theme-comment);
 }
 
-.theme-dark .navigation-marker .url {
-  background: #14171a; /* mainBackgroundColor */
+.navigation-marker .url {
+  background: var(--theme-body-background);
 }
 
 .theme-dark .inlined-variables-view iframe {
   border-color: #333;
 }
 
 .theme-dark .stacktrace {
   border-color: #333;
 }
 
 .theme-light .jsterm-input-container {
-  background-color: #fff; /* mainBackgroundColor */
+  /* For light theme use a white background for the input - it looks better
+     than off-white */
+  background-color: #fff;
   border-color: ThreeDShadow;
 }
-
-.theme-light .jsterm-input-node {
-  color: black; /* textColor */
-}
-
-.theme-light .jsterm-complete-node {
-  color: hsl(90,2%,46%); /* commentColor */
-}
-
 .theme-light .navigation-marker .url {
-  background: #fff; /* mainBackgroundColor */
+  background: #fff;
 }
 
 .theme-light .inlined-variables-view iframe {
   border-color: #ccc;
 }
 
 .theme-light .stacktrace {
   border-color: #ccc;
--- a/browser/themes/shared/devtools/widgets.inc.css
+++ b/browser/themes/shared/devtools/widgets.inc.css
@@ -117,24 +117,24 @@
   opacity: 0.5;
 }
 
 /* Draw shadows to indicate there is more content 'behind' scrollbuttons. */
 .scrollbutton-up:-moz-locale-dir(ltr),
 .scrollbutton-down:-moz-locale-dir(rtl) {
   border-right: solid 1px rgba(255, 255, 255, .1);
   border-left: solid 1px transparent;
-  box-shadow: 3px 0px 3px -3px #181d20;
+  box-shadow: 3px 0px 3px -3px var(--theme-sidebar-background);
 }
 
 .scrollbutton-down:-moz-locale-dir(ltr),
 .scrollbutton-up:-moz-locale-dir(rtl) {
   border-right: solid 1px transparent;
   border-left: solid 1px rgba(255, 255, 255, .1);
-  box-shadow: -3px 0px 3px -3px #181d20;
+  box-shadow: -3px 0px 3px -3px var(--theme-sidebar-background);
 }
 
 .scrollbutton-up[disabled],
 .scrollbutton-down[disabled] {
   box-shadow: none;
   border-color: transparent;
 }
 
@@ -156,34 +156,24 @@
 #breadcrumb-separator-before,
 #breadcrumb-separator-after,
 #breadcrumb-separator-normal {
   width: 12px;
   height: 24px;
   overflow: hidden;
 }
 
-.theme-dark #breadcrumb-separator-before,
-.theme-dark #breadcrumb-separator-after:after {
-  background: #1d4f73; /* Select Highlight Blue */
+#breadcrumb-separator-before,
+#breadcrumb-separator-after:after {
+  background: var(--theme-selection-background);
 }
 
-.theme-dark #breadcrumb-separator-after,
-.theme-dark #breadcrumb-separator-before:after {
-  background: #343c45; /* Toolbars */
-}
-
-.theme-light #breadcrumb-separator-before,
-.theme-light #breadcrumb-separator-after:after {
-  background: #4c9ed9; /* Select Highlight Blue */
-}
-
-.theme-light #breadcrumb-separator-after,
-.theme-light #breadcrumb-separator-before:after {
-  background: #f0f1f2; /* Toolbars */
+#breadcrumb-separator-after,
+#breadcrumb-separator-before:after {
+  background: var(--theme-toolbar-background);
 }
 
 /* This chevron arrow cannot be replicated easily in CSS, so we are using
  * a background image for it (still keeping it in a separate element so
  * we can handle RTL support with a CSS transform).
  */
 #breadcrumb-separator-normal {
   background: url(breadcrumbs-divider@2x.png) no-repeat center right;
@@ -226,22 +216,18 @@
 .breadcrumbs-widget-item[checked] + .breadcrumbs-widget-item {
   background: -moz-element(#breadcrumb-separator-after) no-repeat 0 0;
 }
 
 .breadcrumbs-widget-item[checked] {
   background: -moz-element(#breadcrumb-separator-before) no-repeat 0 0;
 }
 
-.theme-dark .breadcrumbs-widget-item[checked] {
-  background-color: #1d4f73; /* Select Highlight Blue */
-}
-
-.theme-light .breadcrumbs-widget-item[checked] {
-  background-color: #4c9ed9; /* Select Highlight Blue */
+.breadcrumbs-widget-item[checked] {
+  background-color: var(--theme-selection-background);
 }
 
 .breadcrumbs-widget-item:first-child {
   background-image: none;
 }
 
 /* RTL support: move the images that were on the left to the right,
  * and move images that were on the right to the left.
@@ -265,49 +251,37 @@
 #breadcrumb-separator-after:-moz-locale-dir(rtl):after {
   transform: translateX(-5px) rotate(45deg);
 }
 
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-id,
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-tag,
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-pseudo-classes,
 .breadcrumbs-widget-item[checked] .breadcrumbs-widget-item-classes {
-  color: #f5f7fa; /* Foreground (Text) - Light */
+  color: var(--theme-selection-color);
 }
 
 .theme-dark .breadcrumbs-widget-item {
-  color: #f5f7fa; /* Foreground (Text) - Light */
+  color: var(--theme-selection-color);
 }
 
 .theme-light .breadcrumbs-widget-item {
-  color: #18191a; /* Foreground (Text) - Dark */
+  color: var(--theme-body-color);
 }
 
-.theme-dark .breadcrumbs-widget-item-id {
-  color: #b6babf; /* Foreground (Text) - Grey */
-}
-
-.theme-light .breadcrumbs-widget-item-id {
-  color: #585959; /* Foreground (Text) - Grey */
+.breadcrumbs-widget-item-id {
+  color: var(--theme-body-color-alt);
 }
 
-.theme-dark .breadcrumbs-widget-item-classes {
-  color: #a9bacb; /* Content (Text) - Light */
+.breadcrumbs-widget-item-classes {
+  color: var(--theme-content-color1);
 }
 
-.theme-light .breadcrumbs-widget-item-classes {
-  color: #667380; /* Content (Text) - Dark Grey */
-}
-
-.theme-dark .breadcrumbs-widget-item-pseudo-classes {
-  color: #d99b28; /* Light Orange */
-}
-
-.theme-light .breadcrumbs-widget-item-pseudo-classes {
-  color: #d97e00; /* Light Orange */
+.breadcrumbs-widget-item-pseudo-classes {
+  color: var(--theme-highlight-lightorange);
 }
 
 .theme-dark .breadcrumbs-widget-item:not([checked]):hover label {
   color: white;
 }
 
 .theme-light .breadcrumbs-widget-item:not([checked]):hover label {
   color: black;
@@ -315,82 +289,63 @@
 
 /* SimpleListWidget */
 
 .simple-list-widget-container {
   /* Hack: force hardware acceleration */
   transform: translateZ(1px);
 }
 
-.theme-dark .simple-list-widget-item.selected {
-  background-color: #1d4f73; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .simple-list-widget-item.selected {
-  background-color: #4c9ed9; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
+.simple-list-widget-item.selected {
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 .theme-dark .simple-list-widget-item:not(.selected):hover {
   background-color: rgba(255,255,255,.05);
 }
 
 .theme-light .simple-list-widget-item:not(.selected):hover {
   background-color: rgba(0,0,0,.05);
 }
 
 .simple-list-widget-empty-text,
 .simple-list-widget-perma-text {
   padding: 4px 8px;
 }
 
-.theme-dark .simple-list-widget-empty-text,
-.theme-dark .simple-list-widget-perma-text {
-  color: #b6babf; /* Light foreground text */
-}
-
-.theme-light .simple-list-widget-empty-text,
-.theme-light .simple-list-widget-perma-text {
-  color: #585959; /* Grey foreground text */
+.simple-list-widget-empty-text,
+.simple-list-widget-perma-text {
+  color: var(--theme-body-color-alt);
 }
 
 /* FastListWidget */
 
 .fast-list-widget-container {
   /* Hack: force hardware acceleration */
   transform: translateZ(1px);
 }
 
 .fast-list-widget-empty-text {
   padding: 4px 8px;
 }
 
-.theme-dark .fast-list-widget-empty-text {
-  color: #b6babf; /* Light foreground text */
-}
-
-.theme-light .fast-list-widget-empty-text {
-  color: #585959; /* Grey foreground text */
+.fast-list-widget-empty-text {
+  color: var(--theme-body-color-alt);
 }
 
 /* SideMenuWidget */
 
 .side-menu-widget-container {
   /* Hack: force hardware acceleration */
   transform: translateZ(1px);
 }
 
 /* SideMenuWidget container */
 
-.theme-dark .side-menu-widget-container,
-.theme-dark .side-menu-widget-empty-text {
-  background-color: #343c45; /* Toolbars */
-}
-
 .theme-dark .side-menu-widget-container:-moz-locale-dir(ltr),
 .theme-dark .side-menu-widget-empty-text:-moz-locale-dir(ltr) {
   box-shadow: inset -1px 0 0 @smw_marginDark@;
 }
 
 .theme-dark .side-menu-widget-container:-moz-locale-dir(rtl),
 .theme-dark .side-menu-widget-empty-text:-moz-locale-dir(rtl) {
   box-shadow: inset 1px 0 0 @smw_marginDark@;
@@ -415,65 +370,59 @@
   /* To compensate for the arrow image's dark margin. */
   -moz-margin-end: -1px;
 }
 
 /* SideMenuWidget groups */
 
 .side-menu-widget-group-title {
   padding: 4px;
+  background-color: var(--theme-tab-toolbar-background);
 }
 
 .theme-dark .side-menu-widget-group-title {
-  background-color: #252c33; /* Tab toolbar */
-  color: #a9bacb; /* Light content text */
+  color: var(--theme-content-color1);
 }
 
 .theme-light .side-menu-widget-group-title {
-  background-color: #ebeced; /* Tab toolbar */
-  color: #667380; /* Dark grey content text */
+  color: var(--theme-content-color3);
 }
 
 /* SideMenuWidget items */
 
 .side-menu-widget-item {
   /* To compensate for the top and bottom borders */
   margin-top: -1px;
   margin-bottom: -1px;
   background-clip: padding-box;
 }
 
 .theme-dark .side-menu-widget-item {
   border-top: 1px solid @smw_itemDarkTopBorder@;
   border-bottom: 1px solid @smw_itemDarkBottomBorder@;
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-dark .side-menu-widget-item:last-of-type {
   box-shadow: inset 0 -1px 0 @smw_itemDarkTopBorder@;
 }
 
 .theme-light .side-menu-widget-item {
   border-top: 1px solid @smw_itemLightTopBorder@;
   border-bottom: 1px solid @smw_itemLightBottomBorder@;
-  color: #18191a; /* Dark foreground text */
+  color: var(--theme-body-color);
 }
 
 .theme-light .side-menu-widget-item:last-of-type {
   box-shadow: inset 0 -1px 0 @smw_itemLightTopBorder@;
 }
 
-.theme-dark .side-menu-widget-item.selected {
-  background-color: #1d4f73; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .side-menu-widget-item.selected {
-  background-color: #4c9ed9; /* Select Highlight Blue */
-  color: #f5f7fa; /* Light foreground text */
+.side-menu-widget-item.selected {
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 .side-menu-widget-item-arrow {
   -moz-margin-start: -7px;
   width: 7px; /* The image's width is 7 pixels */
   /* Cover the border of the side-menu-widget-item */
   margin-top: -1px;
   margin-bottom: -1px;
@@ -537,91 +486,71 @@
 }
 
 .theme-light .side-menu-widget-item-other {
   background-color: rgba(128,128,128,.1);
 }
 
 .theme-dark .side-menu-widget-item.selected .side-menu-widget-item-other {
   background-color: rgba(0,0,0,.2); /* Darken the selection by 20% */
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-light .side-menu-widget-item.selected .side-menu-widget-item-other {
   background-color: rgba(255,255,255,.8); /* Lighten the selection by 20% */
-  color: #18191a; /* Dark foreground text */
+  color: var(--theme-body-color);
 }
 
-.theme-dark .side-menu-widget-item.selected .side-menu-widget-item-other.selected {
+.side-menu-widget-item.selected .side-menu-widget-item-other.selected {
   background-color: transparent;
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .side-menu-widget-item.selected .side-menu-widget-item-other.selected {
-  background-color: transparent;
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 /* SideMenuWidget checkboxes */
 
 .side-menu-widget-group-checkbox {
   margin: 0;
   -moz-margin-end: 4px;
 }
 
 .side-menu-widget-item-checkbox {
   margin: 0;
   -moz-margin-start: 4px;
 }
 
 /* SideMenuWidget misc */
 
-.side-menu-widget-empty-text {
-  padding: 4px 8px;
+.theme-dark .side-menu-widget-container,
+.theme-dark .side-menu-widget-empty-text {
+  background-color: var(--theme-toolbar-background);
 }
 
-.theme-dark .side-menu-widget-empty-text {
-  background-color: #343c45; /* Toolbars */
-  color: #b6babf; /* Foreground (Text) - Grey */
-}
-
-.theme-light .side-menu-widget-empty-text {
-  background: #f7f7f7; /* Toolbars */
-  color: #585959; /* Grey foreground text */
+.side-menu-widget-empty-text {
+  padding: 4px 8px;
 }
 
 /* VariablesView */
 
 .variables-view-container {
   /* Hack: force hardware acceleration */
   transform: translateZ(1px);
 }
 
 .variables-view-empty-notice {
   padding: 2px;
 }
 
-.theme-dark .variables-view-empty-notice {
-  color: #b6babf; /* Foreground (Text) - Grey */
-}
-
-.theme-light .variables-view-empty-notice {
-  color: #585959; /* Grey foreground text */
+.variables-view-empty-notice {
+  color: var(--theme-body-color-alt);
 }
 
-.theme-dark .variables-view-scope:focus > .title,
-.theme-dark .variable-or-property:focus > .title {
-  background-color: #1d4f73; /* Selection colors */
-  color: #f5f7fa;
-}
-
-.theme-light .variables-view-scope:focus > .title,
-.theme-light .variable-or-property:focus > .title {
-  background-color: #4c9ed9; /* Selection colors */
-  color: #f5f7fa;
+.variables-view-scope:focus > .title,
+.variable-or-property:focus > .title {
+  background-color: var(--theme-selection-background);
+  color: var(--theme-selection-color);
 }
 
 .variables-view-scope > .title {
   border-top-width: 1px;
   border-top-style: solid;
   margin-top: -1px;
 }
 
@@ -1101,31 +1030,26 @@
 /* Charts */
 
 .generic-chart-container {
   /* Hack: force hardware acceleration */
   transform: translateZ(1px);
 }
 
 .theme-dark .generic-chart-container {
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-light .generic-chart-container {
-  color: #585959; /* Grey foreground text */
+  color: var(--theme-body-color-alt);
 }
 
-.theme-dark .chart-colored-blob {
-  fill: #a9bacb; /* Light content text */
-  background: #a9bacb;
-}
-
-.theme-light .chart-colored-blob {
-  fill: #8fa1b2; /* Grey content text */
-  background: #8fa1b2;
+.chart-colored-blob {
+  fill: var(--theme-content-color2);
+  background: var(--theme-content-color2);
 }
 
 /* Charts: Pie */
 
 .pie-chart-slice {
   stroke-width: 1px;
   cursor: pointer;
 }
@@ -1213,56 +1137,52 @@
   cursor: inherit;
 }
 
 .table-chart-totals {
   margin-top: 8px;
   padding-top: 6px;
 }
 
-.theme-dark .table-chart-totals {
-  border-top: 1px solid #b6babf; /* Grey foreground text */
-}
-
-.theme-light .table-chart-totals {
-  border-top: 1px solid #585959; /* Grey foreground text */
+.table-chart-totals {
+  border-top: 1px solid var(--theme-body-color-alt); /* Grey foreground text */
 }
 
 .table-chart-summary-label {
   font-weight: 600;
   padding: 1px 0px;
 }
 
 .theme-dark .table-chart-summary-label {
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-light .table-chart-summary-label {
-  color: #18191a; /* Dark foreground text */
+  color: var(--theme-body-color);
 }
 
 /* Table Widget */
 
 /* Table body */
 
 .table-widget-body > .devtools-side-splitter {
   border: none;
 }
 
 .table-widget-body {
   overflow: auto;
 }
 
 .theme-light .table-widget-body {
-  background: #F7F7F7; /* Background-Sidebar */
+  background: var(--theme-sidebar-background);
 }
 
 .theme-dark .table-widget-body,
 .theme-dark .table-widget-empty-text {
-  background-color: #343c45; /* Toolbars */
+  background-color: var(--theme-toolbar-background);
 }
 
 .theme-dark .table-widget-body:-moz-locale-dir(ltr) {
   box-shadow: inset -1px 0 0 @smw_marginDark@;
 }
 
 .theme-dark .table-widget-body:-moz-locale-dir(rtl) {
   box-shadow: inset 1px 0 0 @smw_marginDark@;
@@ -1342,17 +1262,17 @@
   background-clip: padding-box;
   min-width: 100px;
   -moz-user-focus: normal;
 }
 
 .theme-dark .table-widget-cell {
   border-top: 1px solid @smw_itemDarkTopBorder@;
   border-bottom: 1px solid @smw_itemDarkBottomBorder@;
-  color: #f5f7fa; /* Light foreground text */
+  color: var(--theme-selection-color);
 }
 
 .theme-dark:not(.filtering) .table-widget-cell:nth-child(odd):not(.theme-selected),
 .theme-dark .table-widget-cell:not(.theme-selected)[odd] {
   background: rgba(255,255,255,0.05);
 }
 
 .theme-dark .table-widget-cell:last-of-type {
@@ -1360,45 +1280,35 @@
 }
 
 .theme-light .table-widget-cell {
   border-top: 1px solid @smw_itemLightTopBorder@;
   border-bottom: 1px solid @smw_itemLightBottomBorder@;
 }
 
 .theme-light .table-widget-cell:not(.theme-selected) {
-  color: #18191a; /* Dark foreground text */
+  color: var(--theme-body-color);
 }
 
 .theme-light:not(.filtering) .table-widget-cell:nth-child(odd):not(.theme-selected),
 .theme-light .table-widget-cell:not(.theme-selected)[odd] {
   background: rgba(128,128,128,0.05);
 }
 
 .theme-light .table-widget-cell:last-of-type {
   box-shadow: inset 0 -1px 0 @smw_itemLightTopBorder@;
 }
 
-.theme-light .table-widget-cell.flash-out {
-  animation: light-flash-out 0.5s ease-in;
+.table-widget-cell.flash-out {
+  animation: flash-out 0.5s ease-in;
 }
 
-@keyframes light-flash-out {
+@keyframes flash-out {
   to {
-    background: #E8B671;
-  }
-}
-
-.theme-dark .table-widget-cell.flash-out {
-  animation: dark-flash-out 0.5s ease-in;
-}
-
-@keyframes dark-flash-out {
-  to {
-    background: #B28025;
+    background: var(--theme-contrast-background);
   }
 }
 
 /* Empty text and initial text */
 
 .table-widget-empty-text {
   display: none;
   text-align: center;
--- a/dom/bluetooth/BluetoothService.cpp
+++ b/dom/bluetooth/BluetoothService.cpp
@@ -141,51 +141,17 @@ GetAllBluetoothActors(InfallibleTArray<B
 
 BluetoothService::ToggleBtAck::ToggleBtAck(bool aEnabled)
   : mEnabled(aEnabled)
 { }
 
 NS_METHOD
 BluetoothService::ToggleBtAck::Run()
 {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // This is requested in Bug 836516. With settings this property, WLAN
-  // firmware could be aware of Bluetooth has been turned on/off, so that the
-  // mecahnism of handling coexistence of WIFI and Bluetooth could be started.
-  //
-  // In the future, we may have our own way instead of setting a system
-  // property to let firmware developers be able to sense that Bluetooth has
-  // been toggled.
-#if defined(MOZ_WIDGET_GONK)
-  if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) {
-    BT_WARNING("Failed to set bluetooth enabled property");
-  }
-#endif
-
-  NS_ENSURE_TRUE(sBluetoothService, NS_OK);
-
-  if (sInShutdown) {
-    sBluetoothService = nullptr;
-    return NS_OK;
-  }
-
-  // Update mEnabled of BluetoothService object since
-  // StartInternal/StopInternal have been already done.
-  sBluetoothService->SetEnabled(mEnabled);
-  sToggleInProgress = false;
-
-  nsAutoString signalName;
-  signalName = mEnabled ? NS_LITERAL_STRING("Enabled")
-                        : NS_LITERAL_STRING("Disabled");
-  BluetoothSignal signal(signalName, NS_LITERAL_STRING(KEY_MANAGER), true);
-  sBluetoothService->DistributeSignal(signal);
-
-  // Event 'AdapterAdded' has to be fired after firing 'Enabled'
-  sBluetoothService->TryFiringAdapterAdded();
+  BluetoothService::AcknowledgeToggleBt(mEnabled);
 
   return NS_OK;
 }
 
 class BluetoothService::StartupTask : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
@@ -798,8 +764,58 @@ BluetoothService::Notify(const Bluetooth
   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
     do_GetService("@mozilla.org/system-message-internal;1");
   NS_ENSURE_TRUE_VOID(systemMessenger);
 
   JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
   systemMessenger->BroadcastMessage(type, value,
                                     JS::UndefinedHandleValue);
 }
+
+void
+BluetoothService::AcknowledgeToggleBt(bool aEnabled)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+#if defined(MOZ_WIDGET_GONK)
+  // This is requested in Bug 836516. With settings this property, WLAN
+  // firmware could be aware of Bluetooth has been turned on/off, so that
+  // the mechanism of handling coexistence of WIFI and Bluetooth could be
+  // started.
+  //
+  // In the future, we may have our own way instead of setting a system
+  // property to let firmware developers be able to sense that Bluetooth
+  // has been toggled.
+  if (property_set(PROP_BLUETOOTH_ENABLED, aEnabled ? "true" : "false") != 0) {
+    BT_WARNING("Failed to set bluetooth enabled property");
+  }
+#endif
+
+  if (sInShutdown) {
+    sBluetoothService = nullptr;
+    return;
+  }
+
+  NS_ENSURE_TRUE_VOID(sBluetoothService);
+
+  sBluetoothService->CompleteToggleBt(aEnabled);
+}
+
+void
+BluetoothService::CompleteToggleBt(bool aEnabled)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // Update |mEnabled| of |BluetoothService| object since
+  // |StartInternal| and |StopInternal| have been already
+  // done.
+  SetEnabled(aEnabled);
+  sToggleInProgress = false;
+
+  nsAutoString signalName;
+  signalName = aEnabled ? NS_LITERAL_STRING("Enabled")
+                        : NS_LITERAL_STRING("Disabled");
+  BluetoothSignal signal(signalName, NS_LITERAL_STRING(KEY_MANAGER), true);
+  DistributeSignal(signal);
+
+  // Event 'AdapterAdded' has to be fired after firing 'Enabled'
+  TryFiringAdapterAdded();
+}
--- a/dom/bluetooth/BluetoothService.h
+++ b/dom/bluetooth/BluetoothService.h
@@ -308,16 +308,18 @@ public:
   IsEnabled() const
   {
     return mEnabled;
   }
 
   bool
   IsToggling() const;
 
+  static void AcknowledgeToggleBt(bool aEnabled);
+
   /**
    * Below 2 function/variable are used for ensuring event 'AdapterAdded' will
    * be fired after event 'Enabled'.
    */
   void TryFiringAdapterAdded();
   void AdapterAddedReceived();
 
 protected:
@@ -388,16 +390,18 @@ protected:
   // Called by ToggleBtAck.
   void
   SetEnabled(bool aEnabled);
 
   // Called by Get().
   static BluetoothService*
   Create();
 
+  void CompleteToggleBt(bool aEnabled);
+
   typedef nsClassHashtable<nsStringHashKey, BluetoothSignalObserverList >
   BluetoothSignalObserverTable;
 
   BluetoothSignalObserverTable mBluetoothSignalObserverTable;
 
   bool mEnabled;
 
 private:
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
@@ -59,136 +59,20 @@ static nsTArray<int> sRequestedDeviceCou
 static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sSetPropertyRunnableArray;
 static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sGetDeviceRunnableArray;
 static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sBondingRunnableArray;
 static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sUnbondingRunnableArray;
 static bool sAdapterDiscoverable(false);
 static uint32_t sAdapterDiscoverableTimeout(0);
 
 /**
- *  Classes only used in this file
- */
-
-class SetupAfterEnabledTask MOZ_FINAL : public nsRunnable
-{
-public:
-  class SetAdapterPropertyResultHandler MOZ_FINAL
-  : public BluetoothResultHandler
-  {
-  public:
-    void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
-    {
-      BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
-    }
-  };
-
-  NS_IMETHOD
-  Run()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    // Bluetooth just enabled, clear profile controllers and runnable arrays.
-    sControllerArray.Clear();
-    sBondingRunnableArray.Clear();
-    sGetDeviceRunnableArray.Clear();
-    sSetPropertyRunnableArray.Clear();
-    sUnbondingRunnableArray.Clear();
-
-    // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., It should
-    // be connectable and non-discoverable.
-    NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
-    sBtInterface->SetAdapterProperty(
-      BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
-      new SetAdapterPropertyResultHandler());
-
-    // Try to fire event 'AdapterAdded' to fit the original behaviour when
-    // we used BlueZ as backend.
-    BluetoothService* bs = BluetoothService::Get();
-    NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
-
-    bs->AdapterAddedReceived();
-    bs->TryFiringAdapterAdded();
-
-    // Trigger BluetoothOppManager to listen
-    BluetoothOppManager* opp = BluetoothOppManager::Get();
-    if (!opp || !opp->Listen()) {
-      BT_LOGR("Fail to start BluetoothOppManager listening");
-    }
-
-    return NS_OK;
-  }
-};
-
-/* |ProfileDeinitResultHandler| collect the results of all profile
- * result handlers and calls |Proceed| after all results handlers
- * have been run.
- */
-class ProfileDeinitResultHandler MOZ_FINAL
-: public BluetoothProfileResultHandler
-{
-public:
-  ProfileDeinitResultHandler(unsigned char aNumProfiles)
-  : mNumProfiles(aNumProfiles)
-  {
-    MOZ_ASSERT(mNumProfiles);
-  }
-
-  void Deinit() MOZ_OVERRIDE
-  {
-    if (!(--mNumProfiles)) {
-      Proceed();
-    }
-  }
-
-  void OnError(nsresult aResult) MOZ_OVERRIDE
-  {
-    if (!(--mNumProfiles)) {
-      Proceed();
-    }
-  }
-
-private:
-  void Proceed() const
-  {
-    sBtInterface->Cleanup(nullptr);
-  }
-
-  unsigned char mNumProfiles;
-};
-
-class CleanupTask MOZ_FINAL : public nsRunnable
-{
-public:
-  NS_IMETHOD
-  Run()
-  {
-    static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
-      BluetoothHfpManager::DeinitHfpInterface,
-      BluetoothA2dpManager::DeinitA2dpInterface
-    };
-
-    MOZ_ASSERT(NS_IsMainThread());
-
-    // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
-    nsRefPtr<ProfileDeinitResultHandler> res =
-      new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
-
-    for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
-      sDeinitManager[i](res);
-    }
-
-    return NS_OK;
-  }
-};
-
-/**
  *  Static callback functions
  */
-static void
-ClassToIcon(uint32_t aClass, nsAString& aRetIcon)
+void
+BluetoothServiceBluedroid::ClassToIcon(uint32_t aClass, nsAString& aRetIcon)
 {
   switch ((aClass & 0x1f00) >> 8) {
     case 0x01:
       aRetIcon.AssignLiteral("computer");
       break;
     case 0x02:
       switch ((aClass & 0xfc) >> 2) {
         case 0x01:
@@ -268,18 +152,19 @@ ClassToIcon(uint32_t aClass, nsAString& 
        */
       aRetIcon.AssignLiteral("audio-card");
     } else {
       BT_LOGR("No icon to match class: %x", aClass);
     }
   }
 }
 
-static ControlPlayStatus
-PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
+ControlPlayStatus
+BluetoothServiceBluedroid::PlayStatusStringToControlPlayStatus(
+  const nsAString& aPlayStatus)
 {
   ControlPlayStatus playStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
   if (aPlayStatus.EqualsLiteral("STOPPED")) {
     playStatus = ControlPlayStatus::PLAYSTATUS_STOPPED;
   } else if (aPlayStatus.EqualsLiteral("PLAYING")) {
     playStatus = ControlPlayStatus::PLAYSTATUS_PLAYING;
   } else if (aPlayStatus.EqualsLiteral("PAUSED")) {
     playStatus = ControlPlayStatus::PLAYSTATUS_PAUSED;
@@ -292,46 +177,44 @@ PlayStatusStringToControlPlayStatus(cons
   }
 
   return playStatus;
 }
 
 /**
  *  Static functions
  */
-static bool
-EnsureBluetoothHalLoad()
+bool
+BluetoothServiceBluedroid::EnsureBluetoothHalLoad()
 {
   sBtInterface = BluetoothInterface::GetInstance();
   NS_ENSURE_TRUE(sBtInterface, false);
 
   return true;
 }
 
-class EnableResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::EnableResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     BT_LOGR("BluetoothInterface::Enable failed: %d", aStatus);
 
-    nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+    BluetoothService::AcknowledgeToggleBt(false);
   }
 };
 
 /* |ProfileInitResultHandler| collect the results of all profile
  * result handlers and calls |Proceed| after all results handlers
  * have been run.
  */
-class ProfileInitResultHandler MOZ_FINAL
+class BluetoothServiceBluedroid::ProfileInitResultHandler MOZ_FINAL
 : public BluetoothProfileResultHandler
 {
 public:
   ProfileInitResultHandler(unsigned char aNumProfiles)
   : mNumProfiles(aNumProfiles)
   {
     MOZ_ASSERT(mNumProfiles);
   }
@@ -354,17 +237,18 @@ private:
   void Proceed() const
   {
     sBtInterface->Enable(new EnableResultHandler());
   }
 
   unsigned char mNumProfiles;
 };
 
-class InitResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::InitResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   void Init() MOZ_OVERRIDE
   {
     static void (* const sInitManager[])(BluetoothProfileResultHandler*) = {
       BluetoothHfpManager::InitHfpInterface,
       BluetoothA2dpManager::InitA2dpInterface
     };
@@ -385,80 +269,69 @@ public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     BT_LOGR("BluetoothInterface::Init failed: %d", aStatus);
 
     sBtInterface = nullptr;
 
-    nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+    BluetoothService::AcknowledgeToggleBt(false);
   }
 };
 
-static nsresult
-StartGonkBluetooth()
+nsresult
+BluetoothServiceBluedroid::StartGonkBluetooth()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
 
   if (bs->IsEnabled()) {
     // Keep current enable status
-    nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(true);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+    BluetoothService::AcknowledgeToggleBt(true);
     return NS_OK;
   }
 
   sBtInterface->Init(reinterpret_cast<BluetoothServiceBluedroid*>(bs),
                      new InitResultHandler());
 
   return NS_OK;
 }
 
-class DisableResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::DisableResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     BT_LOGR("BluetoothInterface::Disable failed: %d", aStatus);
 
-    nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(true);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+    BluetoothService::AcknowledgeToggleBt(true);
   }
 };
 
-static nsresult
-StopGonkBluetooth()
+nsresult
+BluetoothServiceBluedroid::StopGonkBluetooth()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
 
   if (!bs->IsEnabled()) {
     // Keep current enable status
-    nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+    BluetoothService::AcknowledgeToggleBt(false);
     return NS_OK;
   }
 
   sBtInterface->Disable(new DisableResultHandler());
 
   return NS_OK;
 }
 
@@ -508,39 +381,31 @@ BluetoothServiceBluedroid::~BluetoothSer
 
 nsresult
 BluetoothServiceBluedroid::StartInternal()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsresult ret = StartGonkBluetooth();
   if (NS_FAILED(ret)) {
-    nsRefPtr<nsRunnable> runnable =
-      new BluetoothService::ToggleBtAck(false);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+    BluetoothService::AcknowledgeToggleBt(false);
     BT_LOGR("Error");
   }
 
   return ret;
 }
 
 nsresult
 BluetoothServiceBluedroid::StopInternal()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsresult ret = StopGonkBluetooth();
   if (NS_FAILED(ret)) {
-    nsRefPtr<nsRunnable> runnable =
-      new BluetoothService::ToggleBtAck(true);
-    if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-      BT_WARNING("Failed to dispatch to main thread!");
-    }
+    BluetoothService::AcknowledgeToggleBt(true);
     BT_LOGR("Error");
   }
 
   return ret;
 }
 
 nsresult
 BluetoothServiceBluedroid::GetDefaultAdapterPathInternal(
@@ -570,18 +435,18 @@ BluetoothServiceBluedroid::GetDefaultAda
   BT_APPEND_NAMED_VALUE(v.get_ArrayOfBluetoothNamedValue(),
                         "Devices", sAdapterBondedAddressArray);
 
   DispatchBluetoothReply(aRunnable, v, EmptyString());
 
   return NS_OK;
 }
 
-class GetRemoteDevicePropertiesResultHandler MOZ_FINAL
-: public BluetoothResultHandler
+class BluetoothServiceBluedroid::GetRemoteDevicePropertiesResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   GetRemoteDevicePropertiesResultHandler(const nsAString& aDeviceAddress)
   : mDeviceAddress(aDeviceAddress)
   { }
 
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
@@ -672,17 +537,18 @@ BluetoothServiceBluedroid::GetPairedDevi
     // Retrieve all properties of devices
     sBtInterface->GetRemoteDeviceProperties(aDeviceAddress[i],
       new GetRemoteDevicePropertiesResultHandler(aDeviceAddress[i]));
   }
 
   return NS_OK;
 }
 
-class StartDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::StartDiscoveryResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   StartDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
   : mRunnable(aRunnable)
   { }
 
   void StartDiscovery() MOZ_OVERRIDE
   {
@@ -707,17 +573,18 @@ BluetoothServiceBluedroid::StartDiscover
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
   sBtInterface->StartDiscovery(new StartDiscoveryResultHandler(aRunnable));
 
   return NS_OK;
 }
 
-class CancelDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::CancelDiscoveryResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   CancelDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
   : mRunnable(aRunnable)
   { }
 
   void CancelDiscovery() MOZ_OVERRIDE
   {
@@ -742,17 +609,18 @@ BluetoothServiceBluedroid::StopDiscovery
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
   sBtInterface->CancelDiscovery(new CancelDiscoveryResultHandler(aRunnable));
 
   return NS_OK;
 }
 
-class SetAdapterPropertyResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::SetAdapterPropertyResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   SetAdapterPropertyResultHandler(BluetoothReplyRunnable* aRunnable)
   : mRunnable(aRunnable)
   { }
 
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
@@ -791,17 +659,18 @@ BluetoothServiceBluedroid::GetServiceCha
 bool
 BluetoothServiceBluedroid::UpdateSdpRecords(
   const nsAString& aDeviceAddress,
   BluetoothProfileManagerBase* aManager)
 {
   return true;
 }
 
-class CreateBondResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::CreateBondResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   CreateBondResultHandler(BluetoothReplyRunnable* aRunnable)
   : mRunnable(aRunnable)
   { }
 
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
@@ -825,17 +694,18 @@ BluetoothServiceBluedroid::CreatePairedD
   sBondingRunnableArray.AppendElement(aRunnable);
 
   sBtInterface->CreateBond(aDeviceAddress,
                            new CreateBondResultHandler(aRunnable));
 
   return NS_OK;
 }
 
-class RemoveBondResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::RemoveBondResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   RemoveBondResultHandler(BluetoothReplyRunnable* aRunnable)
   : mRunnable(aRunnable)
   { }
 
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
@@ -858,17 +728,18 @@ BluetoothServiceBluedroid::RemoveDeviceI
   sUnbondingRunnableArray.AppendElement(aRunnable);
 
   sBtInterface->RemoveBond(aDeviceAddress,
                            new RemoveBondResultHandler(aRunnable));
 
   return NS_OK;
 }
 
-class PinReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::PinReplyResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   PinReplyResultHandler(BluetoothReplyRunnable* aRunnable)
   : mRunnable(aRunnable)
   { }
 
   void PinReply() MOZ_OVERRIDE
   {
@@ -902,17 +773,18 @@ BluetoothServiceBluedroid::SetPinCodeInt
 bool
 BluetoothServiceBluedroid::SetPasskeyInternal(
   const nsAString& aDeviceAddress, uint32_t aPasskey,
   BluetoothReplyRunnable* aRunnable)
 {
   return true;
 }
 
-class SspReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::SspReplyResultHandler MOZ_FINAL
+  : public BluetoothResultHandler
 {
 public:
   SspReplyResultHandler(BluetoothReplyRunnable* aRunnable)
   : mRunnable(aRunnable)
   { }
 
   void SspReply() MOZ_OVERRIDE
   {
@@ -1225,42 +1097,118 @@ void
 BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
 {
 }
 
 //
 // Bluetooth notifications
 //
 
+/* |ProfileDeinitResultHandler| collect the results of all profile
+ * result handlers and calls |Proceed| after all results handlers
+ * have been run.
+ */
+class BluetoothServiceBluedroid::ProfileDeinitResultHandler MOZ_FINAL
+: public BluetoothProfileResultHandler
+{
+public:
+  ProfileDeinitResultHandler(unsigned char aNumProfiles)
+  : mNumProfiles(aNumProfiles)
+  {
+    MOZ_ASSERT(mNumProfiles);
+  }
+
+  void Deinit() MOZ_OVERRIDE
+  {
+    if (!(--mNumProfiles)) {
+      Proceed();
+    }
+  }
+
+  void OnError(nsresult aResult) MOZ_OVERRIDE
+  {
+    if (!(--mNumProfiles)) {
+      Proceed();
+    }
+  }
+
+private:
+  void Proceed() const
+  {
+    sBtInterface->Cleanup(nullptr);
+  }
+
+  unsigned char mNumProfiles;
+};
+
+class BluetoothServiceBluedroid::SetAdapterPropertyDiscoverableResultHandler
+  MOZ_FINAL
+  : public BluetoothResultHandler
+{
+public:
+  void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
+  {
+    BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
+  }
+};
+
 void
 BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BT_LOGR("BT_STATE: %d", aState);
 
   bool isBtEnabled = (aState == true);
 
-  if (!isBtEnabled &&
-      NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) {
-    BT_WARNING("Failed to dispatch to main thread!");
-    return;
+  if (!isBtEnabled) {
+    static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
+      BluetoothHfpManager::DeinitHfpInterface,
+      BluetoothA2dpManager::DeinitA2dpInterface
+    };
+
+    // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
+    nsRefPtr<ProfileDeinitResultHandler> res =
+      new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
+
+    for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
+      sDeinitManager[i](res);
+    }
   }
 
-  nsRefPtr<nsRunnable> runnable =
-    new BluetoothService::ToggleBtAck(isBtEnabled);
-  if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
-    BT_WARNING("Failed to dispatch to main thread!");
-    return;
-  }
+  BluetoothService::AcknowledgeToggleBt(isBtEnabled);
+
+  if (isBtEnabled) {
+    // Bluetooth just enabled, clear profile controllers and runnable arrays.
+    sControllerArray.Clear();
+    sBondingRunnableArray.Clear();
+    sGetDeviceRunnableArray.Clear();
+    sSetPropertyRunnableArray.Clear();
+    sUnbondingRunnableArray.Clear();
 
-  if (isBtEnabled &&
-      NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) {
-    BT_WARNING("Failed to dispatch to main thread!");
-    return;
+    // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., It should
+    // be connectable and non-discoverable.
+    NS_ENSURE_TRUE_VOID(sBtInterface);
+    sBtInterface->SetAdapterProperty(
+      BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
+      new SetAdapterPropertyDiscoverableResultHandler());
+
+    // Try to fire event 'AdapterAdded' to fit the original behaviour when
+    // we used BlueZ as backend.
+    BluetoothService* bs = BluetoothService::Get();
+    NS_ENSURE_TRUE_VOID(bs);
+
+    bs->AdapterAddedReceived();
+    bs->TryFiringAdapterAdded();
+
+    // Trigger BluetoothOppManager to listen
+    BluetoothOppManager* opp = BluetoothOppManager::Get();
+    if (!opp || !opp->Listen()) {
+      BT_LOGR("Fail to start BluetoothOppManager listening");
+    }
   }
 }
 
 /**
  * AdapterPropertiesNotification will be called after enable() but
  * before AdapterStateChangeCallback is called. At that moment, both
  * BluetoothManager and BluetoothAdapter, do not register observer
  * yet.
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
@@ -11,16 +11,31 @@
 #include "BluetoothInterface.h"
 #include "BluetoothService.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothServiceBluedroid : public BluetoothService
                                 , public BluetoothNotificationHandler
 {
+  class CancelDiscoveryResultHandler;
+  class CreateBondResultHandler;
+  class DisableResultHandler;
+  class EnableResultHandler;
+  class GetRemoteDevicePropertiesResultHandler;
+  class InitResultHandler;
+  class PinReplyResultHandler;
+  class ProfileDeinitResultHandler;
+  class ProfileInitResultHandler;
+  class RemoveBondResultHandler;
+  class SetAdapterPropertyDiscoverableResultHandler;
+  class SetAdapterPropertyResultHandler;
+  class SspReplyResultHandler;
+  class StartDiscoveryResultHandler;
+
 public:
   BluetoothServiceBluedroid();
   ~BluetoothServiceBluedroid();
 
   virtual nsresult StartInternal();
   virtual nsresult StopInternal();
 
   virtual nsresult GetDefaultAdapterPathInternal(
@@ -191,14 +206,24 @@ public:
                                            const nsAString& aRemoteBdAddr,
                                            bool aState) MOZ_OVERRIDE;
 
   virtual void DutModeRecvNotification(uint16_t aOpcode,
                                        const uint8_t* aBuf,
                                        uint8_t aLen) MOZ_OVERRIDE;
   virtual void LeTestModeNotification(BluetoothStatus aStatus,
                                       uint16_t aNumPackets) MOZ_OVERRIDE;
+
+protected:
+  static nsresult StartGonkBluetooth();
+  static nsresult StopGonkBluetooth();
+  static bool EnsureBluetoothHalLoad();
+
+  static void ClassToIcon(uint32_t aClass, nsAString& aRetIcon);
+
+  static ControlPlayStatus PlayStatusStringToControlPlayStatus(
+    const nsAString& aPlayStatus);
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
 
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -801,17 +801,25 @@ Layer::ComputeEffectiveTransformForMaskL
 {
   if (mMaskLayer) {
     mMaskLayer->mEffectiveTransform = aTransformToSurface;
 
 #ifdef DEBUG
     bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D();
     NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
 #endif
-    mMaskLayer->mEffectiveTransform = mMaskLayer->GetTransform() * mMaskLayer->mEffectiveTransform;
+    // Use our shadow transform and base transform to compute a delta for the
+    // mask layer's effective transform, as though it was also transformed by
+    // the APZ.
+    //
+    // Note: This will fail if the base transform is degenerate. Currently, this
+    //       is not expected for OMTA transformed layers.
+    mMaskLayer->mEffectiveTransform = mMaskLayer->GetTransform() *
+      GetTransform().Inverse() * GetLocalTransform() *
+      mMaskLayer->mEffectiveTransform;
   }
 }
 
 RenderTargetRect
 Layer::TransformRectToRenderTarget(const LayerIntRect& aRect)
 {
   LayerRect rect(aRect);
   RenderTargetRect quad = RenderTargetRect::FromUnknown(
new file mode 100644
--- /dev/null
+++ b/gfx/tests/reftest/1086723-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Testcase for bug 1086723</title>
+  <style type="text/css">
+    .test_div {
+      position: fixed;
+      overflow: hidden;
+      background: blue;
+      width: 50%;
+      height: 50%;
+      border-radius: 0px 50% 50% 0px;
+    }
+    .filler {
+      height: 5000px;
+    }
+    body,html {
+      overflow: hidden;
+    }
+  </style>
+</head>
+<body>
+  <div class="test_div"></div>
+  <div class="filler"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/gfx/tests/reftest/1086723.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html reftest-async-scroll reftest-async-scroll-x="0" reftest-async-scroll-y="2000">
+<head>
+  <meta charset="utf-8">
+  <title>Testcase for bug 1086723</title>
+  <style type="text/css">
+    .test_div {
+      position: fixed;
+      overflow: hidden;
+      background: blue;
+      width: 50%;
+      height: 50%;
+      border-radius: 0px 50% 50% 0px;
+    }
+    .filler {
+      height: 5000px;
+    }
+    body,html {
+      overflow: hidden;
+    }
+  </style>
+</head>
+<body>
+  <div class="test_div"></div>
+  <div class="filler"></div>
+</body>
+</html>
--- a/gfx/tests/reftest/reftest.list
+++ b/gfx/tests/reftest/reftest.list
@@ -1,4 +1,5 @@
 # 468496-1 will also detect bugs in video drivers.
 == 468496-1.html 468496-1-ref.html
 fuzzy-if(winWidget,175,443) == 611498-1.html 611498-ref.html
 skip-if(B2G) fuzzy-if(Android&&AndroidVersion>=15,8,1000) == 709477-1.html 709477-1-ref.html # bug 773482
+skip-if(!asyncPanZoom) == 1086723.html 1086723-ref.html
--- a/mobile/android/base/resources/values/styles.xml
+++ b/mobile/android/base/resources/values/styles.xml
@@ -199,16 +199,17 @@
         <item name="android:layout_height">match_parent</item>
         <item name="android:paddingTop">0dp</item>
         <item name="android:stretchMode">columnWidth</item>
         <item name="android:numColumns">auto_fit</item>
         <item name="android:columnWidth">@dimen/tabs_grid_view_column_width</item>
         <item name="android:horizontalSpacing">2dp</item>
         <item name="android:verticalSpacing">2dp</item>
         <item name="android:drawSelectorOnTop">true</item>
+        <item name="android:clipToPadding">false</item>
     </style>
 
     <style name="Widget.BookmarkItemView" parent="Widget.TwoLinePageRow"/>
 
     <style name="Widget.BookmarksListView" parent="Widget.HomeListView"/>
 
     <style name="Widget.TopSitesThumbnailView">
       <item name="android:padding">0dip</item>
--- a/toolkit/components/places/History.jsm
+++ b/toolkit/components/places/History.jsm
@@ -60,16 +60,18 @@
  * @see nsINavHistoryObserver
  */
 
 this.EXPORTED_SYMBOLS = [ "History" ];
 
 const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
+                                  "resource://gre/modules/AsyncShutdown.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
@@ -78,36 +80,72 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyServiceGetter(this, "gNotifier",
                                    "@mozilla.org/browser/nav-history-service;1",
                                    Ci.nsPIPlacesHistoryListenersNotifier);
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 Cu.importGlobalProperties(["URL"]);
 
 /**
+ * Whenever we update or remove numerous pages, it is preferable
+ * to yield time to the main thread every so often to avoid janking.
+ * This constant determines the maximal number of notifications we
+ * may emit before we yield.
+ */
+const NOTIFICATION_CHUNK_SIZE = 300;
+
+/**
+ * Private shutdown barrier blocked by ongoing operations.
+ */
+XPCOMUtils.defineLazyGetter(this, "operationsBarrier", () =>
+  new AsyncShutdown.Barrier("Sqlite.jsm: wait until all connections are closed")
+);
+
+/**
  * Shared connection
  */
 XPCOMUtils.defineLazyGetter(this, "DBConnPromised",
   () => new Promise((resolve) => {
     Sqlite.wrapStorageConnection({ connection: PlacesUtils.history.DBConnection } )
           .then(db => {
       try {
-        Sqlite.shutdown.addBlocker("Places History.jsm: Closing database wrapper",
-                                   () => db.close());
+        Sqlite.shutdown.addBlocker(
+          "Places History.jsm: Closing database wrapper",
+          Task.async(function*() {
+            yield operationsBarrier.wait();
+            gIsClosed = true;
+            yield db.close();
+          }),
+          () => ({
+            fetchState: () => ({
+              isClosed: gIsClosed,
+              operations: operationsBarrier.state,
+            })
+          }));
       } catch (ex) {
         // It's too late to block shutdown of Sqlite, so close the connection
         // immediately.
         db.close();
         throw ex;
       }
       resolve(db);
     });
   })
 );
 
+/**
+ * `true` once this module has been shutdown.
+ */
+let gIsClosed = false;
+function ensureModuleIsOpen() {
+  if (gIsClosed) {
+    throw new Error("History.jsm has been shutdown");
+  }
+}
+
 this.History = Object.freeze({
   /**
    * Fetch the available information for one page.
    *
    * @param guidOrURI: (URL or nsIURI)
    *      The full URI of the page.
    *            or (string)
    *      Either the full URI of the page or the GUID of the page.
@@ -204,16 +242,18 @@ this.History = Object.freeze({
    * @resolve (bool)
    *      `true` if at least one page was removed, `false` otherwise.
    * @throws (TypeError)
    *       If `pages` has an unexpected type or if a string provided
    *       is neither a valid GUID nor a valid URI or if `pages`
    *       is an empty array.
    */
   remove: function (pages, onResult = null) {
+    ensureModuleIsOpen();
+
     // Normalize and type-check arguments
     if (Array.isArray(pages)) {
       if (pages.length == 0) {
         throw new TypeError("Expected at least one page");
       }
     } else {
       pages = [pages];
     }
@@ -225,25 +265,48 @@ this.History = Object.freeze({
       // be normalized.
       let normalized = normalizeToURLOrGUID(page);
       if (typeof normalized === "string") {
         guids.push(normalized);
       } else {
         urls.push(normalized.href);
       }
     }
+    let normalizedPages = {guids: guids, urls: urls};
+
     // At this stage, we know that either `guids` is not-empty
     // or `urls` is not-empty.
 
     if (onResult && typeof onResult != "function") {
       throw new TypeError("Invalid function: " + onResult);
     }
 
-    // Now perform queries
-    return remove({guids: guids, urls: urls}, onResult);
+    return Task.spawn(function*() {
+      let promise = remove(normalizedPages, onResult);
+
+      operationsBarrier.client.addBlocker(
+        "History.remove",
+        promise,
+        {
+          // In case of crash, we do not want to upload information on
+          // which urls are being cleared, for privacy reasons. GUIDs
+          // are safe wrt privacy, but useless.
+          fetchState: () => ({
+            guids: guids.length,
+            urls: normalizedPages.urls.map(u => u.protocol),
+          })
+        });
+
+      try {
+        return (yield promise);
+      } finally {
+        // Cleanup the barrier.
+        operationsBarrier.client.removeBlocker(promise);
+      }
+    });
   },
 
   /**
    * Determine if a page has been visited.
    *
    * @param pages: (URL or nsIURI)
    *      The full URI of the page.
    *            or (string)
rename from toolkit/components/places/tests/unit/history/head_history.js
rename to toolkit/components/places/tests/history/head_history.js
--- a/toolkit/components/places/tests/unit/history/head_history.js
+++ b/toolkit/components/places/tests/history/head_history.js
@@ -7,13 +7,13 @@
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Import common head.
-let (commonFile = do_get_file("../../head_common.js", false)) {
+let (commonFile = do_get_file("../head_common.js", false)) {
   let uri = Services.io.newFileURI(commonFile);
   Services.scriptloader.loadSubScript(uri.spec, this);
 };
 
rename from toolkit/components/places/tests/unit/history/test_remove.js
rename to toolkit/components/places/tests/history/test_remove.js
rename from toolkit/components/places/tests/unit/history/xpcshell.ini
rename to toolkit/components/places/tests/history/xpcshell.ini
--- a/toolkit/components/places/tests/moz.build
+++ b/toolkit/components/places/tests/moz.build
@@ -6,22 +6,22 @@
 
 TEST_DIRS += ['cpp']
 
 XPCSHELL_TESTS_MANIFESTS += [
     'autocomplete/xpcshell.ini',
     'bookmarks/xpcshell.ini',
     'expiration/xpcshell.ini',
     'favicons/xpcshell.ini',
+    'history/xpcshell.ini',
     'inline/xpcshell.ini',
     'migration/xpcshell.ini',
     'network/xpcshell.ini',
     'queries/xpcshell.ini',
     'unifiedcomplete/xpcshell.ini',
-    'unit/history/xpcshell.ini',
     'unit/xpcshell.ini',
     'xpcshell.ini',
 ]
 
 BROWSER_CHROME_MANIFESTS += ['browser/browser.ini']
 MOCHITEST_CHROME_MANIFESTS += [
     'chrome.ini',
     'chrome/chrome.ini',
--- a/toolkit/content/aboutTelemetry.css
+++ b/toolkit/content/aboutTelemetry.css
@@ -117,26 +117,26 @@ body[dir="rtl"] .histogram {
   overflow: hidden;
 }
 
 .keyed-histogram {
   white-space: nowrap;
   padding: 15px;
   position: relative; /* required for position:absolute of the contained .copy-node */
   display: block;
+  overflow: hidden;
 }
 
 .keyed-histogram-title {
   text-overflow: ellipsis;
   width: 100%;
   margin: 10px;
   font-weight: bold;
   font-size: 120%;
   white-space: nowrap;
-  overflow: hidden;
 }
 
 
 .bar {
   width: 2em;
   margin: 2px;
   text-align: center;
   float: left;