Merge m-c to inbound. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 17 Jul 2015 10:27:24 -0400
changeset 253486 ea2b6887033b21ef89cad2d19204dd537abdf076
parent 253485 ec3acc5237a8f5bee8a969e10ad7b6135a7723e4 (current diff)
parent 253469 911935404233ebe6d54f87a11b89073f7558517b (diff)
child 253487 ecd916f018fdbad3a2332cc2c5d84b562d699f87
push id29067
push userkwierso@gmail.com
push dateSat, 18 Jul 2015 00:57:04 +0000
treeherdermozilla-central@e2f2eb9ecca0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone42.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
browser/base/content/searchSuggestionUI.css
browser/base/content/searchSuggestionUI.js
browser/base/content/test/general/browser_searchSuggestionUI.js
browser/base/content/test/general/searchSuggestionUI.html
browser/base/content/test/general/searchSuggestionUI.js
build/mobile/robocop/robotium-solo-5.4.1.jar
dom/system/gonk/tests/test_ril_worker_mmi.js
dom/system/gonk/tests/test_ril_worker_mmi_cf.js
dom/telephony/test/marionette/test_mmi.js
mobile/android/base/resources/drawable/anchored_popup_bg.xml
toolkit/devtools/touch-events.js
--- a/b2g/chrome/content/desktop.js
+++ b/b2g/chrome/content/desktop.js
@@ -5,23 +5,19 @@
 let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
 let isMulet = "ResponsiveUI" in browserWindow;
 
 // Enable touch event shim on desktop that translates mouse events
 // into touch ones
 function enableTouch() {
   let require = Cu.import('resource://gre/modules/devtools/Loader.jsm', {})
                   .devtools.require;
-  let { TouchEventHandler } = require('devtools/touch-events');
-  let chromeEventHandler = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                                 .getInterface(Ci.nsIWebNavigation)
-                                 .QueryInterface(Ci.nsIDocShell)
-                                 .chromeEventHandler || window;
-  let touchEventHandler = new TouchEventHandler(chromeEventHandler);
-  touchEventHandler.start();
+  let { TouchEventSimulator } = require('devtools/toolkit/touch/simulator');
+  let touchEventSimulator = new TouchEventSimulator(shell.contentBrowser);
+  touchEventSimulator.start();
 }
 
 function setupButtons() {
   let homeButton = document.getElementById('home-button');
   if (!homeButton) {
     // The toolbar only exists in b2g desktop build with
     // FXOS_SIMULATOR turned on.
     return;
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
   <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36", 
+        "git_revision": "8c009877aff6b8b2f4a60756e2d09c0182393721", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "dfd4a9e8f31e64d427030d3612a48f7dbcada5d3", 
+    "revision": "494ef969c9ddbf15fc8a094c2da7bc46d08b1fc3", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -402,17 +402,17 @@ pref("browser.search.defaultenginename",
 pref("browser.search.order.1",                "chrome://browser-region/locale/region.properties");
 pref("browser.search.order.2",                "chrome://browser-region/locale/region.properties");
 pref("browser.search.order.3",                "chrome://browser-region/locale/region.properties");
 
 // Market-specific search defaults
 // This is disabled globally, and then enabled for individual locales
 // in firefox-l10n.js (eg. it's enabled for en-US).
 pref("browser.search.geoSpecificDefaults", false);
-pref("browser.search.geoSpecificDefaults.url", "");
+pref("browser.search.geoSpecificDefaults.url", "https://search.services.mozilla.com/1/%APP%/%VERSION%/%CHANNEL%/%LOCALE%/%REGION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%");
 
 // US specific default (used as a fallback if the geoSpecificDefaults request fails).
 pref("browser.search.defaultenginename.US",      "data:text/plain,browser.search.defaultenginename.US=Yahoo");
 pref("browser.search.order.US.1",                "data:text/plain,browser.search.order.US.1=Yahoo");
 pref("browser.search.order.US.2",                "data:text/plain,browser.search.order.US.2=Google");
 pref("browser.search.order.US.3",                "data:text/plain,browser.search.order.US.3=Bing");
 
 // search bar results always open in a new tab
@@ -1858,16 +1858,19 @@ pref("identity.fxaccounts.settings.uri",
 pref("identity.fxaccounts.remote.profile.uri", "https://profile.accounts.firefox.com/v1");
 
 // The remote URL of the FxA OAuth Server
 pref("identity.fxaccounts.remote.oauth.uri", "https://oauth.accounts.firefox.com/v1");
 
 // Whether we display profile images in the UI or not.
 pref("identity.fxaccounts.profile_image.enabled", true);
 
+// Token server used by the FxA Sync identity.
+pref("identity.sync.tokenserver.uri", "https://token.services.mozilla.com/1.0/sync/1.5");
+
 // Migrate any existing Firefox Account data from the default profile to the
 // Developer Edition profile.
 #ifdef MOZ_DEV_EDITION
 pref("identity.fxaccounts.migrateToDevEdition", true);
 #else
 pref("identity.fxaccounts.migrateToDevEdition", false);
 #endif
 
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -42,25 +42,20 @@ const gXPInstallObserver = {
       }
       return;
     }
 
     const anchorID = "addons-notification-icon";
 
     // Make notifications persist a minimum of 30 seconds
     var options = {
-      timeout: Date.now() + 30000
+      displayURI: installInfo.originatingURI,
+      timeout: Date.now() + 30000,
     };
 
-    try {
-      options.displayOrigin = installInfo.originatingURI.host;
-    } catch (e) {
-      // originatingURI might be missing or 'host' might throw for non-nsStandardURL nsIURIs.
-    }
-
     let cancelInstallation = () => {
       if (installInfo) {
         for (let install of installInfo.installs)
           install.cancel();
       }
 
       this.acceptInstallation = null;
 
@@ -195,25 +190,20 @@ const gXPInstallObserver = {
 
     const anchorID = "addons-notification-icon";
     var messageString, action;
     var brandShortName = brandBundle.getString("brandShortName");
 
     var notificationID = aTopic;
     // Make notifications persist a minimum of 30 seconds
     var options = {
-      timeout: Date.now() + 30000
+      displayURI: installInfo.originatingURI,
+      timeout: Date.now() + 30000,
     };
 
-    try {
-      options.displayOrigin = installInfo.originatingURI.host;
-    } catch (e) {
-      // originatingURI might be missing or 'host' might throw for non-nsStandardURL nsIURIs.
-    }
-
     switch (aTopic) {
     case "addon-install-disabled": {
       notificationID = "xpinstall-disabled";
 
       if (gPrefService.prefIsLocked("xpinstall.enabled")) {
         messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
         buttons = [];
       }
@@ -287,17 +277,23 @@ const gXPInstallObserver = {
         acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
       } else {
         acceptButton.hidden = true;
       }
       break; }
     case "addon-install-failed": {
       // TODO This isn't terribly ideal for the multiple failure case
       for (let install of installInfo.installs) {
-        let host = options.displayOrigin;
+        let host;
+        try {
+          host  = options.displayURI.host;
+        } catch (e) {
+          // displayURI might be missing or 'host' might throw for non-nsStandardURL nsIURIs.
+        }
+
         if (!host)
           host = (install.sourceURI instanceof Ci.nsIStandardURL) &&
                  install.sourceURI.host;
 
         let error = (host || install.error == 0) ? "addonInstallError" : "addonLocalInstallError";
         let args;
         if (install.error < 0) {
           error += install.error;
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -1353,8 +1353,15 @@ toolbarpaletteitem[place="palette"][hidd
 
 #password-notification-password:hover::after {
   color: hsl(210,100%,50%);
 }
 
 #password-notification-password[focused]::after {
   content: none;
 }
+
+/* Bug 1175941: Disable the transition on 10.10 due to flickering, possibly due to an OS X bug. */
+@media (-moz-mac-yosemite-theme) {
+  #password-notification-password::after {
+    transition: none;
+  }
+}
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5169,16 +5169,18 @@ var TabsInTitlebar = {
       if (tabAndMenuHeight > titlebarContentHeight) {
         // We need to increase the titlebar content's outer height (ie including margins)
         // to match the tab and menu height:
         let extraMargin = tabAndMenuHeight - titlebarContentHeight;
 #ifndef XP_MACOSX
         titlebarContent.style.marginBottom = extraMargin + "px";
 #endif
         titlebarContentHeight += extraMargin;
+      } else {
+        titlebarContent.style.removeProperty("margin-bottom");
       }
 
       // Then we bring up the titlebar by the same amount, but we add any negative margin:
       titlebar.style.marginBottom = "-" + titlebarContentHeight + "px";
 
 
       // Finally, size the placeholders:
 #ifdef XP_MACOSX
@@ -7099,35 +7101,31 @@ var gIdentityHandler = {
 
     // Update the popup strings
     this.setPopupMessages(this._identityBox.className);
 
     this.updateSitePermissions();
 
     // Add the "open" attribute to the identity box for styling
     this._identityBox.setAttribute("open", "true");
-    var self = this;
-    this._identityPopup.addEventListener("popuphidden", function onPopupHidden(e) {
-      e.currentTarget.removeEventListener("popuphidden", onPopupHidden, false);
-      self._identityBox.removeAttribute("open");
-    }, false);
 
     // Now open the popup, anchored off the primary chrome element
     this._identityPopup.openPopup(this._identityIcon, "bottomcenter topleft");
   },
 
   onPopupShown(event) {
     if (event.target == this._identityPopup) {
       window.addEventListener("focus", this, true);
     }
   },
 
   onPopupHidden(event) {
     if (event.target == this._identityPopup) {
       window.removeEventListener("focus", this, true);
+      this._identityBox.removeAttribute("open");
     }
   },
 
   handleEvent(event) {
     let elem = document.activeElement;
     let position = elem.compareDocumentPosition(this._identityPopup);
 
     if (!(position & (Node.DOCUMENT_POSITION_CONTAINS |
--- a/browser/base/content/test/general/browser_parsable_css.js
+++ b/browser/base/content/test/general/browser_parsable_css.js
@@ -16,16 +16,19 @@ const kWhitelist = [
   {sourceName: /codemirror\.css/i},
   // PDFjs is futureproofing its pseudoselectors, and those rules are dropped.
   {sourceName: /web\/viewer\.css/i,
    errorMessage: /Unknown pseudo-class.*(fullscreen|selection)/i},
   // Tracked in bug 1004428.
   {sourceName: /aboutaccounts\/(main|normalize)\.css/i},
   // TokBox SDK assets, see bug 1032469.
   {sourceName: /loop\/.*sdk-content\/.*\.css$/i},
+  // Loop standalone client CSS uses placeholder cross browser pseudo-element
+  {sourceName: /loop\/.*\.css/i,
+   errorMessage: /Unknown pseudo-class.*placeholder/i},
   // Highlighter CSS uses chrome-only pseudo-class, see bug 985597.
   {sourceName: /highlighter\.css/i,
    errorMessage: /Unknown pseudo-class.*moz-native-anonymous/i},
 ];
 
 let moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
 let {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
 
--- a/browser/base/content/test/general/browser_trackingUI_1.js
+++ b/browser/base/content/test/general/browser_trackingUI_1.js
@@ -53,27 +53,35 @@ function testBenignPage() {
   ok (hidden("#tracking-action-unblock"), "unblockButton is hidden");
 
   // Make sure that the no tracking elements message appears
   ok (!hidden("#tracking-not-detected"), "labelNoTracking is visible");
   ok (hidden("#tracking-loaded"), "labelTrackingLoaded is hidden");
   ok (hidden("#tracking-blocked"), "labelTrackingBlocked is hidden");
 }
 
-function testTrackingPage() {
+function testTrackingPage(window) {
   info("Tracking content must be blocked");
   ok (!TrackingProtection.container.hidden, "The container is visible");
   is (TrackingProtection.content.getAttribute("state"), "blocked-tracking-content",
       'content: state="blocked-tracking-content"');
   is (TrackingProtection.icon.getAttribute("state"), "blocked-tracking-content",
       'icon: state="blocked-tracking-content"');
 
   ok (!hidden("#tracking-protection-icon"), "icon is visible");
   ok (hidden("#tracking-action-block"), "blockButton is hidden");
-  ok (!hidden("#tracking-action-unblock"), "unblockButton is visible");
+
+
+  if (PrivateBrowsingUtils.isWindowPrivate(window)) {
+    ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
+    ok(!hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is visible");
+  } else {
+    ok(!hidden("#tracking-action-unblock"), "unblockButton is visible");
+    ok(hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is hidden");
+  }
 
   // Make sure that the blocked tracking elements message appears
   ok (hidden("#tracking-not-detected"), "labelNoTracking is hidden");
   ok (hidden("#tracking-loaded"), "labelTrackingLoaded is hidden");
   ok (!hidden("#tracking-blocked"), "labelTrackingBlocked is visible");
 }
 
 function testTrackingPageUnblocked() {
@@ -96,29 +104,29 @@ function testTrackingPageUnblocked() {
 
 function* testTrackingProtectionForTab(tab) {
   info("Load a test page not containing tracking elements");
   yield promiseTabLoadEvent(tab, BENIGN_PAGE);
   testBenignPage();
 
   info("Load a test page containing tracking elements");
   yield promiseTabLoadEvent(tab, TRACKING_PAGE);
-  testTrackingPage();
+  testTrackingPage(tab.ownerDocument.defaultView);
 
   info("Disable TP for the page (which reloads the page)");
   let tabReloadPromise = promiseTabLoadEvent(tab);
   clickButton("#tracking-action-unblock");
   yield tabReloadPromise;
   testTrackingPageUnblocked();
 
   info("Re-enable TP for the page (which reloads the page)");
   tabReloadPromise = promiseTabLoadEvent(tab);
   clickButton("#tracking-action-block");
   yield tabReloadPromise;
-  testTrackingPage();
+  testTrackingPage(tab.ownerDocument.defaultView);
 }
 
 add_task(function* testNormalBrowsing() {
   yield UrlClassifierTestUtils.addTestTrackers();
 
   browser = gBrowser;
   let tab = browser.selectedTab = browser.addTab();
 
--- a/browser/base/content/test/plugins/browser_CTP_hide_overlay.js
+++ b/browser/base/content/test/plugins/browser_CTP_hide_overlay.js
@@ -24,37 +24,33 @@ add_task(function* () {
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
 
   yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");
 
   // Work around for delayed PluginBindingAttached
   yield promiseUpdatePluginBindings(gBrowser.selectedBrowser);
 
-  // Tests that the overlay can be hidded for disabled plugins using the close icon.
-  yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
+  // Tests that the overlay can be hidden for plugins using the close icon.
+  let overlayIsVisible = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
     let doc = content.document;
     let plugin = doc.getElementById("test");
     let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
     let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon")
     let bounds = closeIcon.getBoundingClientRect();
     let left = (bounds.left + bounds.right) / 2;
     let top = (bounds.top + bounds.bottom) / 2;
     let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                        .getInterface(Components.interfaces.nsIDOMWindowUtils);
     utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
     utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
+
+    return overlay.classList.contains("visible");
   });
 
-  let overlayIsVisible = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
-    let doc = content.document;
-    let plugin = doc.getElementById("test");
-    let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
-    return plugin && overlay.classList.contains("visible");
-  });
   ok(!overlayIsVisible, "overlay should be hidden.");
 });
 
 // Test that the overlay cannot be interacted with after the user closes the overlay
 add_task(function* () {
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
 
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -3111,19 +3111,19 @@ file, You can obtain one at http://mozil
           if (!this._notificationType) {
             return;
           }
 
           let viewsLeft = this._viewsLeft;
           if (viewsLeft) {
             let notification = this._panel.firstElementChild.notification;
             if (this._notificationType == "passwords" && notification && notification.options &&
-                notification.options.origin) {
+                notification.options.displayURI instanceof Ci.nsIStandardURL) {
               let fxAOrigin = new URL(Services.prefs.getCharPref("identity.fxaccounts.remote.signup.uri")).origin
-              if (notification.options.origin == fxAOrigin) {
+              if (notification.options.displayURI.prePath == fxAOrigin) {
                 // Somewhat gross hack - we don't want to show the sync promo while
                 // the user may be logging into Sync.
                 return;
               }
             }
 
             if (Services.prefs.prefHasUserValue("services.sync.username") &&
                this._notificationType != "addons-sync-disabled") {
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -39,33 +39,38 @@
       <hbox id="tracking-protection-container" class="identity-popup-section">
         <vbox id="tracking-protection-content" flex="1">
           <description class="identity-popup-text identity-popup-headline"
                        crop="end"
                        value="&trackingProtection.title;" />
 
           <label id="tracking-blocked"
                  class="identity-popup-text"
-                 crop="end">&trackingProtection.detectedBlocked;</label>
+                 crop="end">&trackingProtection.detectedBlocked2;</label>
           <label id="tracking-loaded"
                  class="identity-popup-text"
-                 crop="end">&trackingProtection.detectedNotBlocked;</label>
+                 crop="end">&trackingProtection.detectedNotBlocked2;</label>
           <label id="tracking-not-detected"
                  class="identity-popup-text"
-                 crop="end">&trackingProtection.notDetected;</label>
+                 crop="end">&trackingProtection.notDetected2;</label>
 
           <button id="tracking-action-unblock"
                   label="&trackingProtection.unblock.label;"
                   class="identity-popup-button"
                   accesskey="&trackingProtection.unblock.accesskey;"
                   oncommand="TrackingProtection.disableForCurrentPage();" />
+          <button id="tracking-action-unblock-private"
+                  label="&trackingProtection.unblockPrivate.label;"
+                  class="identity-popup-button"
+                  accesskey="&trackingProtection.unblock.accesskey;"
+                  oncommand="TrackingProtection.disableForCurrentPage();" />
           <button id="tracking-action-block"
-                  label="&trackingProtection.block.label;"
+                  label="&trackingProtection.block2.label;"
                   class="identity-popup-button"
-                  accesskey="&trackingProtection.block.accesskey;"
+                  accesskey="&trackingProtection.block2.accesskey;"
                   oncommand="TrackingProtection.enableForCurrentPage();" />
         </vbox>
       </hbox>
 
       <!-- Permissions Section -->
       <hbox id="identity-popup-permissions" class="identity-popup-section">
         <vbox id="identity-popup-permissions-content" flex="1">
           <label class="identity-popup-text identity-popup-headline"
--- a/browser/components/customizableui/test/browser_946320_tabs_from_other_computers.js
+++ b/browser/components/customizableui/test/browser_946320_tabs_from_other_computers.js
@@ -82,17 +82,17 @@ function configureFxAccountIdentity() {
     kA: "kA",
     kB: "kB",
     sessionToken: "sessionToken",
     uid: "user_uid",
     verified: true,
   };
 
   let token = {
-    endpoint: Weave.Svc.Prefs.get("tokenServerURI"),
+    endpoint: null,
     duration: 300,
     id: "id",
     key: "key",
     // uid will be set to the username.
   };
 
   let MockInternal = {};
   let mockTSC = { // TokenServerClient
--- a/browser/components/loop/content/css/panel.css
+++ b/browser/components/loop/content/css/panel.css
@@ -210,17 +210,17 @@ body {
 .rooms > h1 {
   font-weight: bold;
   color: #999;
   padding: .5rem 0;
 }
 
 .new-room-view > .context {
   margin: .5rem 0 0;
-  background-color: #DEEFF7;
+  background-color: #dbf7ff;
   border-radius: 3px 3px 0 0;
   padding: .5rem;
 }
 
 .new-room-view > .context > .context-enabled {
   margin-bottom: .5rem;
   display: block;
 }
@@ -238,17 +238,17 @@ body {
   background-color: #fff;
 }
 
 .new-room-view > .context > .checkbox-wrapper > .checkbox.checked {
   background-image: url("../shared/img/check.svg#check-blue");
 }
 
 .new-room-view > .context > .checkbox-wrapper > label {
-  color: #3c3c3c;
+  color: #333;
   font-weight: 700;
 }
 
 .new-room-view > .btn {
   display: block;
   font-size: 1rem;
   margin: 0 auto .5rem;
   width: 100%;
--- a/browser/components/loop/content/shared/css/common.css
+++ b/browser/components/loop/content/shared/css/common.css
@@ -515,17 +515,17 @@ html[dir="rtl"] .context-content {
 
 .context-content > p {
   font-weight: bold;
   margin-bottom: .8em;
   margin-top: 0;
 }
 
 .context-wrapper {
-  border: 1px solid #0096dd;
+  border: 1px solid #5cccee;
   border-radius: 3px;
   background: #fff;
   padding: .8em;
   /* Use the flex row mode to position the elements next to each other. */
   display: flex;
   flex-flow: row nowrap;
   line-height: 1.1em;
 }
--- a/browser/components/loop/content/shared/css/conversation.css
+++ b/browser/components/loop/content/shared/css/conversation.css
@@ -1460,38 +1460,43 @@ html[dir="rtl"] .standalone .room-conver
 
 .text-chat-entries {
   overflow: auto;
 }
 
 .text-chat-entry {
   display: flex;
   flex-direction: row;
+  margin-right: .2em;
   margin-bottom: .5em;
-  text-align: start;
+  text-align: end;
   flex-wrap: nowrap;
   justify-content: flex-start;
   align-content: stretch;
   align-items: flex-start;
 }
 
+html[dir="rtl"] .text-chat-entry {
+  margin-right: auto;
+  margin-left: .2em;
+}
+
 .text-chat-entry > p {
   position: relative;
   z-index: 10;
   /* Drop the default margins from the 'p' element. */
   margin: 0;
   padding: .7em;
   /* leave some room for the chat bubble arrow */
   max-width: 80%;
   border-width: 1px;
   border-style: solid;
-  border-color: #2ea4ff;
+  border-color: #5cccee;
   background: #fff;
   word-wrap: break-word;
-  word-wrap: break-word;
   flex: 0 1 auto;
   align-self: auto;
 }
 
 .text-chat-entry.sent > p,
 .text-chat-entry.received > p {
   background: #fff;
 }
@@ -1529,17 +1534,17 @@ html[dir="rtl"] .text-chat-entry.receive
 }
 
 .text-chat-entry.received > p {
   border-color: #d8d8d8;
 }
 
 /* Text chat entry timestamp */
 .text-chat-entry-timestamp {
-  margin: 0 .2em;
+  margin: 0 .5em;
   color: #aaa;
   font-style: italic;
   font-size: .8em;
   order: 0;
   flex: 0 1 auto;
   align-self: center;
 }
 
@@ -1664,17 +1669,42 @@ html[dir="rtl"] .text-chat-entry.receive
 }
 
 .text-chat-box > form > input {
   width: 100%;
   height: 40px;
   padding: 0 .5em .5em;
   font-size: 1.1em;
   border: 0;
-  border-top: 1px solid #999;
+  border-top: 1px solid #d8d8d8;
+}
+
+.text-chat-box > form > input::-webkit-input-placeholder {
+  font-size: 1.1em;
+  color: #999;
+}
+
+.text-chat-box > form > input::-moz-placeholder {
+  font-size: 1.1em;
+  color: #999;
+}
+
+.text-chat-box > form > input:-moz-placeholder {
+  font-size: 1.1em;
+  color: #999;
+}
+
+.text-chat-box > form > input:-ms-input-placeholder {
+  font-size: 1.1em;
+  color: #999;
+}
+
+.text-chat-box > form > input:input-placeholder {
+  font-size: 1.1em;
+  color: #999;
 }
 
 /* turn the visible border blue as a visual indicator of focus */
 .text-chat-box > form > input:focus {
   border-top: 1px solid #66c9f2;
 }
 
 @media screen and (max-width:640px) {
--- a/browser/components/loop/content/shared/img/chatbubble-arrow-right.svg
+++ b/browser/components/loop/content/shared/img/chatbubble-arrow-right.svg
@@ -1,14 +1,14 @@
 <?xml version="1.0"?>
 <svg width="20" height="9" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <title>chatbubble-arrow</title>
  <desc>Created with Sketch.</desc>
  <g>
   <title>Layer 1</title>
   <g id="svg_1" fill="none">
-   <path id="svg_2" fill="#2EA4FF" d="m19.505243,8.972466l-9.299002,0l0,-1l6.088001,0c-2.110002,-0.967 -4.742001,-2.818 -6.088001,-6.278l0.932,-0.363c2.202,5.664 8.377999,6.637 8.44,6.646c0.259001,0.039 0.444,0.27 0.426001,0.531c-0.019001,0.262 -0.237,0.464 -0.498999,0.464l-12.072001,-0.352"/>
+   <path id="svg_2" fill="#5cccee" d="m19.505243,8.972466l-9.299002,0l0,-1l6.088001,0c-2.110002,-0.967 -4.742001,-2.818 -6.088001,-6.278l0.932,-0.363c2.202,5.664 8.377999,6.637 8.44,6.646c0.259001,0.039 0.444,0.27 0.426001,0.531c-0.019001,0.262 -0.237,0.464 -0.498999,0.464l-12.072001,-0.352"/>
   </g>
   <line id="svg_13" y2="8.474788" x2="6.200791" y1="8.474788" x1="10.265923" stroke="#22a4ff" fill="none"/>
   <line id="svg_26" y2="8.474788" x2="2.14584" y1="8.474788" x1="6.210972" stroke="#22a4ff" fill="none"/>
   <line id="svg_27" y2="8.474788" x2="0.000501" y1="8.474788" x1="4.065633" stroke="#22a4ff" fill="none"/>
  </g>
 </svg>
\ No newline at end of file
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -737,17 +737,30 @@ nsDefaultCommandLineHandler.prototype = 
     try {
       var ar;
       while ((ar = cmdLine.handleFlagWithParam("url", false))) {
         var uri = resolveURIInternal(cmdLine, ar);
 
         // Searches in the Windows 10 task bar searchbox simply open the default browser
         // with a URL for a search on Bing. Here we extract the search term and use the
         // user's default search engine instead.
-        if (redirectWinSearch && uri.spec.startsWith("https://www.bing.com/search")) {
+        var uriScheme = "", uriHost = "", uriPath = "";
+        try {
+          uriScheme = uri.scheme;
+          uriHost = uri.host;
+          uriPath = uri.path;
+        } catch(e) {
+        }
+
+        // Most Windows searches are "https://www.bing.com/search...", but bug
+        // 1182308 reports a Chinese edition of Windows 10 using
+        // "http://cn.bing.com/search...", so be a bit flexible in what we match.
+        if (redirectWinSearch &&
+            (uriScheme == "http" || uriScheme == "https") &&
+            uriHost.endsWith(".bing.com") && uriPath.startsWith("/search")) {
           try {
             var url = uri.QueryInterface(Components.interfaces.nsIURL);
             var params = new URLSearchParams(url.query);
             // We don't want to rewrite all Bing URLs coming from external apps. Look
             // for the magic URL parm that's present in searches from the task bar.
             // (Typed searches use "form=WNSGPH", Cortana voice searches use "FORM=WNSBOX")
             var formParam = params.get("form");
             if (!formParam) {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2435,19 +2435,17 @@ ContentPermissionPrompt.prototype = {
     let types = aRequest.types.QueryInterface(Ci.nsIArray);
     if (types.length != 1) {
       aRequest.cancel();
       return;
     }
 
     if (!aOptions)
       aOptions = {};
-    aOptions.displayOrigin = (requestPrincipal.URI instanceof Ci.nsIFileURL) ?
-                             requestPrincipal.URI.file.path :
-                             requestPrincipal.URI.host;
+    aOptions.displayOrigin = requestPrincipal.URI;
 
     return chromeWin.PopupNotifications.show(browser, aNotificationId, aMessage, aAnchorId,
                                              mainAction, secondaryActions, aOptions);
   },
 
   _promptPush : function(aRequest) {
     var message = gBrowserBundle.GetStringFromName("push.enablePush2");
 
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -364,29 +364,16 @@ var gPrivacyPane = {
       mode.selectedIndex = this._lastMode;
       mode.doCommand();
 
       this._shouldPromptForRestart = true;
   },
 
   // HISTORY
 
-  /**
-   * Update browser.urlbar.autocomplete.enabled when a
-   * browser.urlbar.suggest.* pref is changed from the ui.
-   */
-  writeSuggestionPref() {
-    let getVal = (aPref) => {
-      return document.getElementById("browser.urlbar.suggest." + aPref).value;
-    }
-    // autocomplete.enabled is true if any of the suggestions is true
-    let enabled = ["history", "bookmark", "openpage", "searches"].map(getVal).some(v => v);
-    Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", enabled);
-  },
-
   /*
    * Preferences:
    *
    * places.history.enabled
    * - whether history is enabled or not
    * browser.formfill.enable
    * - true if entries in forms and the search bar should be saved, false
    *   otherwise
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -248,25 +248,21 @@
 
 <!-- Location Bar -->
 <groupbox id="locationBarGroup"
           data-category="panePrivacy"
           hidden="true">
   <caption><label>&locationBar.label;</label></caption>
   <label id="locationBarSuggestionLabel">&locbar.suggest.label;</label>
   <checkbox id="historySuggestion" label="&locbar.history.label;"
-            onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
             accesskey="&locbar.history.accesskey;"
             preference="browser.urlbar.suggest.history"/>
   <checkbox id="bookmarkSuggestion" label="&locbar.bookmarks.label;"
-            onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
             accesskey="&locbar.bookmarks.accesskey;"
             preference="browser.urlbar.suggest.bookmark"/>
   <checkbox id="openpageSuggestion" label="&locbar.openpage.label;"
-            onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
             accesskey="&locbar.openpage.accesskey;"
             preference="browser.urlbar.suggest.openpage"/>
   <checkbox id="searchesSuggestion" label="&locbar.searches.label;"
             hidden="true"
-            onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
             accesskey="&locbar.searches.accesskey;"
             preference="browser.urlbar.suggest.searches"/>
 </groupbox>
--- a/browser/components/preferences/in-content/sync.js
+++ b/browser/components/preferences/in-content/sync.js
@@ -182,25 +182,25 @@ let gSyncPane = {
     });
     setEventListener("syncEnginesList", "select", function () {
       if (this.selectedCount)
         this.clearSelection();
     });
     setEventListener("syncComputerName", "change", function (e) {
       gSyncUtils.changeName(e.target);
     });
-    setEventListener("fxaChangeDeviceName", "click", function () {
+    setEventListener("fxaChangeDeviceName", "command", function () {
       this._toggleComputerNameControls(true);
       this._focusComputerNameTextbox();
     });
-    setEventListener("fxaCancelChangeDeviceName", "click", function () {
+    setEventListener("fxaCancelChangeDeviceName", "command", function () {
       this._toggleComputerNameControls(false);
       this._updateComputerNameValue(false);
     });
-    setEventListener("fxaSaveChangeDeviceName", "click", function () {
+    setEventListener("fxaSaveChangeDeviceName", "command", function () {
       this._toggleComputerNameControls(false);
       this._updateComputerNameValue(true);
     });
     setEventListener("unlinkDevice", "click", function () {
       gSyncPane.startOver(true);
       return false;
     });
     setEventListener("tosPP-normal-ToS", "click", gSyncPane.openToS);
@@ -314,44 +314,45 @@ let gSyncPane = {
         if (!data) {
           this.page = FXA_PAGE_LOGGED_OUT;
           return false;
         }
         this.page = FXA_PAGE_LOGGED_IN;
         // We are logged in locally, but maybe we are in a state where the
         // server rejected our credentials (eg, password changed on the server)
         let fxaLoginStatus = document.getElementById("fxaLoginStatus");
-        let enginesListDisabled;
+        let syncReady;
         // Not Verfied implies login error state, so check that first.
         if (!data.verified) {
           fxaLoginStatus.selectedIndex = FXA_LOGIN_UNVERIFIED;
-          enginesListDisabled = true;
+          syncReady = false;
         // So we think we are logged in, so login problems are next.
         // (Although if the Sync identity manager is still initializing, we
         // ignore login errors and assume all will eventually be good.)
         // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in".
         // All other login failures are assumed to be transient and should go
         // away by themselves, so aren't reflected here.
         } else if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
           fxaLoginStatus.selectedIndex = FXA_LOGIN_FAILED;
-          enginesListDisabled = true;
+          syncReady = false;
         // Else we must be golden (or in an error state we expect to magically
         // resolve itself)
         } else {
           fxaLoginStatus.selectedIndex = FXA_LOGIN_VERIFIED;
-          enginesListDisabled = false;
+          syncReady = true;
         }
         fxaEmailAddress1Label.textContent = data.email;
         document.getElementById("fxaEmailAddress2").textContent = data.email;
         document.getElementById("fxaEmailAddress3").textContent = data.email;
         document.getElementById("fxaSyncComputerName").value = Weave.Service.clientsEngine.localName;
         let engines = document.getElementById("fxaSyncEngines")
         for (let checkbox of engines.querySelectorAll("checkbox")) {
-          checkbox.disabled = enginesListDisabled;
+          checkbox.disabled = !syncReady;
         }
+        document.getElementById("fxaChangeDeviceName").disabled = !syncReady;
 
         // Clear the profile image (if any) of the previously logged in account.
         document.getElementById("fxaProfileImage").style.removeProperty("background-image");
 
         // If the account is verified the next promise in the chain will
         // fetch profile data.
         return data.verified;
       }).then(isVerified => {
--- a/browser/components/preferences/in-content/sync.xul
+++ b/browser/components/preferences/in-content/sync.xul
@@ -340,18 +340,18 @@
             <button id="fxaSaveChangeDeviceName"
                     label="&saveChangeSyncDeviceName.label;"
                     hidden="true"/>
           </hbox>
         </hbox>
       </vbox>
     </groupbox>
     <spacer flex="1"/>
-    <hbox id="tosPP-small">
+    <vbox id="tosPP-small">
       <label id="tosPP-small-ToS" class="text-link">
         &prefs.tosLink.label;
       </label>
       <label id="tosPP-small-PP" class="text-link">
         &fxaPrivacyNotice.link.label;
       </label>
-    </hbox>
+    </vbox>
   </vbox>
 </deck>
--- a/browser/components/preferences/privacy.js
+++ b/browser/components/preferences/privacy.js
@@ -319,29 +319,16 @@ var gPrivacyPane = {
       mode.selectedIndex = this._lastMode;
       mode.doCommand();
 
       this._shouldPromptForRestart = true;
   },
 
   // HISTORY
 
-  /**
-   * Update browser.urlbar.autocomplete.enabled when a
-   * browser.urlbar.suggest.* pref is changed from the ui.
-   */
-  writeSuggestionPref() {
-    let getVal = (aPref) => {
-      return document.getElementById("browser.urlbar.suggest." + aPref).value;
-    }
-    // autocomplete.enabled is true if any of the suggestions is true
-    let enabled = ["history", "bookmark", "openpage", "searches"].map(getVal).some(v => v);
-    Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", enabled);
-  },
-
   /*
    * Preferences:
    *
    * places.history.enabled
    * - whether history is enabled or not
    * browser.formfill.enable
    * - true if entries in forms and the search bar should be saved, false
    *   otherwise
--- a/browser/components/preferences/privacy.xul
+++ b/browser/components/preferences/privacy.xul
@@ -267,30 +267,26 @@
     <!-- Location Bar -->
     <groupbox id="locationBarGroup">
       <caption label="&locationBar.label;"/>
 
       <label id="locationBarSuggestionLabel">&locbar.suggest.label;</label>
 
       <vbox id="tabPrefsBox" align="start" flex="1">
         <checkbox id="historySuggestion" label="&locbar.history.label;"
-                  onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
                   accesskey="&locbar.history.accesskey;"
                   preference="browser.urlbar.suggest.history"/>
         <checkbox id="bookmarkSuggestion" label="&locbar.bookmarks.label;"
-                  onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
                   accesskey="&locbar.bookmarks.accesskey;"
                   preference="browser.urlbar.suggest.bookmark"/>
         <checkbox id="openpageSuggestion" label="&locbar.openpage.label;"
-                  onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
                   accesskey="&locbar.openpage.accesskey;"
                   preference="browser.urlbar.suggest.openpage"/>
         <checkbox id="searchesSuggestion" label="&locbar.searches.label;"
                   hidden="true"
-                  onsyncfrompreference="return gPrivacyPane.writeSuggestionPref();"
                   accesskey="&locbar.searches.accesskey;"
                   preference="browser.urlbar.suggest.searches"/>
       </vbox>
     </groupbox>
 
   </prefpane>
 
 </overlay>
--- a/browser/components/sessionstore/test/browser_607016.js
+++ b/browser/components/sessionstore/test/browser_607016.js
@@ -1,57 +1,30 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
 
 let stateBackup = ss.getBrowserState();
 
-function cleanup() {
-  // Reset the pref
-  try {
-    Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
-  } catch (e) {}
-  ss.setBrowserState(stateBackup);
-  executeSoon(finish);
-}
-
-function test() {
+add_task(function* () {
   /** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/
-  waitForExplicitFinish();
   ignoreAllUncaughtExceptions();
 
   // Set the pref to true so we know exactly how many tabs should be restoring at
   // any given time. This guarantees that a finishing load won't start another.
   Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
 
-  // We have our own progress listener for this test, which we'll attach before our state is set
-  let progressListener = {
-    onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
-      if (aBrowser.__SS_restoreState == TAB_STATE_RESTORING &&
-          aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
-          aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
-          aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)
-        progressCallback(aBrowser);
-    }
-  }
-
   let state = { windows: [{ tabs: [
     { entries: [{ url: "http://example.org#1" }], extData: { "uniq": r() } },
     { entries: [{ url: "http://example.org#2" }], extData: { "uniq": r() } }, // overwriting
     { entries: [{ url: "http://example.org#3" }], extData: { "uniq": r() } }, // hiding
     { entries: [{ url: "http://example.org#4" }], extData: { "uniq": r() } }, // adding
     { entries: [{ url: "http://example.org#5" }], extData: { "uniq": r() } }, // deleting
     { entries: [{ url: "http://example.org#6" }] } // creating
   ], selected: 1 }] };
 
-  function progressCallback(aBrowser) {
-    // We'll remove the progress listener after the first one because we aren't
-    // loading any other tabs
-    window.gBrowser.removeTabsProgressListener(progressListener);
-
+  function* progressCallback() {
     let curState = JSON.parse(ss.getBrowserState());
     for (let i = 0; i < curState.windows[0].tabs.length; i++) {
       let tabState = state.windows[0].tabs[i];
       let tabCurState = curState.windows[0].tabs[i];
       if (tabState.extData) {
         is(tabCurState.extData["uniq"], tabState.extData["uniq"],
            "sanity check that tab has correct extData");
       }
@@ -62,56 +35,65 @@ function test() {
         ok(!("extData" in tabCurState) || !("uniq" in tabCurState.extData),
            "sanity check that tab doesn't have extData or extData doesn't have 'uniq'");
       }
     }
 
     // Now we'll set a new unique value on 1 of the tabs
     let newUniq = r();
     ss.setTabValue(gBrowser.tabs[1], "uniq", newUniq);
-    gBrowser.removeTab(gBrowser.tabs[1]);
+    yield promiseRemoveTab(gBrowser.tabs[1]);
     let closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0];
     is(closedTabData.state.extData.uniq, newUniq,
        "(overwriting) new data is stored in extData");
 
     // hide the next tab before closing it
     gBrowser.hideTab(gBrowser.tabs[1]);
-    gBrowser.removeTab(gBrowser.tabs[1]);
+    yield promiseRemoveTab(gBrowser.tabs[1]);
     closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0];
     ok(closedTabData.state.hidden, "(hiding) tab data has hidden == true");
 
     // set data that's not in a conflicting key
     let stillUniq = r();
     ss.setTabValue(gBrowser.tabs[1], "stillUniq", stillUniq);
-    gBrowser.removeTab(gBrowser.tabs[1]);
+    yield promiseRemoveTab(gBrowser.tabs[1]);
     closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0];
     is(closedTabData.state.extData.stillUniq, stillUniq,
        "(adding) new data is stored in extData");
 
     // remove the uniq value and make sure it's not there in the closed data
     ss.deleteTabValue(gBrowser.tabs[1], "uniq");
-    gBrowser.removeTab(gBrowser.tabs[1]);
+    yield promiseRemoveTab(gBrowser.tabs[1]);
     closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0];
     // Since Panorama might have put data in, first check if there is extData.
     // If there is explicitly check that "uniq" isn't in it. Otherwise, we're ok
     if ("extData" in closedTabData.state) {
       ok(!("uniq" in closedTabData.state.extData),
          "(deleting) uniq not in existing extData");
     }
     else {
       ok(true, "(deleting) no data is stored in extData");
     }
 
     // set unique data on the tab that never had any set, make sure that's saved
     let newUniq2 = r();
     ss.setTabValue(gBrowser.tabs[1], "uniq", newUniq2);
-    gBrowser.removeTab(gBrowser.tabs[1]);
+    yield promiseRemoveTab(gBrowser.tabs[1]);
     closedTabData = (JSON.parse(ss.getClosedTabData(window)))[0];
     is(closedTabData.state.extData.uniq, newUniq2,
        "(creating) new data is stored in extData where there was none");
-
-    cleanup();
   }
 
-  window.gBrowser.addTabsProgressListener(progressListener);
+  // Set the test state.
   ss.setBrowserState(JSON.stringify(state));
-}
+
+  // Wait until the selected tab is restored and all others are pending.
+  yield Promise.all(Array.map(gBrowser.tabs, tab => {
+    return (tab == gBrowser.selectedTab) ?
+      promiseTabRestored(tab) : promiseTabRestoring(tab)
+  }));
 
+  // Kick off the actual tests.
+  yield progressCallback();
+
+  // Cleanup.
+  yield promiseBrowserState(stateBackup);
+});
--- a/browser/devtools/.eslintrc
+++ b/browser/devtools/.eslintrc
@@ -14,16 +14,17 @@
     "EventEmitter": true,
     "exports": true,
     "loader": true,
     "module": true,
     "require": true,
     "Services": true,
     "Task": true,
     "XPCOMUtils": true,
+    "XPCNativeWrapper": true,
   },
   "rules": {
     // These are the rules that have been configured so far to match the
     // devtools coding style.
 
     // Disallow using variables outside the blocks they are defined (especially
     // since only let and const are used, see "no-var").
     "block-scoped-var": 2,
--- a/browser/devtools/responsivedesign/responsivedesign.jsm
+++ b/browser/devtools/responsivedesign/responsivedesign.jsm
@@ -13,18 +13,19 @@ Cu.import("resource:///modules/devtools/
 Cu.import("resource://gre/modules/devtools/event-emitter.js");
 Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
 let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
 
 var require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
 let Telemetry = require("devtools/shared/telemetry");
-let {showDoorhanger} = require("devtools/shared/doorhanger");
-let {TouchEventHandler} = require("devtools/touch-events");
+let { showDoorhanger } = require("devtools/shared/doorhanger");
+let { TouchEventSimulator } = require("devtools/toolkit/touch/simulator");
+let { Task } = require("resource://gre/modules/Task.jsm");
 
 this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"];
 
 const MIN_WIDTH = 50;
 const MIN_HEIGHT = 50;
 
 const MAX_WIDTH = 10000;
 const MAX_HEIGHT = 10000;
@@ -129,17 +130,16 @@ function ResponsiveUI(aWindow, aTab)
   this.tab = aTab;
   this.mm = this.tab.linkedBrowser.messageManager;
   this.tabContainer = aWindow.gBrowser.tabContainer;
   this.browser = aTab.linkedBrowser;
   this.chromeDoc = aWindow.document;
   this.container = aWindow.gBrowser.getBrowserContainer(this.browser);
   this.stack = this.container.querySelector(".browserStack");
   this._telemetry = new Telemetry();
-  this.e10s = !this.browser.contentWindow;
 
   let childOn = () => {
     this.mm.removeMessageListener("ResponsiveMode:Start:Done", childOn);
     ResponsiveUIManager.emit("on", { tab: this.tab });
   }
   this.mm.addMessageListener("ResponsiveMode:Start:Done", childOn);
 
   let requiresFloatingScrollbars = !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
@@ -214,21 +214,19 @@ function ResponsiveUI(aWindow, aTab)
       this.rotate();
     }
   } catch(e) {}
 
   ActiveTabs.set(aTab, this);
 
   this._telemetry.toolOpened("responsive");
 
-  if (!this.e10s) {
-    // Touch events support
-    this.touchEnableBefore = false;
-    this.touchEventHandler = new TouchEventHandler(this.browser);
-  }
+  // Touch events support
+  this.touchEnableBefore = false;
+  this.touchEventSimulator = new TouchEventSimulator(this.browser);
 
   // Hook to display promotional Developer Edition doorhanger. Only displayed once.
   showDoorhanger({
     window: this.mainWindow,
     type: "deveditionpromo",
     anchor: this.chromeDoc.querySelector("#content")
   });
 }
@@ -269,19 +267,17 @@ ResponsiveUI.prototype = {
     this.menulist.removeEventListener("change", this.bound_handleManualInput, true);
     this.tab.removeEventListener("TabClose", this);
     this.tabContainer.removeEventListener("TabSelect", this);
     this.rotatebutton.removeEventListener("command", this.bound_rotate, true);
     this.screenshotbutton.removeEventListener("command", this.bound_screenshot, true);
     this.closebutton.removeEventListener("command", this.bound_close, true);
     this.addbutton.removeEventListener("command", this.bound_addPreset, true);
     this.removebutton.removeEventListener("command", this.bound_removePreset, true);
-    if (!this.e10s) {
-      this.touchbutton.removeEventListener("command", this.bound_touch, true);
-    }
+    this.touchbutton.removeEventListener("command", this.bound_touch, true);
 
     // Removed elements.
     this.container.removeChild(this.toolbar);
     if (this.bottomToolbar) {
       this.bottomToolbar.remove();
       delete this.bottomToolbar;
     }
     this.stack.removeChild(this.resizer);
@@ -290,18 +286,18 @@ ResponsiveUI.prototype = {
 
     this.stack.classList.remove("fxos-mode");
 
     // Unset the responsive mode.
     this.container.removeAttribute("responsivemode");
     this.stack.removeAttribute("responsivemode");
 
     ActiveTabs.delete(this.tab);
-    if (!this.e10s && this.touchEventHandler) {
-      this.touchEventHandler.stop();
+    if (this.touchEventSimulator) {
+      this.touchEventSimulator.stop();
     }
     this._telemetry.toolClosed("responsive");
     let childOff = () => {
       this.mm.removeMessageListener("ResponsiveMode:Stop:Done", childOff);
       ResponsiveUIManager.emit("off", { tab: this.tab });
     }
     this.mm.addMessageListener("ResponsiveMode:Stop:Done", childOff);
     this.tab.linkedBrowser.messageManager.sendAsyncMessage("ResponsiveMode:Stop");
@@ -436,24 +432,22 @@ ResponsiveUI.prototype = {
     this.closebutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-close";
     this.closebutton.setAttribute("tooltiptext", this.strings.GetStringFromName("responsiveUI.close"));
     this.closebutton.addEventListener("command", this.bound_close, true);
 
     this.toolbar.appendChild(this.closebutton);
     this.toolbar.appendChild(this.menulist);
     this.toolbar.appendChild(this.rotatebutton);
 
-    if (!this.e10s) {
-      this.touchbutton = this.chromeDoc.createElement("toolbarbutton");
-      this.touchbutton.setAttribute("tabindex", "0");
-      this.touchbutton.setAttribute("tooltiptext", this.strings.GetStringFromName("responsiveUI.touch"));
-      this.touchbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-touch";
-      this.touchbutton.addEventListener("command", this.bound_touch, true);
-      this.toolbar.appendChild(this.touchbutton);
-    }
+    this.touchbutton = this.chromeDoc.createElement("toolbarbutton");
+    this.touchbutton.setAttribute("tabindex", "0");
+    this.touchbutton.setAttribute("tooltiptext", this.strings.GetStringFromName("responsiveUI.touch"));
+    this.touchbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-touch";
+    this.touchbutton.addEventListener("command", this.bound_touch, true);
+    this.toolbar.appendChild(this.touchbutton);
 
     this.toolbar.appendChild(this.screenshotbutton);
 
     // Resizers
     let resizerTooltip = this.strings.GetStringFromName("responsiveUI.resizerTooltip");
     this.resizer = this.chromeDoc.createElement("box");
     this.resizer.className = "devtools-responsiveui-resizehandle";
     this.resizer.setAttribute("right", "0");
@@ -788,45 +782,39 @@ ResponsiveUI.prototype = {
     mm.addMessageListener("ResponsiveMode:RequestScreenshot:Done", onScreenshot);
     mm.sendAsyncMessage("ResponsiveMode:RequestScreenshot");
   },
 
   /**
    * Enable/Disable mouse -> touch events translation.
    */
    enableTouch: function RUI_enableTouch() {
-     if (!this.touchEventHandler.enabled) {
-       let isReloadNeeded = this.touchEventHandler.start();
-       this.touchbutton.setAttribute("checked", "true");
-       return isReloadNeeded;
-     }
-     return false;
+     this.touchbutton.setAttribute("checked", "true");
+     return this.touchEventSimulator.start();
    },
 
    disableTouch: function RUI_disableTouch() {
-     if (this.touchEventHandler.enabled) {
-       this.touchEventHandler.stop();
-       this.touchbutton.removeAttribute("checked");
-     }
+     this.touchbutton.removeAttribute("checked");
+     return this.touchEventSimulator.stop();
    },
 
    hideTouchNotification: function RUI_hideTouchNotification() {
      let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
      let n = nbox.getNotificationWithValue("responsive-ui-need-reload");
      if (n) {
        n.close();
      }
    },
 
-   toggleTouch: function RUI_toggleTouch() {
+   toggleTouch: Task.async(function*() {
      this.hideTouchNotification();
-     if (this.touchEventHandler.enabled) {
+     if (this.touchEventSimulator.enabled) {
        this.disableTouch();
      } else {
-       let isReloadNeeded = this.enableTouch();
+       let isReloadNeeded = yield this.enableTouch();
        if (isReloadNeeded) {
          if (Services.prefs.getBoolPref("devtools.responsiveUI.no-reload-notification")) {
            return;
          }
 
          let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
 
          var buttons = [{
@@ -846,17 +834,17 @@ ResponsiveUI.prototype = {
          nbox.appendNotification(
            this.strings.GetStringFromName("responsiveUI.needReload"),
            "responsive-ui-need-reload",
            null,
            nbox.PRIORITY_INFO_LOW,
            buttons);
        }
      }
-   },
+   }),
 
   /**
    * Change the size of the browser.
    *
    * @param aWidth width of the browser.
    * @param aHeight height of the browser.
    */
   setSize: function RUI_setSize(aWidth, aHeight) {
--- a/browser/devtools/responsivedesign/test/browser.ini
+++ b/browser/devtools/responsivedesign/test/browser.ini
@@ -7,11 +7,10 @@ support-files =
 
 [browser_responsive_cmd.js]
 [browser_responsivecomputedview.js]
 skip-if = e10s # Bug ??????
 [browser_responsiveruleview.js]
 skip-if = e10s # Bug ??????
 [browser_responsiveui.js]
 [browser_responsiveui_touch.js]
-skip-if = e10s # Bug ?????? - [e10s] re-introduce touch feature in responsive mode
 [browser_responsiveuiaddcustompreset.js]
 [browser_responsive_devicewidth.js]
--- a/browser/devtools/responsivedesign/test/browser_responsiveui_touch.js
+++ b/browser/devtools/responsivedesign/test/browser_responsiveui_touch.js
@@ -1,66 +1,50 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-function test() {
-  let url = "http://mochi.test:8888/browser/browser/devtools/responsivedesign/test/touch.html";
-
-  let mgr = ResponsiveUI.ResponsiveUIManager;
-
-  waitForExplicitFinish();
+"use strict";
 
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function onload() {
-    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
-    waitForFocus(startTest, content);
-  }, true);
-
-  content.location = url;
+const TEST_URI = "http://mochi.test:8888/browser/browser/devtools/" +
+                 "responsivedesign/test/touch.html";
 
-  function startTest() {
-    mgr.once("on", function() {executeSoon(testWithNoTouch)});
-    mgr.once("off", function() {executeSoon(finishUp)});
-    mgr.toggle(window, gBrowser.selectedTab);
-  }
-
-  function testWithNoTouch() {
-    let div = content.document.querySelector("div");
-    let x = 2, y = 2;
-    EventUtils.synthesizeMouse(div, x, y, {type: "mousedown", isSynthesized: false}, content);
-    x += 20; y += 10;
-    EventUtils.synthesizeMouse(div, x, y, {type: "mousemove", isSynthesized: false}, content);
-    is(div.style.transform, "", "touch didn't work");
-    EventUtils.synthesizeMouse(div, x, y, {type: "mouseup", isSynthesized: false}, content);
-    testWithTouch();
-  }
+add_task(function*() {
+  yield addTab(TEST_URI);
+  let mgr = ResponsiveUI.ResponsiveUIManager;
+  let mgrOn = once(mgr, "on");
+  mgr.toggle(window, gBrowser.selectedTab);
+  yield mgrOn;
+  yield testWithNoTouch();
+  yield mgr.getResponsiveUIForTab(gBrowser.selectedTab).enableTouch();
+  yield testWithTouch();
+  yield mgr.getResponsiveUIForTab(gBrowser.selectedTab).disableTouch();
+  yield testWithNoTouch();
+  let mgrOff = once(mgr, "off");
+  mgr.toggle(window, gBrowser.selectedTab);
+  yield mgrOff;
+});
 
-  function testWithTouch() {
-    mgr.getResponsiveUIForTab(gBrowser.selectedTab).enableTouch();
-    let div = content.document.querySelector("div");
-    let x = 2, y = 2;
-    EventUtils.synthesizeMouse(div, x, y, {type: "mousedown", isSynthesized: false}, content);
-    x += 20; y += 10;
-    EventUtils.synthesizeMouse(div, x, y, {type: "mousemove", isSynthesized: false}, content);
-    is(div.style.transform, "translate(20px, 10px)", "touch worked");
-    EventUtils.synthesizeMouse(div, x, y, {type: "mouseup", isSynthesized: false}, content);
-    is(div.style.transform, "none", "end event worked");
-    mgr.toggle(window, gBrowser.selectedTab);
-  }
+function* testWithNoTouch() {
+  let div = content.document.querySelector("div");
+  let x = 2, y = 2;
+  yield BrowserTestUtils.synthesizeMouse("div", x, y,
+        { type: "mousedown", isSynthesized: false }, gBrowser.selectedBrowser);
+  x += 20; y += 10;
+  yield BrowserTestUtils.synthesizeMouse("div", x, y,
+        { type: "mousemove", isSynthesized: false }, gBrowser.selectedBrowser);
+  is(div.style.transform, "none", "touch didn't work");
+  yield BrowserTestUtils.synthesizeMouse("div", x, y,
+        { type: "mouseup", isSynthesized: false }, gBrowser.selectedBrowser);
+}
 
-  function testWithTouchAgain() {
-    mgr.getResponsiveUIForTab(gBrowser.selectedTab).disableTouch();
-    let div = content.document.querySelector("div");
-    let x = 2, y = 2;
-    EventUtils.synthesizeMouse(div, x, y, {type: "mousedown", isSynthesized: false}, content);
-    x += 20; y += 10;
-    EventUtils.synthesizeMouse(div, x, y, {type: "mousemove", isSynthesized: false}, content);
-    is(div.style.transform, "", "touch didn't work");
-    EventUtils.synthesizeMouse(div, x, y, {type: "mouseup", isSynthesized: false}, content);
-    finishUp();
-  }
-
-
-  function finishUp() {
-    gBrowser.removeCurrentTab();
-    finish();
-  }
+function* testWithTouch() {
+  let div = content.document.querySelector("div");
+  let x = 2, y = 2;
+  yield BrowserTestUtils.synthesizeMouse("div", x, y,
+        { type: "mousedown", isSynthesized: false }, gBrowser.selectedBrowser);
+  x += 20; y += 10;
+  yield BrowserTestUtils.synthesizeMouse("div", x, y,
+        { type: "mousemove", isSynthesized: false }, gBrowser.selectedBrowser);
+  is(div.style.transform, "translate(20px, 10px)", "touch worked");
+  yield BrowserTestUtils.synthesizeMouse("div", x, y,
+        { type: "mouseup", isSynthesized: false }, gBrowser.selectedBrowser);
+  is(div.style.transform, "none", "end event worked");
 }
--- a/browser/devtools/responsivedesign/test/head.js
+++ b/browser/devtools/responsivedesign/test/head.js
@@ -9,18 +9,21 @@ let {devtools} = Cu.import("resource:///
 let TargetFactory = devtools.TargetFactory;
 let DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils");
 
 // Import the GCLI test helper
 let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
 Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
 
 DevToolsUtils.testing = true;
-SimpleTest.registerCleanupFunction(() => {
+registerCleanupFunction(() => {
   DevToolsUtils.testing = false;
+  while (gBrowser.tabs.length > 1) {
+    gBrowser.removeCurrentTab();
+  }
 });
 
 /**
  * Open the toolbox, with the inspector tool visible.
  * @return a promise that resolves when the inspector is ready
  */
 let openInspector = Task.async(function*() {
   info("Opening the inspector");
--- a/browser/devtools/responsivedesign/test/touch.html
+++ b/browser/devtools/responsivedesign/test/touch.html
@@ -12,16 +12,17 @@
 </style>
 
 <div></div>
 
 <script>
   var div = document.querySelector("div");
   var initX, initY;
 
+  div.style.transform = "none";
 
   div.addEventListener("touchstart", function(evt) {
     var touch = evt.changedTouches[0];
     initX = touch.pageX;
     initY = touch.pageY;
   }, true);
 
   div.addEventListener("touchmove", function(evt) {
--- a/browser/devtools/sourceeditor/editor.js
+++ b/browser/devtools/sourceeditor/editor.js
@@ -31,16 +31,18 @@ const RE_JUMP_TO_LINE = /^(\d+):?(\d+)?/
 
 const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 const events  = require("devtools/toolkit/event-emitter");
 const { PrefObserver } = require("devtools/styleeditor/utils");
 
 Cu.import("resource://gre/modules/Services.jsm");
 const L10N = Services.strings.createBundle(L10N_BUNDLE);
 
+const { OS } = Services.appinfo;
+
 // CM_STYLES, CM_SCRIPTS and CM_IFRAME represent the HTML,
 // JavaScript and CSS that is injected into an iframe in
 // order to initialize a CodeMirror instance.
 
 const CM_STYLES   = [
   "chrome://browser/skin/devtools/common.css",
   "chrome://browser/content/devtools/codemirror/codemirror.css",
   "chrome://browser/content/devtools/codemirror/dialog.css",
@@ -294,16 +296,72 @@ Editor.prototype = {
         ev.preventDefault();
         if (!this.config.contextMenu) return;
         let popup = this.config.contextMenu;
         if (typeof popup == "string")
           popup = el.ownerDocument.getElementById(this.config.contextMenu);
         popup.openPopupAtScreen(ev.screenX, ev.screenY, true);
       }, false);
 
+      // Intercept the find and find again keystroke on CodeMirror, to avoid
+      // the browser's search
+
+      let findKey = L10N.GetStringFromName("find.commandkey");
+      let findAgainKey = L10N.GetStringFromName("findAgain.commandkey");
+      let [accel, modifier] = OS === "Darwin"
+                                      ? ["metaKey", "altKey"]
+                                      : ["ctrlKey", "shiftKey"];
+
+      cm.getWrapperElement().addEventListener("keydown", (ev) => {
+        let key = ev.key.toUpperCase();
+        let node = ev.originalTarget;
+        let isInput = node.tagName === "INPUT";
+        let isSearchInput = isInput && node.type === "search";
+
+        // replace box is a different input instance than search, and it is
+        // located in a code mirror dialog
+        let isDialogInput = isInput &&
+                       node.parentNode &&
+                       node.parentNode.classList.contains("CodeMirror-dialog");
+
+        if (!ev[accel] || !(isSearchInput || isDialogInput)) return;
+
+        if (key === findKey) {
+          ev.preventDefault();
+
+          if (isSearchInput || ev[modifier]) {
+            node.select();
+          }
+        } else if (key === findAgainKey) {
+          ev.preventDefault();
+
+          if (!isSearchInput) return;
+
+          let query = node.value;
+
+          // If there isn't a search state, or the text in the input does not
+          // match with the current search state, we need to create a new one
+          if (!cm.state.search || cm.state.search.query !== query) {
+            cm.state.search = {
+              posFrom: null,
+              posTo: null,
+              overlay: null,
+              query
+            };
+          }
+
+          if (ev.shiftKey) {
+            cm.execCommand("findPrev");
+          } else {
+            cm.execCommand("findNext");
+          }
+        }
+      });
+
+
       cm.on("focus", () => this.emit("focus"));
       cm.on("scroll", () => this.emit("scroll"));
       cm.on("change", () => {
         this.emit("change");
         if (!this._lastDirty) {
           this._lastDirty = true;
           this.emit("dirty-change");
         }
--- a/browser/devtools/sourceeditor/test/browser.ini
+++ b/browser/devtools/sourceeditor/test/browser.ini
@@ -23,16 +23,17 @@ support-files =
   head.js
   helper_codemirror_runner.js
 
 [browser_editor_autocomplete_basic.js]
 [browser_editor_autocomplete_events.js]
 [browser_editor_autocomplete_js.js]
 [browser_editor_basic.js]
 [browser_editor_cursor.js]
+[browser_editor_find_again.js]
 [browser_editor_goto_line.js]
 [browser_editor_history.js]
 [browser_editor_markers.js]
 [browser_editor_movelines.js]
 [browser_editor_prefs.js]
 [browser_editor_script_injection.js]
 [browser_editor_addons.js]
 [browser_codemirror.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/sourceeditor/test/browser_editor_find_again.js
@@ -0,0 +1,214 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const L10N_BUNDLE = "chrome://browser/locale/devtools/sourceeditor.properties";
+const L10N = Services.strings.createBundle(L10N_BUNDLE);
+
+const FIND_KEY = L10N.GetStringFromName("find.commandkey");
+const FINDAGAIN_KEY = L10N.GetStringFromName("findAgain.commandkey");
+
+const { OS } = Services.appinfo;
+
+// On linux, getting immediately the selection's range here fails, returning
+// values like it's not selected – even if the selection is visible.
+// For the record, setting the selection's range immediately doesn't have
+// any effect.
+// It's like the <input> is not ready yet.
+// Therefore, we trigger the UI focus event to the <input>, waiting for the
+// response.
+// Using a timeout could also work, but that is more precise, ensuring also
+// the execution of the listeners added to the <input>'s focus.
+const dispatchAndWaitForFocus = (target) => new Promise((resolve) => {
+  target.addEventListener("focus", function listener() {
+    target.removeEventListener("focus", listener);
+    resolve(target);
+  });
+
+  target.dispatchEvent(new UIEvent("focus"));
+});
+
+function openSearchBox(ed) {
+  let edDoc = ed.container.contentDocument;
+  let edWin = edDoc.defaultView;
+
+  let input = edDoc.querySelector("input[type=search]");
+  ok(!input, "search box closed");
+
+  // The editor needs the focus to properly receive the `synthesizeKey`
+  ed.focus();
+
+  EventUtils.synthesizeKey(FINDAGAIN_KEY, { accelKey: true }, edWin);
+
+  input = edDoc.querySelector("input[type=search]");
+  ok(input, "find again command key opens the search box");
+}
+
+function testFindAgain (ed, inputLine, expectCursor, shiftKey=false) {
+  let edDoc = ed.container.contentDocument;
+  let edWin = edDoc.defaultView;
+
+  let input = edDoc.querySelector("input[type=search]");
+  input.value = inputLine;
+
+  // Ensure the input has the focus before send the key – necessary on Linux,
+  // it seems that during the tests can be lost
+  input.focus();
+
+  EventUtils.synthesizeKey(FINDAGAIN_KEY, { accelKey: true, shiftKey }, edWin);
+
+  ch(ed.getCursor(), expectCursor,
+    "find: " + inputLine + " expects cursor: " + expectCursor.toSource());
+}
+
+const testSearchBoxTextIsSelected = Task.async(function*(ed) {
+  let edDoc = ed.container.contentDocument;
+  let edWin = edDoc.defaultView;
+
+  let input = edDoc.querySelector("input[type=search]");
+  ok(input, "search box is opened");
+
+  // Ensure the input has the focus before send the key – necessary on Linux,
+  // it seems that during the tests can be lost
+  input.focus();
+
+  // Close search box
+  EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
+
+  input = edDoc.querySelector("input[type=search]");
+  ok(!input, "search box is closed");
+
+  // Re-open the search box
+  EventUtils.synthesizeKey(FIND_KEY, { accelKey: true }, edWin);
+
+  input = edDoc.querySelector("input[type=search]");
+  ok(input, "find command key opens the search box");
+
+  yield dispatchAndWaitForFocus(input);
+
+  let { selectionStart, selectionEnd, value } = input;
+
+  ok(selectionStart === 0 && selectionEnd === value.length,
+    "search box's text is selected when re-opened");
+
+  // Removing selection
+  input.setSelectionRange(0, 0);
+
+  EventUtils.synthesizeKey(FIND_KEY, { accelKey: true }, edWin);
+
+  ({ selectionStart, selectionEnd } = input);
+
+  ok(selectionStart === 0 && selectionEnd === value.length,
+    "search box's text is selected when find key is pressed");
+
+  // Close search box
+  EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
+});
+
+const testReplaceBoxTextIsSelected = Task.async(function*(ed) {
+  let edDoc = ed.container.contentDocument;
+  let edWin = edDoc.defaultView;
+
+  let input = edDoc.querySelector(".CodeMirror-dialog > input");
+  ok(!input, "dialog box with replace is closed");
+
+  // The editor needs the focus to properly receive the `synthesizeKey`
+  ed.focus();
+
+  // Send the replace's key with the appropriate modifiers based on OS
+  let [altKey, shiftKey] = OS === "Darwin" ? [true, false] : [false, true];
+
+  EventUtils.synthesizeKey(FIND_KEY,
+    { accelKey: true, altKey, shiftKey }, edWin);
+
+  input = edDoc.querySelector(".CodeMirror-dialog > input");
+  ok(input, "dialog box with replace is opened");
+
+  input.value = "line 5";
+
+  // Ensure the input has the focus before send the key – necessary on Linux,
+  // it seems that during the tests can be lost
+  input.focus();
+
+  yield dispatchAndWaitForFocus(input);
+
+  let { selectionStart, selectionEnd, value } = input;
+
+  ok(!(selectionStart === 0 && selectionEnd === value.length),
+    "Text in dialog box is not selected");
+
+  EventUtils.synthesizeKey(FIND_KEY,
+    { accelKey: true, altKey, shiftKey }, edWin);
+
+  ({ selectionStart, selectionEnd } = input);
+
+  ok(selectionStart === 0 && selectionEnd === value.length,
+    "dialog box's text is selected when replace key is pressed");
+
+  // Close dialog box
+  EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
+});
+
+add_task(function*() {
+  let { ed, win } = yield setup();
+
+  ed.setText([
+    "// line 1",
+    "//  line 2",
+    "//   line 3",
+    "//    line 4",
+    "//     line 5"
+  ].join("\n"));
+
+  yield promiseWaitForFocus();
+
+  openSearchBox(ed);
+
+  let testVectors = [
+    // Starting here expect data needs to get updated for length changes to
+    // "textLines" above.
+    ["line",
+     {line: 0, ch: 7}],
+    ["line",
+     {line: 1, ch: 8}],
+    ["line",
+     {line: 2, ch: 9}],
+    ["line",
+     {line: 3, ch: 10}],
+    ["line",
+     {line: 4, ch: 11}],
+    ["ne 3",
+     {line: 2, ch: 11}],
+    ["line 1",
+      {line: 0, ch: 9}],
+    // Testing find prev
+    ["line",
+      {line: 4, ch: 11},
+      true],
+    ["line",
+      {line: 3, ch: 10},
+      true],
+    ["line",
+      {line: 2, ch: 9},
+      true],
+    ["line",
+      {line: 1, ch: 8},
+      true],
+    ["line",
+      {line: 0, ch: 7},
+      true]
+  ];
+
+  for (let v of testVectors) {
+    yield testFindAgain(ed, ...v);
+  }
+
+  yield testSearchBoxTextIsSelected(ed);
+
+  yield testReplaceBoxTextIsSelected(ed);
+
+  teardown(ed, win);
+});
--- a/browser/devtools/sourceeditor/test/head.js
+++ b/browser/devtools/sourceeditor/test/head.js
@@ -35,16 +35,21 @@ function addTab(aURL, aCallback) {
   browser.addEventListener("load", onTabLoad, true);
 }
 
 function promiseTab(aURL) {
   return new Promise(resolve =>
     addTab(aURL, resolve));
 }
 
+function promiseWaitForFocus() {
+  return new Promise(resolve =>
+    waitForFocus(resolve));
+}
+
 function setup(cb, additionalOpts = {}) {
   cb = cb || function() {};
   let def = promise.defer();
   const opt = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
   const url = "data:application/vnd.mozilla.xul+xml;charset=UTF-8,<?xml version='1.0'?>" +
     "<?xml-stylesheet href='chrome://global/skin/global.css'?>" +
     "<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
     " title='Editor' width='600' height='500'><box flex='1'/></window>";
--- a/browser/devtools/styleinspector/computed-view.js
+++ b/browser/devtools/styleinspector/computed-view.js
@@ -1,35 +1,39 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
+/* globals overlays, StyleInspectorMenu */
+
+"use strict";
+
 const {Cc, Ci, Cu} = require("chrome");
 
 const ToolDefinitions = require("main").Tools;
 const {CssLogic} = require("devtools/styleinspector/css-logic");
 const {ELEMENT_STYLE} = require("devtools/server/actors/styles");
 const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
-const {EventEmitter} = require("devtools/toolkit/event-emitter");
 const {OutputParser} = require("devtools/output-parser");
 const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/styleeditor/utils");
 const {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
-const overlays = require("devtools/styleinspector/style-inspector-overlays");
+
+loader.lazyRequireGetter(this, "overlays", "devtools/styleinspector/style-inspector-overlays");
+loader.lazyRequireGetter(this, "StyleInspectorMenu", "devtools/styleinspector/style-inspector-menu");
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
                                   "resource://gre/modules/PluralForm.jsm");
 
 const FILTER_CHANGED_TIMEOUT = 150;
 const HTML_NS = "http://www.w3.org/1999/xhtml";
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 /**
  * Helper for long-running processes that should yield occasionally to
  * the mainloop.
  *
  * @param {Window} aWin
  *        Timeouts will be set on this window when appropriate.
  * @param {Generator} aGenerator
@@ -45,17 +49,17 @@ const XUL_NS = "http://www.mozilla.org/k
  *
  * @constructor
  */
 function UpdateProcess(aWin, aGenerator, aOptions)
 {
   this.win = aWin;
   this.iter = _Iterator(aGenerator);
   this.onItem = aOptions.onItem || function() {};
-  this.onBatch = aOptions.onBatch || function () {};
+  this.onBatch = aOptions.onBatch || function() {};
   this.onDone = aOptions.onDone || function() {};
   this.onCancel = aOptions.onCancel || function() {};
   this.threshold = aOptions.threshold || 45;
 
   this.canceled = false;
 }
 
 UpdateProcess.prototype = {
@@ -111,53 +115,48 @@ UpdateProcess.prototype = {
         this.onBatch();
         return;
       }
     }
   }
 };
 
 /**
- * CssHtmlTree is a panel that manages the display of a table sorted by style.
- * There should be one instance of CssHtmlTree per style display (of which there
+ * CssComputedView is a panel that manages the display of a table sorted by style.
+ * There should be one instance of CssComputedView per style display (of which there
  * will generally only be one).
  *
- * @params {StyleInspector} aStyleInspector The owner of this CssHtmlTree
- * @param {PageStyleFront} aPageStyle
+ * @param {Inspector} inspector toolbox panel
+ * @param {Document} document The document that will contain the computed view.
+ * @param {PageStyleFront} pageStyle
  *        Front for the page style actor that will be providing
  *        the style information.
  *
  * @constructor
  */
-function CssHtmlTree(aStyleInspector, aPageStyle)
-{
-  this.styleWindow = aStyleInspector.doc.defaultView;
-  this.styleDocument = aStyleInspector.doc;
-  this.styleInspector = aStyleInspector;
-  this.inspector = this.styleInspector.inspector;
-  this.pageStyle = aPageStyle;
+function CssComputedView(inspector, document, pageStyle) {
+  this.inspector = inspector;
+  this.styleDocument = document;
+  this.styleWindow = this.styleDocument.defaultView;
+  this.pageStyle = pageStyle;
+
   this.propertyViews = [];
 
   this._outputParser = new OutputParser();
 
   let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
     getService(Ci.nsIXULChromeRegistry);
   this.getRTLAttr = chromeReg.isLocaleRTL("global") ? "rtl" : "ltr";
 
   // Create bound methods.
   this.focusWindow = this.focusWindow.bind(this);
   this._onKeypress = this._onKeypress.bind(this);
   this._onContextMenu = this._onContextMenu.bind(this);
-  this._contextMenuUpdate = this._contextMenuUpdate.bind(this);
-  this._onSelectAll = this._onSelectAll.bind(this);
   this._onClick = this._onClick.bind(this);
   this._onCopy = this._onCopy.bind(this);
-  this._onCopyColor = this._onCopyColor.bind(this);
-  this._onCopyUrl = this._onCopyUrl.bind(this);
-  this._onCopyImageDataUrl = this._onCopyImageDataUrl.bind(this);
   this._onFilterStyles = this._onFilterStyles.bind(this);
   this._onFilterKeyPress = this._onFilterKeyPress.bind(this);
   this._onClearSearch = this._onClearSearch.bind(this);
   this._onIncludeBrowserStyles = this._onIncludeBrowserStyles.bind(this);
   this._onFilterTextboxContextMenu = this._onFilterTextboxContextMenu.bind(this);
 
   let doc = this.styleDocument;
   this.root = doc.getElementById("root");
@@ -183,59 +182,61 @@ function CssHtmlTree(aStyleInspector, aP
   // No results text.
   this.noResults = this.styleDocument.getElementById("noResults");
 
   // Refresh panel when color unit changed.
   this._handlePrefChange = this._handlePrefChange.bind(this);
   gDevTools.on("pref-changed", this._handlePrefChange);
 
   // Refresh panel when pref for showing original sources changes
-  this._updateSourceLinks = this._updateSourceLinks.bind(this);
+  this._onSourcePrefChanged = this._onSourcePrefChanged.bind(this);
   this._prefObserver = new PrefObserver("devtools.");
-  this._prefObserver.on(PREF_ORIG_SOURCES, this._updateSourceLinks);
+  this._prefObserver.on(PREF_ORIG_SOURCES, this._onSourcePrefChanged);
 
   // The element that we're inspecting, and the document that it comes from.
   this.viewedElement = null;
 
-  this._buildContextMenu();
   this.createStyleViews();
 
+  this._contextmenu = new StyleInspectorMenu(this, { isRuleView: false });
+
   // Add the tooltips and highlightersoverlay
   this.tooltips = new overlays.TooltipsOverlay(this);
   this.tooltips.addToView();
+
   this.highlighters = new overlays.HighlightersOverlay(this);
   this.highlighters.addToView();
 }
 
 /**
  * Memoized lookup of a l10n string from a string bundle.
  * @param {string} aName The key to lookup.
  * @returns A localized version of the given key.
  */
-CssHtmlTree.l10n = function CssHtmlTree_l10n(aName)
+CssComputedView.l10n = function CssComputedView_l10n(aName)
 {
   try {
-    return CssHtmlTree._strings.GetStringFromName(aName);
+    return CssComputedView._strings.GetStringFromName(aName);
   } catch (ex) {
     Services.console.logStringMessage("Error reading '" + aName + "'");
     throw new Error("l10n error with " + aName);
   }
 };
 
-XPCOMUtils.defineLazyGetter(CssHtmlTree, "_strings", function() {
+XPCOMUtils.defineLazyGetter(CssComputedView, "_strings", function() {
   return Services.strings.createBundle(
     "chrome://global/locale/devtools/styleinspector.properties");
 });
 
 XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function() {
   return Cc["@mozilla.org/widget/clipboardhelper;1"]
          .getService(Ci.nsIClipboardHelper);
 });
 
-CssHtmlTree.prototype = {
+CssComputedView.prototype = {
   // Cache the list of properties that match the selected element.
   _matchedProperties: null,
 
   // Used for cancelling timeouts in the style filter.
   _filterChangedTimeout: null,
 
   // Holds the ID of the panelRefresh timeout.
   _panelRefreshTimeout: null,
@@ -259,17 +260,17 @@ CssHtmlTree.prototype = {
     if (this._computed && (data.pref == "devtools.defaultColorUnit" ||
         data.pref == PREF_ORIG_SOURCES)) {
       this.refreshPanel();
     }
   },
 
   /**
    * Update the view with a new selected element.
-   * The CssHtmlTree panel will show the style information for the given element.
+   * The CssComputedView panel will show the style information for the given element.
    * @param {NodeFront} aElement The highlighted node to get styles for.
    * @returns a promise that will be resolved when highlighting is complete.
    */
   selectElement: function(aElement) {
     if (!aElement) {
       this.viewedElement = null;
       this.noResults.hidden = false;
 
@@ -390,17 +391,17 @@ CssHtmlTree.prototype = {
 
     let deferred = promise.defer();
     this._createViewsPromise = deferred.promise;
 
     this.refreshSourceFilter();
     this.numVisibleProperties = 0;
     let fragment = this.styleDocument.createDocumentFragment();
 
-    this._createViewsProcess = new UpdateProcess(this.styleWindow, CssHtmlTree.propertyNames, {
+    this._createViewsProcess = new UpdateProcess(this.styleWindow, CssComputedView.propertyNames, {
       onItem: (aPropertyName) => {
         // Per-item callback.
         let propView = new PropertyView(this, aPropertyName);
         fragment.appendChild(propView.buildMain());
         fragment.appendChild(propView.buildSelectorContainer());
 
         if (propView.visible) {
           this.numVisibleProperties++;
@@ -420,17 +421,17 @@ CssHtmlTree.prototype = {
 
     this._createViewsProcess.schedule();
     return deferred.promise;
   },
 
   /**
    * Refresh the panel content.
    */
-  refreshPanel: function CssHtmlTree_refreshPanel()
+  refreshPanel: function CssComputedView_refreshPanel()
   {
     if (!this.viewedElement) {
       return promise.resolve();
     }
 
     // Capture the current viewed element to return from the promise handler
     // early if it changed
     let viewedElement = this.viewedElement;
@@ -586,65 +587,65 @@ CssHtmlTree.prototype = {
   },
 
   /**
    * When includeBrowserStylesCheckbox.checked is false we only display
    * properties that have matched selectors and have been included by the
    * document or one of thedocument's stylesheets. If .checked is false we
    * display all properties including those that come from UA stylesheets.
    */
-  refreshSourceFilter: function CssHtmlTree_setSourceFilter()
+  refreshSourceFilter: function CssComputedView_setSourceFilter()
   {
     this._matchedProperties = null;
     this._sourceFilter = this.includeBrowserStyles ?
                                  CssLogic.FILTER.UA :
                                  CssLogic.FILTER.USER;
   },
 
-  _updateSourceLinks: function CssHtmlTree__updateSourceLinks()
+  _onSourcePrefChanged: function CssComputedView__onSourcePrefChanged()
   {
     for (let propView of this.propertyViews) {
       propView.updateSourceLinks();
     }
     this.inspector.emit("computed-view-sourcelinks-updated");
   },
 
   /**
    * The CSS as displayed by the UI.
    */
-  createStyleViews: function CssHtmlTree_createStyleViews()
+  createStyleViews: function CssComputedView_createStyleViews()
   {
-    if (CssHtmlTree.propertyNames) {
+    if (CssComputedView.propertyNames) {
       return;
     }
 
-    CssHtmlTree.propertyNames = [];
+    CssComputedView.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.startsWith("--")) {
         // Skip any CSS variables used inside of browser CSS files
         continue;
       } else if (prop.startsWith("-")) {
         mozProps.push(prop);
       } else {
-        CssHtmlTree.propertyNames.push(prop);
+        CssComputedView.propertyNames.push(prop);
       }
     }
 
-    CssHtmlTree.propertyNames.sort();
-    CssHtmlTree.propertyNames.push.apply(CssHtmlTree.propertyNames,
+    CssComputedView.propertyNames.sort();
+    CssComputedView.propertyNames.push.apply(CssComputedView.propertyNames,
       mozProps.sort());
 
     this._createPropertyViews().then(null, e => {
-      if (!this.styleInspector) {
+      if (!this._isDestroyed) {
         console.warn("The creation of property views was cancelled because the " +
           "computed-view was destroyed before it was done creating views");
       } else {
         console.error(e);
       }
     });
   },
 
@@ -665,341 +666,106 @@ CssHtmlTree.prototype = {
    */
   focusWindow: function(aEvent)
   {
     let win = this.styleDocument.defaultView;
     win.focus();
   },
 
   /**
-   * Create a context menu.
-   */
-  _buildContextMenu: function()
-  {
-    let doc = this.styleDocument.defaultView.parent.document;
-
-    this._contextmenu = this.styleDocument.createElementNS(XUL_NS, "menupopup");
-    this._contextmenu.addEventListener("popupshowing", this._contextMenuUpdate);
-    this._contextmenu.id = "computed-view-context-menu";
-
-    // Select All
-    this.menuitemSelectAll = createMenuItem(this._contextmenu, {
-      label: "computedView.contextmenu.selectAll",
-      accesskey: "computedView.contextmenu.selectAll.accessKey",
-      command: this._onSelectAll
-    });
-
-    // Copy
-    this.menuitemCopy = createMenuItem(this._contextmenu, {
-      label: "computedView.contextmenu.copy",
-      accesskey: "computedView.contextmenu.copy.accessKey",
-      command: this._onCopy
-    });
-
-    // Copy color
-    this.menuitemCopyColor = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copyColor",
-      accesskey: "ruleView.contextmenu.copyColor.accessKey",
-      command: this._onCopyColor
-    });
-
-    // Copy URL
-    this.menuitemCopyUrl = createMenuItem(this._contextmenu, {
-      label: "styleinspector.contextmenu.copyUrl",
-      accesskey: "styleinspector.contextmenu.copyUrl.accessKey",
-      command: this._onCopyUrl
-    });
-
-    // Copy data URI
-    this.menuitemCopyImageDataUrl = createMenuItem(this._contextmenu, {
-      label: "styleinspector.contextmenu.copyImageDataUrl",
-      accesskey: "styleinspector.contextmenu.copyImageDataUrl.accessKey",
-      command: this._onCopyImageDataUrl
-    });
-
-    // Show Original Sources
-    this.menuitemSources= createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.showOrigSources",
-      accesskey: "ruleView.contextmenu.showOrigSources.accessKey",
-      command: this._onToggleOrigSources,
-      type: "checkbox"
-    });
-
-    let popupset = doc.documentElement.querySelector("popupset");
-    if (!popupset) {
-      popupset = doc.createElementNS(XUL_NS, "popupset");
-      doc.documentElement.appendChild(popupset);
-    }
-    popupset.appendChild(this._contextmenu);
-  },
-
-  /**
-   * Update the context menu. This means enabling or disabling menuitems as
-   * appropriate.
-   */
-  _contextMenuUpdate: function()
-  {
-    let win = this.styleDocument.defaultView;
-    let disable = win.getSelection().isCollapsed;
-    this.menuitemCopy.disabled = disable;
-
-    let showOrig = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
-    this.menuitemSources.setAttribute("checked", showOrig);
-
-    this.menuitemCopyColor.hidden = !this._isColorPopup();
-    this.menuitemCopyUrl.hidden = !this._isImageUrlPopup();
-    this.menuitemCopyImageDataUrl.hidden = !this._isImageUrlPopup();
-  },
-
-  /**
-   * A helper that determines if the popup was opened with a click to a color
-   * value and saves the color to this._colorToCopy.
-   *
-   * @return {Boolean}
-   *         true if click on color opened the popup, false otherwise.
-   */
-  _isColorPopup: function () {
-    this._colorToCopy = "";
-
-
-    let container = this._getPopupNodeContainer();
-    if (!container) {
-      return false;
-    }
-
-    let isColorNode = el => el.dataset && "color" in el.dataset;
-
-    while (!isColorNode(container)) {
-      container = container.parentNode;
-      if (!container) {
-        return false;
-      }
-    }
-
-    this._colorToCopy = container.dataset["color"];
-    return true;
-  },
-
-  /**
-   * Check if the context menu popup was opened with a click on an image link
-   * If true, save the image url to this._imageUrlToCopy
-   */
-  _isImageUrlPopup: function () {
-    this._imageUrlToCopy = "";
-
-    let container = this._getPopupNodeContainer();
-    let isImageUrlNode = this._isImageUrlNode(container);
-    if (isImageUrlNode) {
-      this._imageUrlToCopy = container.href;
-    }
-
-    return isImageUrlNode;
-  },
-
-  /**
-   * Check if a node is an image url
-   * @param {DOMNode} node The node which we want information about
-   * @return {Boolean} true if the node is an image url
-   */
-  _isImageUrlNode: function (node) {
-    let nodeInfo = this.getNodeInfo(node);
-    if (!nodeInfo) {
-      return false
-    }
-    return nodeInfo.type == overlays.VIEW_NODE_IMAGE_URL_TYPE;
-  },
-
-  /**
-   * Get the DOM Node container for the current popupNode.
-   * If popupNode is a textNode, return the parent node, otherwise return popupNode itself.
-   * @return {DOMNode}
-   */
-  _getPopupNodeContainer: function () {
-    let container = null;
-    let node = this.popupNode;
-
-    if (node) {
-      let isTextNode = node.nodeType == node.TEXT_NODE;
-      container = isTextNode ? node.parentElement : node;
-    }
-
-    return container;
-  },
-
-  /**
    * Context menu handler.
    */
   _onContextMenu: function(event) {
-    try {
-      this.popupNode = event.explicitOriginalTarget;
-      this.styleDocument.defaultView.focus();
-      this._contextmenu.openPopupAtScreen(event.screenX, event.screenY, true);
-    } catch(e) {
-      console.error(e);
-    }
-  },
-
-  /**
-   * Select all text.
-   */
-  _onSelectAll: function()
-  {
-    try {
-      let win = this.styleDocument.defaultView;
-      let selection = win.getSelection();
-
-      selection.selectAllChildren(this.styleDocument.documentElement);
-    } catch(e) {
-      console.error(e);
-    }
+    this._contextmenu.show(event);
   },
 
   _onClick: function(event) {
     let target = event.target;
 
     if (target.nodeName === "a") {
       event.stopPropagation();
       event.preventDefault();
       let browserWin = this.inspector.target.tab.ownerDocument.defaultView;
       browserWin.openUILinkIn(target.href, "tab");
     }
   },
 
-  _onCopyColor: function() {
-    clipboardHelper.copyString(this._colorToCopy);
-  },
-
   /**
-   * Retrieve the url for the selected image and copy it to the clipboard
+   * Callback for copy event. Copy selected text.
+   * @param {Event} event copy event object.
    */
-  _onCopyUrl: function() {
-    clipboardHelper.copyString(this._imageUrlToCopy);
+  _onCopy: function(event) {
+    this.copySelection();
+    if (event) {
+      event.preventDefault();
+    }
   },
 
   /**
-   * Retrieve the image data for the selected image url and copy it to the clipboard
+   * Copy the current selection to the clipboard
    */
-  _onCopyImageDataUrl: Task.async(function*() {
-    let message;
-    try {
-      let inspectorFront = this.inspector.inspector;
-      let data = yield inspectorFront.getImageDataFromURL(this._imageUrlToCopy);
-      message = yield data.data.string();
-    } catch (e) {
-      message = CssHtmlTree.l10n("styleinspector.copyImageDataUrlError");
-    }
-
-    clipboardHelper.copyString(message);
-  }),
-
-  /**
-   * Copy selected text.
-   *
-   * @param event The event object
-   */
-  _onCopy: function(event)
-  {
+  copySelection: function() {
     try {
       let win = this.styleDocument.defaultView;
       let text = win.getSelection().toString().trim();
 
       // Tidy up block headings by moving CSS property names and their values onto
       // the same line and inserting a colon between them.
       let textArray = text.split(/[\r\n]+/);
       let result = "";
 
       // Parse text array to output string.
       if (textArray.length > 1) {
         for (let prop of textArray) {
-          if (CssHtmlTree.propertyNames.indexOf(prop) !== -1) {
+          if (CssComputedView.propertyNames.indexOf(prop) !== -1) {
             // Property name
             result += prop;
           } else {
             // Property value
-            result += ": " + prop;
-            if (result.length > 0) {
-              result += ";\n";
-            }
+            result += ": " + prop + ";\n";
           }
         }
       } else {
         // Short text fragment.
         result = textArray[0];
       }
 
       clipboardHelper.copyString(result);
-
-      if (event) {
-        event.preventDefault();
-      }
     } catch(e) {
       console.error(e);
     }
   },
 
   /**
-   *  Toggle the original sources pref.
+   * Destructor for CssComputedView.
    */
-  _onToggleOrigSources: function()
-  {
-    let isEnabled = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
-    Services.prefs.setBoolPref(PREF_ORIG_SOURCES, !isEnabled);
-  },
-
-  /**
-   * Destructor for CssHtmlTree.
-   */
-  destroy: function CssHtmlTree_destroy()
+  destroy: function CssComputedView_destroy()
   {
     this.viewedElement = null;
     this._outputParser = null;
 
     gDevTools.off("pref-changed", this._handlePrefChange);
 
-    this._prefObserver.off(PREF_ORIG_SOURCES, this._updateSourceLinks);
+    this._prefObserver.off(PREF_ORIG_SOURCES, this._onSourcePrefChanged);
     this._prefObserver.destroy();
 
     // Cancel tree construction
     if (this._createViewsProcess) {
       this._createViewsProcess.cancel();
     }
     if (this._refreshProcess) {
       this._refreshProcess.cancel();
     }
 
     // Remove context menu
     if (this._contextmenu) {
-      // Destroy the Select All menuitem.
-      this.menuitemCopy.removeEventListener("command", this._onCopy);
-      this.menuitemCopy = null;
-
-      // Destroy the Copy menuitem.
-      this.menuitemSelectAll.removeEventListener("command", this._onSelectAll);
-      this.menuitemSelectAll = null;
-
-      // Destroy Copy Color menuitem.
-      this.menuitemCopyColor.removeEventListener("command", this._onCopyColor);
-      this.menuitemCopyColor = null;
-
-      // Destroy Copy URL menuitem
-      this.menuitemCopyUrl.removeEventListener("command", this._onCopyUrl);
-      this.menuitemCopyUrl = null;
-
-      // Destroy Copy Data URI menuitem.
-      this.menuitemCopyImageDataUrl.removeEventListener("command", this._onCopyImageDataUrl);
-      this.menuitemCopyImageDataUrl = null;
-
-      // Destroy the context menu.
-      this._contextmenu.removeEventListener("popupshowing", this._contextMenuUpdate);
-      this._contextmenu.parentNode.removeChild(this._contextmenu);
+      this._contextmenu.destroy();
       this._contextmenu = null;
     }
 
-    this.popupNode = null;
-
     this.tooltips.destroy();
     this.highlighters.destroy();
 
     // Remove bound listeners
     this.styleDocument.removeEventListener("mousedown", this.focusWindow);
     this.element.removeEventListener("click", this._onClick);
     this.element.removeEventListener("copy", this._onCopy);
     this.element.removeEventListener("contextmenu", this._onContextMenu);
@@ -1013,68 +779,48 @@ CssHtmlTree.prototype = {
     // Nodes used in templating
     this.root = null;
     this.element = null;
     this.panel = null;
     this.searchField = null;
     this.searchClearButton = null;
     this.includeBrowserStylesCheckbox = null;
 
-    // The document in which we display the results (csshtmltree.xul).
-    this.styleDocument = null;
-
-    for (let propView of this.propertyViews)  {
+    // Property views
+    for (let propView of this.propertyViews) {
       propView.destroy();
     }
+    this.propertyViews = null;
 
-    // The element that we're inspecting, and the document that it comes from.
-    this.propertyViews = null;
+    this.inspector = null;
+    this.styleDocument = null;
     this.styleWindow = null;
-    this.styleDocument = null;
-    this.styleInspector = null;
+
+    this._isDestroyed = true;
   }
 };
 
 function PropertyInfo(aTree, aName) {
   this.tree = aTree;
   this.name = aName;
 }
 PropertyInfo.prototype = {
   get value() {
     if (this.tree._computed) {
       let value = this.tree._computed[this.name].value;
       return value;
     }
   }
 };
 
-function createMenuItem(aMenu, aAttributes)
-{
-  let item = aMenu.ownerDocument.createElementNS(XUL_NS, "menuitem");
-
-  item.setAttribute("label", CssHtmlTree.l10n(aAttributes.label));
-  if (aAttributes.accesskey) {
-    item.setAttribute("accesskey", CssHtmlTree.l10n(aAttributes.accesskey));
-  }
-  item.addEventListener("command", aAttributes.command);
-
-  if (aAttributes.type) {
-    item.setAttribute("type", aAttributes.type);
-  }
-
-  aMenu.appendChild(item);
-
-  return item;
-}
-
 /**
  * A container to give easy access to property data from the template engine.
  *
  * @constructor
- * @param {CssHtmlTree} aTree the CssHtmlTree instance we are working with.
+ * @param {CssComputedView} aTree the CssComputedView instance we are working with.
  * @param {string} aName the CSS property name for which this PropertyView
  * instance will render the rules.
  */
 function PropertyView(aTree, aName)
 {
   this.tree = aTree;
   this.name = aName;
   this.getRTLAttr = aTree.getRTLAttr;
@@ -1388,17 +1134,16 @@ PropertyView.prototype = {
   {
     if (!this._matchedSelectorViews) {
       this._matchedSelectorViews = [];
       this._matchedSelectorResponse.forEach(
         function matchedSelectorViews_convert(aSelectorInfo) {
           this._matchedSelectorViews.push(new SelectorView(this.tree, aSelectorInfo));
         }, this);
     }
-
     return this._matchedSelectorViews;
   },
 
   /**
    * Update all the selector source links to reflect whether we're linking to
    * original sources (e.g. Sass files).
    */
   updateSourceLinks: function PropertyView_updateSourceLinks()
@@ -1457,17 +1202,17 @@ PropertyView.prototype = {
 
     this.valueNode.removeEventListener("click", this.onFocus, false);
     this.valueNode = null;
   }
 };
 
 /**
  * A container to give us easy access to display data from a CssRule
- * @param CssHtmlTree aTree, the owning CssHtmlTree
+ * @param CssComputedView aTree, the owning CssComputedView
  * @param aSelectorInfo
  */
 function SelectorView(aTree, aSelectorInfo)
 {
   this.tree = aTree;
   this.selectorInfo = aSelectorInfo;
   this._cacheStatusNames();
 
@@ -1504,17 +1249,17 @@ SelectorView.prototype = {
   {
     if (SelectorView.STATUS_NAMES.length) {
       return;
     }
 
     for (let status in CssLogic.STATUS) {
       let i = CssLogic.STATUS[status];
       if (i > CssLogic.STATUS.UNMATCHED) {
-        let value = CssHtmlTree.l10n("rule.status." + status);
+        let value = CssComputedView.l10n("rule.status." + status);
         // Replace normal spaces with non-breaking spaces
         SelectorView.STATUS_NAMES[i] = value.replace(/ /g, '\u00A0');
       }
     }
   },
 
   /**
    * A localized version of cssRule.status
@@ -1595,17 +1340,16 @@ SelectorView.prototype = {
   updateSource: function()
   {
     let rule = this.selectorInfo.rule;
     this.sheet = rule.parentStyleSheet;
 
     if (!rule || !this.sheet) {
       let oldSource = this.source;
       this.source = CssLogic.l10n("rule.sourceElement");
-      this.href = "#";
       return promise.resolve(oldSource);
     }
 
     let showOrig = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
 
     if (showOrig && rule.type != ELEMENT_STYLE) {
       let deferred = promise.defer();
 
@@ -1709,10 +1453,10 @@ function createChild(aParent, aTag, aAtt
         elt.setAttribute(attr, aAttributes[attr]);
       }
     }
   }
   aParent.appendChild(elt);
   return elt;
 }
 
-exports.CssHtmlTree = CssHtmlTree;
+exports.CssComputedView = CssComputedView;
 exports.PropertyView = PropertyView;
--- a/browser/devtools/styleinspector/moz.build
+++ b/browser/devtools/styleinspector/moz.build
@@ -6,11 +6,12 @@
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
 
 EXTRA_JS_MODULES.devtools.styleinspector += [
     'computed-view.js',
     'css-parsing-utils.js',
     'rule-view.js',
+    'style-inspector-menu.js',
     'style-inspector-overlays.js',
     'style-inspector.js',
 ]
--- a/browser/devtools/styleinspector/rule-view.js
+++ b/browser/devtools/styleinspector/rule-view.js
@@ -1,15 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
-/* globals clipboardHelper, _strings, domUtils, AutocompletePopup */
+/* globals overlays, Services, EventEmitter, StyleInspectorMenu,
+   clipboardHelper, _strings, domUtils, AutocompletePopup */
 
 "use strict";
 
 const {Cc, Ci, Cu} = require("chrome");
 const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 const {CssLogic} = require("devtools/styleinspector/css-logic");
 const {InplaceEditor, editableField, editableItem} =
       require("devtools/shared/inplace-editor");
@@ -20,20 +21,22 @@ const {PrefObserver, PREF_ORIG_SOURCES} 
 const {
   parseDeclarations,
   parseSingleValue,
   parsePseudoClassesAndAttributes,
   SELECTOR_ATTRIBUTE,
   SELECTOR_ELEMENT,
   SELECTOR_PSEUDO_CLASS
 } = require("devtools/styleinspector/css-parsing-utils");
-const overlays = require("devtools/styleinspector/style-inspector-overlays");
-const EventEmitter = require("devtools/toolkit/event-emitter");
-
-Cu.import("resource://gre/modules/Services.jsm");
+
+loader.lazyRequireGetter(this, "overlays", "devtools/styleinspector/style-inspector-overlays");
+loader.lazyRequireGetter(this, "EventEmitter", "devtools/toolkit/event-emitter");
+loader.lazyRequireGetter(this, "StyleInspectorMenu", "devtools/styleinspector/style-inspector-menu");
+loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
+
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles";
 const PREF_DEFAULT_COLOR_UNIT = "devtools.defaultColorUnit";
 const PREF_ENABLE_MDN_DOCS_TOOLTIP =
       "devtools.inspector.mdnDocsTooltip.enabled";
@@ -1136,76 +1139,61 @@ TextProperty.prototype = {
  *   Can mark a property disabled or enabled.
  */
 
 /**
  * CssRuleView is a view of the style rules and declarations that
  * apply to a given element.  After construction, the 'element'
  * property will be available with the user interface.
  *
- * @param {Inspector} aInspector
- * @param {Document} aDoc
- *        The document that will contain the rule view.
+ * @param {Inspector} inspector toolbox panel
+ * @param {Document} document The document that will contain the rule view.
  * @param {object} aStore
  *        The CSS rule view can use this object to store metadata
  *        that might outlast the rule view, particularly the current
  *        set of disabled properties.
  * @param {PageStyleFront} aPageStyle
  *        The PageStyleFront for communicating with the remote server.
  * @constructor
  */
-function CssRuleView(aInspector, aDoc, aStore, aPageStyle) {
-  this.inspector = aInspector;
-  this.doc = aDoc;
+function CssRuleView(inspector, document, aStore, aPageStyle) {
+  this.inspector = inspector;
+  this.styleDocument = document;
+  this.styleWindow = this.styleDocument.defaultView;
   this.store = aStore || {};
   this.pageStyle = aPageStyle;
 
   this._editorsExpandedForFilter = [];
   this._outputParser = new OutputParser();
 
-  this._buildContextMenu = this._buildContextMenu.bind(this);
-  this._onContextMenu = this._onContextMenu.bind(this);
-  this._contextMenuUpdate = this._contextMenuUpdate.bind(this);
   this._onKeypress = this._onKeypress.bind(this);
   this._onAddRule = this._onAddRule.bind(this);
-  this._onSelectAll = this._onSelectAll.bind(this);
+  this._onContextMenu = this._onContextMenu.bind(this);
   this._onCopy = this._onCopy.bind(this);
-  this._onCopyColor = this._onCopyColor.bind(this);
-  this._onCopyUrl = this._onCopyUrl.bind(this);
-  this._onCopyImageDataUrl = this._onCopyImageDataUrl.bind(this);
-  this._onCopyLocation = this._onCopyLocation.bind(this);
-  this._onCopyPropertyDeclaration = this._onCopyPropertyDeclaration.bind(this);
-  this._onCopyPropertyName = this._onCopyPropertyName.bind(this);
-  this._onCopyPropertyValue = this._onCopyPropertyValue.bind(this);
-  this._onCopyRule = this._onCopyRule.bind(this);
-  this._onCopySelector = this._onCopySelector.bind(this);
-  this._onToggleOrigSources = this._onToggleOrigSources.bind(this);
-  this._onShowMdnDocs = this._onShowMdnDocs.bind(this);
   this._onFilterStyles = this._onFilterStyles.bind(this);
   this._onFilterKeyPress = this._onFilterKeyPress.bind(this);
   this._onClearSearch = this._onClearSearch.bind(this);
-  this._onFilterTextboxContextMenu =
-    this._onFilterTextboxContextMenu.bind(this);
+  this._onFilterTextboxContextMenu = this._onFilterTextboxContextMenu.bind(this);
   this._onTogglePseudoClassPanel = this._onTogglePseudoClassPanel.bind(this);
   this._onTogglePseudoClass = this._onTogglePseudoClass.bind(this);
 
-  this.element = this.doc.getElementById("ruleview-container");
-  this.addRuleButton = this.doc.getElementById("ruleview-add-rule-button");
-  this.searchField = this.doc.getElementById("ruleview-searchbox");
-  this.searchClearButton =
-    this.doc.getElementById("ruleview-searchinput-clear");
-  this.pseudoClassPanel = this.doc.getElementById("pseudo-class-panel");
-  this.pseudoClassToggle = this.doc.getElementById("pseudo-class-panel-toggle");
-  this.hoverCheckbox = this.doc.getElementById("pseudo-hover-toggle");
-  this.activeCheckbox = this.doc.getElementById("pseudo-active-toggle");
-  this.focusCheckbox = this.doc.getElementById("pseudo-focus-toggle");
+  let doc = this.styleDocument;
+  this.element = doc.getElementById("ruleview-container");
+  this.addRuleButton = doc.getElementById("ruleview-add-rule-button");
+  this.searchField = doc.getElementById("ruleview-searchbox");
+  this.searchClearButton = doc.getElementById("ruleview-searchinput-clear");
+  this.pseudoClassPanel = doc.getElementById("pseudo-class-panel");
+  this.pseudoClassToggle = doc.getElementById("pseudo-class-panel-toggle");
+  this.hoverCheckbox = doc.getElementById("pseudo-hover-toggle");
+  this.activeCheckbox = doc.getElementById("pseudo-active-toggle");
+  this.focusCheckbox = doc.getElementById("pseudo-focus-toggle");
 
   this.searchClearButton.hidden = true;
 
-  this.doc.addEventListener("keypress", this._onKeypress);
+  this.styleDocument.addEventListener("keypress", this._onKeypress);
   this.element.addEventListener("copy", this._onCopy);
   this.element.addEventListener("contextmenu", this._onContextMenu);
   this.addRuleButton.addEventListener("click", this._onAddRule);
   this.searchField.addEventListener("input", this._onFilterStyles);
   this.searchField.addEventListener("keypress", this._onFilterKeyPress);
   this.searchField.addEventListener("contextmenu",
                                     this._onFilterTextboxContextMenu);
   this.searchClearButton.addEventListener("click", this._onClearSearch);
@@ -1227,21 +1215,22 @@ function CssRuleView(aInspector, aDoc, a
   this.showUserAgentStyles = Services.prefs.getBoolPref(PREF_UA_STYLES);
   this.enableMdnDocsTooltip =
     Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
 
   let options = {
     autoSelect: true,
     theme: "auto"
   };
-  this.popup = new AutocompletePopup(aDoc.defaultView.parent.document, options);
-
-  this._buildContextMenu();
+  this.popup = new AutocompletePopup(this.styleWindow.parent.document, options);
+
   this._showEmpty();
 
+  this._contextmenu = new StyleInspectorMenu(this, { isRuleView: true });
+
   // Add the tooltips and highlighters to the view
   this.tooltips = new overlays.TooltipsOverlay(this);
   this.tooltips.addToView();
   this.highlighters = new overlays.HighlightersOverlay(this);
   this.highlighters.addToView();
 
   EventEmitter.decorate(this);
 }
@@ -1251,118 +1240,16 @@ exports.CssRuleView = CssRuleView;
 CssRuleView.prototype = {
   // The element that we're inspecting.
   _viewedElement: null,
 
   // Used for cancelling timeouts in the style filter.
   _filterChangedTimeout: null,
 
   /**
-   * Build the context menu.
-   */
-  _buildContextMenu: function() {
-    let doc = this.doc.defaultView.parent.document;
-
-    this._contextmenu = doc.createElementNS(XUL_NS, "menupopup");
-    this._contextmenu.addEventListener("popupshowing", this._contextMenuUpdate);
-    this._contextmenu.id = "rule-view-context-menu";
-
-    this.menuitemCopy = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copy",
-      accesskey: "ruleView.contextmenu.copy.accessKey",
-      command: this._onCopy
-    });
-
-    this.menuitemCopyLocation = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copyLocation",
-      command: this._onCopyLocation
-    });
-
-    this.menuitemCopyRule = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copyRule",
-      command: this._onCopyRule
-    });
-
-    this.menuitemCopyColor = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copyColor",
-      accesskey: "ruleView.contextmenu.copyColor.accessKey",
-      command: this._onCopyColor
-    });
-
-    this.menuitemCopyUrl = createMenuItem(this._contextmenu, {
-      label: "styleinspector.contextmenu.copyUrl",
-      accesskey: "styleinspector.contextmenu.copyUrl.accessKey",
-      command: this._onCopyUrl
-    });
-
-    this.menuitemCopyImageDataUrl = createMenuItem(this._contextmenu, {
-      label: "styleinspector.contextmenu.copyImageDataUrl",
-      accesskey: "styleinspector.contextmenu.copyImageDataUrl.accessKey",
-      command: this._onCopyImageDataUrl
-    });
-
-    this.menuitemCopyPropertyDeclaration = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copyPropertyDeclaration",
-      command: this._onCopyPropertyDeclaration
-    });
-
-    this.menuitemCopyPropertyName = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copyPropertyName",
-      command: this._onCopyPropertyName
-    });
-
-    this.menuitemCopyPropertyValue = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copyPropertyValue",
-      command: this._onCopyPropertyValue
-    });
-
-    this.menuitemCopySelector = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.copySelector",
-      command: this._onCopySelector
-    });
-
-    createMenuSeparator(this._contextmenu);
-
-    this.menuitemSelectAll = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.selectAll",
-      accesskey: "ruleView.contextmenu.selectAll.accessKey",
-      command: this._onSelectAll
-    });
-
-    createMenuSeparator(this._contextmenu);
-
-    this.menuitemAddRule = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.addNewRule",
-      accesskey: "ruleView.contextmenu.addNewRule.accessKey",
-      command: this._onAddRule
-    });
-
-    this.menuitemSources = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.showOrigSources",
-      accesskey: "ruleView.contextmenu.showOrigSources.accessKey",
-      command: this._onToggleOrigSources,
-      type: "checkbox"
-    });
-
-    this.menuitemShowMdnDocs = createMenuItem(this._contextmenu, {
-      label: "ruleView.contextmenu.showMdnDocs",
-      accesskey: "ruleView.contextmenu.showMdnDocs.accessKey",
-      command: this._onShowMdnDocs
-    });
-
-    let popupset = doc.documentElement.querySelector("popupset");
-    if (!popupset) {
-      popupset = doc.createElementNS(XUL_NS, "popupset");
-      doc.documentElement.appendChild(popupset);
-    }
-
-    popupset.appendChild(this._contextmenu);
-  },
-
-  /**
    * Get an instance of SelectorHighlighter (used to highlight nodes that match
    * selectors in the rule-view). A new instance is only created the first time
    * this function is called. The same instance will then be returned.
    * @return {Promise} Resolves to the instance of the highlighter.
    */
   getSelectorHighlighter: Task.async(function*() {
     let utils = this.inspector.toolbox.highlighterUtils;
     if (!utils.supportsCustomHighlighters()) {
@@ -1438,88 +1325,16 @@ CssRuleView.prototype = {
     if (!highlighter) {
       return;
     }
 
     yield highlighter.hide();
   }),
 
   /**
-   * Update the context menu. This means enabling or disabling menuitems as
-   * appropriate.
-   */
-  _contextMenuUpdate: function() {
-    this._enableCopyMenuItems(this.doc.popupNode.parentNode);
-
-    this.menuitemAddRule.disabled = this.inspector.selection.isAnonymousNode();
-
-    this.menuitemShowMdnDocs.hidden = !this.enableMdnDocsTooltip ||
-                                      !this.doc.popupNode.parentNode
-                                      .classList.contains(PROPERTY_NAME_CLASS);
-
-    let showOrig = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
-    this.menuitemSources.setAttribute("checked", showOrig);
-  },
-
-  /**
-   * Display the necessary copy context menu items depending on the clicked
-   * node and selection in the rule view.
-   */
-  _enableCopyMenuItems: function(target) {
-    let win = this.doc.defaultView;
-
-    // Copy selection.
-    let selection = win.getSelection();
-    let copy;
-
-    if (selection.toString()) {
-      // Panel text selected
-      copy = true;
-    } else if (selection.anchorNode) {
-      // input type="text"
-      let { selectionStart, selectionEnd } = this.doc.popupNode;
-
-      if (isFinite(selectionStart) && isFinite(selectionEnd) &&
-          selectionStart !== selectionEnd) {
-        copy = true;
-      }
-    } else {
-      // No text selected, disable copy.
-      copy = false;
-    }
-
-    this.menuitemCopy.hidden = !copy;
-    this.menuitemCopyColor.hidden = !this._isColorPopup();
-    this.menuitemCopyUrl.hidden = !this._isImageUrlPopup();
-    this.menuitemCopyImageDataUrl.hidden = !this._isImageUrlPopup();
-
-    this.menuitemCopyLocation.hidden = true;
-    this.menuitemCopyPropertyDeclaration.hidden = true;
-    this.menuitemCopyPropertyName.hidden = true;
-    this.menuitemCopyPropertyValue.hidden = true;
-    this.menuitemCopySelector.hidden = true;
-
-    this._clickedNodeInfo = this.getNodeInfo(target);
-
-    if (!this._clickedNodeInfo) {
-      return;
-    } else if (this._clickedNodeInfo.type == overlays.VIEW_NODE_PROPERTY_TYPE) {
-      this.menuitemCopyPropertyDeclaration.hidden = false;
-      this.menuitemCopyPropertyName.hidden = false;
-    } else if (this._clickedNodeInfo.type == overlays.VIEW_NODE_VALUE_TYPE) {
-      this.menuitemCopyPropertyDeclaration.hidden = false;
-      this.menuitemCopyPropertyValue.hidden = false;
-    } else if (this._clickedNodeInfo.type == overlays.VIEW_NODE_SELECTOR_TYPE) {
-      this.menuitemCopySelector.hidden = false;
-    } else if (this._clickedNodeInfo.type == overlays.VIEW_NODE_LOCATION_TYPE) {
-      this.menuitemCopyLocation.hidden = false;
-    }
-  },
-
-  /**
    * Get the type of a given node in the rule-view
    * @param {DOMNode} node The node which we want information about
    * @return {Object} The type information object contains the following props:
    * - type {String} One of the VIEW_NODE_XXX_TYPE const in
    *   style-inspector-overlays
    * - value {Object} Depends on the type of the node
    * returns null of the node isn't anything we care about
    */
@@ -1570,287 +1385,92 @@ CssRuleView.prototype = {
     } else if (classes.contains("ruleview-selector-unmatched") ||
                classes.contains("ruleview-selector-matched") ||
                classes.contains("ruleview-selectorcontainer") ||
                classes.contains("ruleview-selector") ||
                classes.contains("ruleview-selector-attribute") ||
                classes.contains("ruleview-selector-pseudo-class") ||
                classes.contains("ruleview-selector-pseudo-class-lock")) {
       type = overlays.VIEW_NODE_SELECTOR_TYPE;
-      value = node.offsetParent._ruleEditor.selectorText.textContent;
-    } else if (classes.contains("ruleview-rule-source")) {
+      value = this._getRuleEditorForNode(node).selectorText.textContent;
+    } else if (classes.contains("ruleview-rule-source") ||
+               classes.contains("ruleview-rule-source-label")) {
       type = overlays.VIEW_NODE_LOCATION_TYPE;
-      let ruleEditor = node.offsetParent._ruleEditor;
-      let rule = ruleEditor.rule;
+      let rule = this._getRuleEditorForNode(node).rule;
       value = (rule.sheet && rule.sheet.href) ? rule.sheet.href : rule.title;
     } else {
       return null;
     }
 
     return {type, value};
   },
 
   /**
-   * A helper that determines if the popup was opened with a click to a color
-   * value and saves the color to this._colorToCopy.
-   *
-   * @return {Boolean}
-   *         true if click on color opened the popup, false otherwise.
-   */
-  _isColorPopup: function() {
-    this._colorToCopy = "";
-
-    let container = this._getPopupNodeContainer();
-    if (!container) {
-      return false;
-    }
-
-    let isColorNode = el => el.dataset && "color" in el.dataset;
-
-    while (!isColorNode(container)) {
-      container = container.parentNode;
-      if (!container) {
-        return false;
-      }
-    }
-
-    this._colorToCopy = container.dataset.color;
-    return true;
-  },
-
-  /**
-   * Check if the context menu popup was opened with a click on an image link
-   * If true, save the image url to this._imageUrlToCopy
+   * Retrieve the RuleEditor instance that should be stored on
+   * the offset parent of the node
    */
-  _isImageUrlPopup: function() {
-    this._imageUrlToCopy = "";
-
-    let container = this._getPopupNodeContainer();
-    let isImageUrlNode = this._isImageUrlNode(container);
-    if (isImageUrlNode) {
-      this._imageUrlToCopy = container.href;
+  _getRuleEditorForNode: function(node) {
+    if (!node.offsetParent) {
+      // some nodes don't have an offsetParent, but their parentNode does
+      node = node.parentNode;
     }
-
-    return isImageUrlNode;
-  },
-
-  /**
-   * Check if a node is an image url
-   * @param {DOMNode} node The node which we want information about
-   * @return {Boolean} true if the node is an image url
-   */
-  _isImageUrlNode: function(node) {
-    let nodeInfo = this.getNodeInfo(node);
-    if (!nodeInfo) {
-      return false;
-    }
-    return nodeInfo.type == overlays.VIEW_NODE_IMAGE_URL_TYPE;
-  },
-
-  /**
-   * Get the DOM Node container for the current popupNode.
-   * If popupNode is a textNode, return the parent node, otherwise
-  *  return popupNode itself.
-   * @return {DOMNode}
-   */
-  _getPopupNodeContainer: function() {
-    let container = null;
-    let node = this.doc.popupNode;
-
-    if (node) {
-      let isTextNode = node.nodeType == node.TEXT_NODE;
-      container = isTextNode ? node.parentElement : node;
-    }
-
-    return container;
+    return node.offsetParent._ruleEditor;
   },
 
   /**
    * Context menu handler.
    */
   _onContextMenu: function(event) {
-    try {
-      // In the sidebar we do not have this.doc.popupNode so we need to save
-      // the node ourselves.
-      this.doc.popupNode = event.explicitOriginalTarget;
-      this.doc.defaultView.focus();
-      this._contextmenu.openPopupAtScreen(event.screenX, event.screenY, true);
-    } catch(e) {
-      console.error(e);
+    this._contextmenu.show(event);
+  },
+
+  /**
+   * Callback for copy event. Copy the selected text.
+   * @param {Event} event copy event object.
+   */
+  _onCopy: function(event) {
+    if (event) {
+      this.copySelection(event.target);
+      event.preventDefault();
     }
   },
 
   /**
-   * Select all text.
+   * Copy the current selection. The current target is necessary
+   * if the selection is inside an input or a textarea
+   * @param {DOMNode} target DOMNode target of the copy action
    */
-  _onSelectAll: function() {
-    let win = this.doc.defaultView;
-    let selection = win.getSelection();
-
-    selection.selectAllChildren(this.doc.documentElement);
-  },
-
-  /**
-   * Copy selected text from the rule view.
-   *
-   * @param {Event} event
-   *        The event object.
-   */
-  _onCopy: function(event) {
+  copySelection: function(target) {
     try {
-      let target = event.target;
-      let text;
-
-      if (event.target.nodeName === "menuitem") {
-        target = this.doc.popupNode;
-      }
-
-      if (target.nodeName == "input") {
+      let text = "";
+
+      if (target && target.nodeName == "input") {
         let start = Math.min(target.selectionStart, target.selectionEnd);
         let end = Math.max(target.selectionStart, target.selectionEnd);
         let count = end - start;
         text = target.value.substr(start, count);
       } else {
-        let win = this.doc.defaultView;
-        let selection = win.getSelection();
-
-        text = selection.toString();
+        text = this.styleWindow.getSelection().toString();
 
         // Remove any double newlines.
         text = text.replace(/(\r?\n)\r?\n/g, "$1");
 
         // Remove "inline"
         let inline = _strings.GetStringFromName("rule.sourceInline");
         let rx = new RegExp("^" + inline + "\\r?\\n?", "g");
         text = text.replace(rx, "");
       }
 
       clipboardHelper.copyString(text);
-      event.preventDefault();
     } catch(e) {
       console.error(e);
     }
   },
 
   /**
-   * Copy the most recently selected color value to clipboard.
-   */
-  _onCopyColor: function() {
-    clipboardHelper.copyString(this._colorToCopy);
-  },
-
-  /**
-   * Retrieve the url for the selected image and copy it to the clipboard
-   */
-  _onCopyUrl: function() {
-    clipboardHelper.copyString(this._imageUrlToCopy);
-  },
-
-  /**
-   * Retrieve the image data for the selected image url and copy it to
-   * the clipboard
-   */
-  _onCopyImageDataUrl: Task.async(function*() {
-    let message;
-    try {
-      let inspectorFront = this.inspector.inspector;
-      let data = yield inspectorFront.getImageDataFromURL(this._imageUrlToCopy);
-      message = yield data.data.string();
-    } catch (e) {
-      message =
-        _strings.GetStringFromName("styleinspector.copyImageDataUrlError");
-    }
-
-    clipboardHelper.copyString(message);
-  }),
-
-  /**
-   * Copy the rule source location of the current clicked node.
-   */
-  _onCopyLocation: function() {
-    if (!this._clickedNodeInfo) {
-      return;
-    }
-
-    clipboardHelper.copyString(this._clickedNodeInfo.value, this.doc);
-  },
-
-  /**
-   * Copy the rule property declaration of the current clicked node.
-   */
-  _onCopyPropertyDeclaration: function() {
-    if (!this._clickedNodeInfo) {
-      return;
-    }
-
-    let textProp = this._clickedNodeInfo.value.textProperty;
-    clipboardHelper.copyString(textProp.stringifyProperty(), this.doc);
-  },
-
-  /**
-   * Copy the rule property name of the current clicked node.
-   */
-  _onCopyPropertyName: function() {
-    if (!this._clickedNodeInfo) {
-      return;
-    }
-
-    clipboardHelper.copyString(this._clickedNodeInfo.value.property, this.doc);
-  },
-
-  /**
-   * Copy the rule property value of the current clicked node.
-   */
-  _onCopyPropertyValue: function() {
-    if (!this._clickedNodeInfo) {
-      return;
-    }
-
-    clipboardHelper.copyString(this._clickedNodeInfo.value.value, this.doc);
-  },
-
-  /**
-   * Copy the rule of the current clicked node.
-   */
-  _onCopyRule: function() {
-    let ruleEditor = this.doc.popupNode.parentNode.offsetParent._ruleEditor;
-    let rule = ruleEditor.rule;
-    clipboardHelper.copyString(rule.stringifyRule(), this.doc);
-  },
-
-  /**
-   * Copy the rule selector of the current clicked node.
-   */
-  _onCopySelector: function() {
-    if (!this._clickedNodeInfo) {
-      return;
-    }
-
-    clipboardHelper.copyString(this._clickedNodeInfo.value, this.doc);
-  },
-
-  /**
-   *  Toggle the original sources pref.
-   */
-  _onToggleOrigSources: function() {
-    let isEnabled = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
-    Services.prefs.setBoolPref(PREF_ORIG_SOURCES, !isEnabled);
-  },
-
-  /**
-   *  Show docs from MDN for a CSS property.
-   */
-  _onShowMdnDocs: function() {
-    let cssPropertyName = this.doc.popupNode.textContent;
-    let anchor = this.doc.popupNode.parentNode;
-    let cssDocsTooltip = this.tooltips.cssDocs;
-    cssDocsTooltip.show(anchor, cssPropertyName);
-  },
-
-  /**
    * Add a new rule to the current element.
    */
   _onAddRule: function() {
     let elementStyle = this._elementStyle;
     let element = elementStyle.element;
     let rules = elementStyle.rules;
     let client = this.inspector.toolbox._target.client;
     let pseudoClasses = element.pseudoClassLocks;
@@ -1858,16 +1478,17 @@ CssRuleView.prototype = {
     if (!client.traits.addNewRule) {
       return;
     }
 
     this.pageStyle.addNewRule(element, pseudoClasses).then(options => {
       let newRule = new Rule(elementStyle, options);
       rules.push(newRule);
       let editor = new RuleEditor(this, newRule);
+      newRule.editor = editor;
 
       // Insert the new rule editor after the inline element rule
       if (rules.length <= 1) {
         this.element.appendChild(editor.element);
       } else {
         for (let rule of rules) {
           if (rule.domRule.type === ELEMENT_STYLE) {
             let referenceElement = rule.editor.element.nextSibling;
@@ -1905,36 +1526,29 @@ CssRuleView.prototype = {
       || this.tooltips.isEditing;
   },
 
   _handlePrefChange: function(pref) {
     if (pref === PREF_UA_STYLES) {
       this.showUserAgentStyles = Services.prefs.getBoolPref(pref);
     }
 
-    if (pref === PREF_ENABLE_MDN_DOCS_TOOLTIP) {
-      this.enableMdnDocsTooltip = Services.prefs.getBoolPref(pref);
-    }
-
     // Reselect the currently selected element
     let refreshOnPrefs = [PREF_UA_STYLES, PREF_DEFAULT_COLOR_UNIT];
     if (refreshOnPrefs.indexOf(pref) > -1) {
       let element = this._viewedElement;
       this._viewedElement = null;
       this.selectElement(element);
     }
   },
 
+  /**
+   * Update source links when pref for showing original sources changes
+   */
   _onSourcePrefChanged: function() {
-    if (this.menuitemSources) {
-      let isEnabled = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
-      this.menuitemSources.setAttribute("checked", isEnabled);
-    }
-
-    // update text of source links if the rule-view is populated
     if (this._elementStyle && this._elementStyle.rules) {
       for (let rule of this._elementStyle.rules) {
         if (rule.editor) {
           rule.editor.updateSourceLink();
         }
       }
       this.inspector.emit("rule-view-sourcelinks-updated");
     }
@@ -1981,17 +1595,17 @@ CssRuleView.prototype = {
     }
   },
 
   /**
    * Context menu handler for filter style search box.
    */
   _onFilterTextboxContextMenu: function(event) {
     try {
-      this.doc.defaultView.focus();
+      this.styleWindow.focus();
       let contextmenu = this.inspector.toolbox.textboxContextMenuPopup;
       contextmenu.openPopupAtScreen(event.screenX, event.screenY, true);
     } catch(e) {
       console.error(e);
     }
   },
 
   /**
@@ -2013,91 +1627,27 @@ CssRuleView.prototype = {
     this.isDestroyed = true;
     this.clear();
 
     gDummyPromise = null;
 
     this._prefObserver.off(PREF_ORIG_SOURCES, this._onSourcePrefChanged);
     this._prefObserver.off(PREF_UA_STYLES, this._handlePrefChange);
     this._prefObserver.off(PREF_DEFAULT_COLOR_UNIT, this._handlePrefChange);
-    this._prefObserver.off(PREF_ENABLE_MDN_DOCS_TOOLTIP,
-                           this._handlePrefChange);
     this._prefObserver.destroy();
 
     this._outputParser = null;
     this._editorsExpandedForFilter = null;
 
     // Remove context menu
     if (this._contextmenu) {
-      // Destroy the Add Rule menuitem.
-      this.menuitemAddRule.removeEventListener("command", this._onAddRule);
-      this.menuitemAddRule = null;
-
-      // Destroy the Select All menuitem.
-      this.menuitemSelectAll.removeEventListener("command", this._onSelectAll);
-      this.menuitemSelectAll = null;
-
-      // Destroy the Copy menuitem.
-      this.menuitemCopy.removeEventListener("command", this._onCopy);
-      this.menuitemCopy = null;
-
-      // Destroy Copy Color menuitem.
-      this.menuitemCopyColor.removeEventListener("command", this._onCopyColor);
-      this.menuitemCopyColor = null;
-
-      // Destroy Copy URL menuitem.
-      this.menuitemCopyUrl.removeEventListener("command",
-        this._onCopyUrl);
-      this.menuitemCopyUrl = null;
-
-      // Destroy Copy Data URI menuitem.
-      this.menuitemCopyImageDataUrl.removeEventListener("command",
-        this._onCopyImageDataUrl);
-      this.menuitemCopyImageDataUrl = null;
-
-      this.menuitemCopyLocation.removeEventListener("command",
-        this._onCopyLocation);
-      this.menuitemCopyLocation = null;
-
-      this.menuitemCopyPropertyDeclaration.removeEventListener("command",
-        this._onCopyPropertyDeclaration);
-      this.menuitemCopyPropertyDeclaration = null;
-
-      this.menuitemCopyPropertyName.removeEventListener("command",
-        this._onCopyPropertyName);
-      this.menuitemCopyPropertyName = null;
-
-      this.menuitemCopyPropertyValue.removeEventListener("command",
-        this._onCopyPropertyValue);
-      this.menuitemCopyPropertyValue = null;
-
-      this.menuitemCopyRule.removeEventListener("command",
-        this._onCopyRule);
-      this.menuitemCopyRule = null;
-
-      this.menuitemCopySelector.removeEventListener("command",
-        this._onCopySelector);
-      this.menuitemCopySelector = null;
-
-      this.menuitemSources.removeEventListener("command",
-        this._onToggleOrigSources);
-      this.menuitemSources = null;
-
-      this._clickedNodeInfo = null;
-
-      // Destroy the context menu.
-      this._contextmenu.removeEventListener("popupshowing",
-        this._contextMenuUpdate);
-      this._contextmenu.parentNode.removeChild(this._contextmenu);
+      this._contextmenu.destroy();
       this._contextmenu = null;
     }
 
-    // We manage the popupNode ourselves so we also need to destroy it.
-    this.doc.popupNode = null;
-
     this.tooltips.destroy();
     this.highlighters.destroy();
 
     // Remove bound listeners
     this.element.removeEventListener("copy", this._onCopy);
     this.element.removeEventListener("contextmenu", this._onContextMenu);
     this.addRuleButton.removeEventListener("click", this._onAddRule);
     this.searchField.removeEventListener("input", this._onFilterStyles);
@@ -2114,16 +1664,20 @@ CssRuleView.prototype = {
     this.searchField = null;
     this.searchClearButton = null;
     this.pseudoClassPanel = null;
     this.pseudoClassToggle = null;
     this.hoverCheckbox = null;
     this.activeCheckbox = null;
     this.focusCheckbox = null;
 
+    this.inspector = null;
+    this.styleDocument = null;
+    this.styleWindow = null;
+
     if (this.element.parentNode) {
       this.element.parentNode.removeChild(this.element);
     }
 
     if (this._elementStyle) {
       this._elementStyle.destroy();
     }
 
@@ -2248,17 +1802,17 @@ CssRuleView.prototype = {
       this.emit("ruleview-refreshed");
     }).then(null, promiseWarn);
   },
 
   /**
    * Show the user that the rule view has no node selected.
    */
   _showEmpty: function() {
-    if (this.doc.getElementById("noResults") > 0) {
+    if (this.styleDocument.getElementById("noResults") > 0) {
       return;
     }
 
     createChild(this.element, "div", {
       id: "noResults",
       textContent: CssLogic.l10n("rule.empty")
     });
   },
@@ -2328,29 +1882,29 @@ CssRuleView.prototype = {
   /**
    * Creates an expandable container in the rule view
    * @param  {String}  aLabel The label for the container header
    * @param  {Boolean} isPseudo Whether or not the container will hold
    *                            pseudo element rules
    * @return {DOMNode} The container element
    */
   createExpandableContainer: function(aLabel, isPseudo = false) {
-    let header = this.doc.createElementNS(HTML_NS, "div");
+    let header = this.styleDocument.createElementNS(HTML_NS, "div");
     header.className = this._getRuleViewHeaderClassName(true);
     header.classList.add("show-expandable-container");
     header.textContent = aLabel;
 
-    let twisty = this.doc.createElementNS(HTML_NS, "span");
+    let twisty = this.styleDocument.createElementNS(HTML_NS, "span");
     twisty.className = "ruleview-expander theme-twisty";
     twisty.setAttribute("open", "true");
 
     header.insertBefore(twisty, header.firstChild);
     this.element.appendChild(header);
 
-    let container = this.doc.createElementNS(HTML_NS, "div");
+    let container = this.styleDocument.createElementNS(HTML_NS, "div");
     container.classList.add("ruleview-expandable-container");
     this.element.appendChild(container);
 
     let toggleContainerVisibility = (isPseudo, showPseudo) => {
       let isOpen = twisty.getAttribute("open");
 
       if (isPseudo) {
         this._showPseudoElements = !!showPseudo;
@@ -2429,25 +1983,25 @@ CssRuleView.prototype = {
         } else if (rule.domRule.type !== ELEMENT_STYLE) {
           continue;
         }
       }
 
       // Only print header for this element if there are pseudo elements
       if (seenPseudoElement && !seenNormalElement && !rule.pseudoElement) {
         seenNormalElement = true;
-        let div = this.doc.createElementNS(HTML_NS, "div");
+        let div = this.styleDocument.createElementNS(HTML_NS, "div");
         div.className = this._getRuleViewHeaderClassName();
         div.textContent = this.selectedElementLabel;
         this.element.appendChild(div);
       }
 
       let inheritedSource = rule.inheritedSource;
       if (inheritedSource && inheritedSource != lastInheritedSource) {
-        let div = this.doc.createElementNS(HTML_NS, "div");
+        let div = this.styleDocument.createElementNS(HTML_NS, "div");
         div.className = this._getRuleViewHeaderClassName();
         div.textContent = inheritedSource;
         lastInheritedSource = inheritedSource;
         this.element.appendChild(div);
       }
 
       if (!seenPseudoElement && rule.pseudoElement) {
         seenPseudoElement = true;
@@ -2673,17 +2227,17 @@ CssRuleView.prototype = {
  * @param {CssRuleView} aRuleView
  *        The CssRuleView containg the document holding this rule editor.
  * @param {Rule} aRule
  *        The Rule object we're editing.
  * @constructor
  */
 function RuleEditor(aRuleView, aRule) {
   this.ruleView = aRuleView;
-  this.doc = this.ruleView.doc;
+  this.doc = this.ruleView.styleDocument;
   this.rule = aRule;
 
   this.isEditable = !aRule.isSystem;
   // Flag that blocks updates of the selector and properties when it is
   // being edited
   this.isEditing = false;
 
   this._onNewProperty = this._onNewProperty.bind(this);
@@ -2724,17 +2278,17 @@ RuleEditor.prototype = {
       if (this.source.hasAttribute("unselectable")) {
         return;
       }
       let rule = this.rule.domRule;
       this.ruleView.emit("ruleview-linked-clicked", rule);
     }.bind(this));
     let sourceLabel = this.doc.createElementNS(XUL_NS, "label");
     sourceLabel.setAttribute("crop", "center");
-    sourceLabel.classList.add("source-link-label");
+    sourceLabel.classList.add("ruleview-rule-source-label");
     this.source.appendChild(sourceLabel);
 
     this.updateSourceLink();
 
     let code = createChild(this.element, "div", {
       class: "ruleview-code"
     });
 
@@ -2804,17 +2358,17 @@ RuleEditor.prototype = {
       // Create a property editor when the close brace is clicked.
       editableItem({ element: this.closeBrace }, () => {
         this.newProperty();
       });
     }
   },
 
   updateSourceLink: function() {
-    let sourceLabel = this.element.querySelector(".source-link-label");
+    let sourceLabel = this.element.querySelector(".ruleview-rule-source-label");
     let sourceHref = (this.rule.sheet && this.rule.sheet.href) ?
       this.rule.sheet.href : this.rule.title;
     let sourceLine = this.rule.ruleLine > 0 ? ":" + this.rule.ruleLine : "";
 
     sourceLabel.setAttribute("tooltiptext", sourceHref + sourceLine);
 
     if (this.rule.isSystem) {
       let uaLabel = _strings.GetStringFromName("rule.userAgentStyles");
@@ -3899,42 +3453,16 @@ function createChild(aParent, aTag, aAtt
         elt.setAttribute(attr, aAttributes[attr]);
       }
     }
   }
   aParent.appendChild(elt);
   return elt;
 }
 
-function createMenuItem(aMenu, aAttributes) {
-  let item = aMenu.ownerDocument.createElementNS(XUL_NS, "menuitem");
-
-  item.setAttribute("label", _strings.GetStringFromName(aAttributes.label));
-
-  if (aAttributes.accesskey) {
-    item.setAttribute("accesskey",
-                      _strings.GetStringFromName(aAttributes.accesskey));
-  }
-
-  item.addEventListener("command", aAttributes.command);
-
-  if (aAttributes.type) {
-    item.setAttribute("type", aAttributes.type);
-  }
-
-  aMenu.appendChild(item);
-
-  return item;
-}
-
-function createMenuSeparator(aMenu) {
-  let separator = aMenu.ownerDocument.createElementNS(XUL_NS, "menuseparator");
-  aMenu.appendChild(separator);
-}
-
 function setTimeout() {
   let window = Services.appShell.hiddenDOMWindow;
   return window.setTimeout.apply(window, arguments);
 }
 
 function clearTimeout() {
   let window = Services.appShell.hiddenDOMWindow;
   return window.clearTimeout.apply(window, arguments);
new file mode 100644
--- /dev/null
+++ b/browser/devtools/styleinspector/style-inspector-menu.js
@@ -0,0 +1,534 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* globals overlays, Services, clipboardHelper, _strings */
+
+"use strict";
+
+const {Cc, Ci, Cu} = require("chrome");
+const {PREF_ORIG_SOURCES} = require("devtools/styleeditor/utils");
+
+loader.lazyRequireGetter(this, "overlays", "devtools/styleinspector/style-inspector-overlays");
+loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
+loader.lazyServiceGetter(this, "clipboardHelper", "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
+loader.lazyGetter(this, "_strings", () => {
+  return Services.strings
+  .createBundle("chrome://global/locale/devtools/styleinspector.properties");
+});
+
+const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+const PREF_ENABLE_MDN_DOCS_TOOLTIP = "devtools.inspector.mdnDocsTooltip.enabled";
+
+/**
+ * Style inspector context menu
+ * @param {RuleView|ComputedView} view RuleView or ComputedView instance controlling this menu
+ * @param {Object} options menu configuration
+ */
+function StyleInspectorMenu(view, options) {
+  this.view = view;
+  this.inspector = this.view.inspector;
+  this.styleDocument = this.view.styleDocument;
+  this.styleWindow = this.view.styleWindow;
+
+  this.isRuleView = options.isRuleView;
+
+  this._onAddNewRule = this._onAddNewRule.bind(this);
+  this._onCopy = this._onCopy.bind(this);
+  this._onCopyColor = this._onCopyColor.bind(this);
+  this._onCopyImageDataUrl = this._onCopyImageDataUrl.bind(this);
+  this._onCopyLocation = this._onCopyLocation.bind(this);
+  this._onCopyPropertyDeclaration = this._onCopyPropertyDeclaration.bind(this);
+  this._onCopyPropertyName = this._onCopyPropertyName.bind(this);
+  this._onCopyPropertyValue = this._onCopyPropertyValue.bind(this);
+  this._onCopyRule = this._onCopyRule.bind(this);
+  this._onCopySelector = this._onCopySelector.bind(this);
+  this._onCopyUrl = this._onCopyUrl.bind(this);
+  this._onSelectAll = this._onSelectAll.bind(this);
+  this._onShowMdnDocs = this._onShowMdnDocs.bind(this);
+  this._onToggleOrigSources = this._onToggleOrigSources.bind(this);
+  this._updateMenuItems = this._updateMenuItems.bind(this);
+
+  this._createContextMenu();
+}
+
+module.exports = StyleInspectorMenu;
+
+StyleInspectorMenu.prototype = {
+  /**
+   * Display the style inspector context menu
+   */
+  show: function(event) {
+    try {
+      // In the sidebar we do not have this.styleDocument.popupNode
+      // so we need to save the node ourselves.
+      this.styleDocument.popupNode = event.explicitOriginalTarget;
+      this.styleWindow.focus();
+      this._menupopup.openPopupAtScreen(event.screenX, event.screenY, true);
+    } catch(e) {
+      console.error(e);
+    }
+  },
+
+  _createContextMenu: function() {
+    this._menupopup = this.styleDocument.createElementNS(XUL_NS, "menupopup");
+    this._menupopup.addEventListener("popupshowing", this._updateMenuItems);
+    this._menupopup.id = "computed-view-context-menu";
+
+    let parentDocument = this.styleWindow.parent.document;
+    let popupset = parentDocument.documentElement.querySelector("popupset");
+    if (!popupset) {
+      popupset = parentDocument.createElementNS(XUL_NS, "popupset");
+      parentDocument.documentElement.appendChild(popupset);
+    }
+    popupset.appendChild(this._menupopup);
+
+    this._createContextMenuItems();
+  },
+  /**
+   * Create all context menu items
+   */
+  _createContextMenuItems: function() {
+    this.menuitemCopy = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copy",
+      accesskey: "styleinspector.contextmenu.copy.accessKey",
+      command: this._onCopy
+    });
+
+    this.menuitemCopyLocation = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyLocation",
+      command: this._onCopyLocation
+    });
+
+    this.menuitemCopyRule = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyRule",
+      command: this._onCopyRule
+    });
+
+    this.menuitemCopyColor = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyColor",
+      accesskey: "styleinspector.contextmenu.copyColor.accessKey",
+      command: this._onCopyColor
+    });
+
+    this.menuitemCopyUrl = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyUrl",
+      accesskey: "styleinspector.contextmenu.copyUrl.accessKey",
+      command: this._onCopyUrl
+    });
+
+    this.menuitemCopyImageDataUrl = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyImageDataUrl",
+      accesskey: "styleinspector.contextmenu.copyImageDataUrl.accessKey",
+      command: this._onCopyImageDataUrl
+    });
+
+    this.menuitemCopyPropertyDeclaration = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyPropertyDeclaration",
+      command: this._onCopyPropertyDeclaration
+    });
+
+    this.menuitemCopyPropertyName = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyPropertyName",
+      command: this._onCopyPropertyName
+    });
+
+    this.menuitemCopyPropertyValue = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copyPropertyValue",
+      command: this._onCopyPropertyValue
+    });
+
+    this.menuitemCopySelector = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.copySelector",
+      command: this._onCopySelector
+    });
+
+    this._createMenuSeparator();
+
+    // Select All
+    this.menuitemSelectAll = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.selectAll",
+      accesskey: "styleinspector.contextmenu.selectAll.accessKey",
+      command: this._onSelectAll
+    });
+
+    this._createMenuSeparator();
+
+    // Add new rule
+    this.menuitemAddRule = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.addNewRule",
+      accesskey: "styleinspector.contextmenu.addNewRule.accessKey",
+      command: this._onAddNewRule
+    });
+
+    // Show MDN Docs
+    this.menuitemShowMdnDocs = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.showMdnDocs",
+      accesskey: "styleinspector.contextmenu.showMdnDocs.accessKey",
+      command: this._onShowMdnDocs
+    });
+
+    // Show Original Sources
+    this.menuitemSources = this._createContextMenuItem({
+      label: "styleinspector.contextmenu.toggleOrigSources",
+      accesskey: "styleinspector.contextmenu.toggleOrigSources.accessKey",
+      command: this._onToggleOrigSources,
+      type: "checkbox"
+    });
+  },
+
+  /**
+   * Create a single context menu item based on the provided configuration
+   * Returns the created menu item element
+   */
+  _createContextMenuItem: function(attributes) {
+    let ownerDocument = this._menupopup.ownerDocument;
+    let item = ownerDocument.createElementNS(XUL_NS, "menuitem");
+
+    item.setAttribute("label", _strings.GetStringFromName(attributes.label));
+    if (attributes.accesskey) {
+      item.setAttribute("accesskey", _strings.GetStringFromName(attributes.accesskey));
+    }
+    item.addEventListener("command", attributes.command);
+
+    if (attributes.type) {
+      item.setAttribute("type", attributes.type);
+    }
+
+    this._menupopup.appendChild(item);
+    return item;
+  },
+
+  _createMenuSeparator: function() {
+    let ownerDocument = this._menupopup.ownerDocument;
+    let separator = ownerDocument.createElementNS(XUL_NS, "menuseparator");
+    this._menupopup.appendChild(separator);
+  },
+
+  /**
+   * Update the context menu. This means enabling or disabling menuitems as
+   * appropriate.
+   */
+  _updateMenuItems: function() {
+    this._updateCopyMenuItems();
+
+    let showOrig = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
+    this.menuitemSources.setAttribute("checked", showOrig);
+
+    let enableMdnDocsTooltip = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
+    this.menuitemShowMdnDocs.hidden = !(enableMdnDocsTooltip && this._isPropertyName());
+
+    this.menuitemAddRule.disabled = !(this.isRuleView && !this.inspector.selection.isAnonymousNode());
+  },
+
+  /**
+   * Display the necessary copy context menu items depending on the clicked
+   * node and selection in the rule view.
+   */
+  _updateCopyMenuItems: function() {
+    this.menuitemCopy.hidden = !this._hasTextSelected();
+    this.menuitemCopyColor.hidden = !this._isColorPopup();
+    this.menuitemCopyImageDataUrl.hidden = !this._isImageUrl();
+
+    this.menuitemCopyRule.hidden = true;
+    this.menuitemCopyLocation.hidden = true;
+    this.menuitemCopyPropertyDeclaration.hidden = true;
+    this.menuitemCopyPropertyName.hidden = true;
+    this.menuitemCopyPropertyValue.hidden = true;
+    this.menuitemCopySelector.hidden = true;
+
+    this._clickedNodeInfo = this._getClickedNodeInfo();
+    if (this.isRuleView && this._clickedNodeInfo) {
+      this.menuitemCopyRule.hidden = false;
+
+      switch (this._clickedNodeInfo.type) {
+        case overlays.VIEW_NODE_PROPERTY_TYPE :
+          this.menuitemCopyPropertyDeclaration.hidden = false;
+          this.menuitemCopyPropertyName.hidden = false;
+          break;
+        case overlays.VIEW_NODE_VALUE_TYPE :
+          this.menuitemCopyPropertyDeclaration.hidden = false;
+          this.menuitemCopyPropertyValue.hidden = false;
+          break;
+        case overlays.VIEW_NODE_SELECTOR_TYPE :
+          this.menuitemCopySelector.hidden = false;
+          break;
+        case overlays.VIEW_NODE_LOCATION_TYPE :
+          this.menuitemCopyLocation.hidden = false;
+          break;
+      }
+    }
+  },
+
+  _hasTextSelected: function() {
+    let hasTextSelected;
+    let selection = this.styleWindow.getSelection();
+
+    let node = this._getClickedNode();
+    if (node.nodeName == "input") {
+       // input type="text"
+      let { selectionStart, selectionEnd } = node;
+      hasTextSelected = isFinite(selectionStart) && isFinite(selectionEnd)
+        && selectionStart !== selectionEnd;
+    } else {
+      hasTextSelected = selection.toString() && !selection.isCollapsed;
+    }
+
+    return hasTextSelected;
+  },
+
+  /**
+   * Get the type of the currently clicked node
+   */
+  _getClickedNodeInfo: function() {
+    let node = this._getClickedNode();
+    return this.view.getNodeInfo(node);
+  },
+
+  /**
+   * A helper that determines if the popup was opened with a click to a color
+   * value and saves the color to this._colorToCopy.
+   *
+   * @return {Boolean}
+   *         true if click on color opened the popup, false otherwise.
+   */
+  _isColorPopup: function() {
+    this._colorToCopy = "";
+
+    let container = this._getClickedNode();
+    if (!container) {
+      return false;
+    }
+
+    let isColorNode = el => el.dataset && "color" in el.dataset;
+
+    while (!isColorNode(container)) {
+      container = container.parentNode;
+      if (!container) {
+        return false;
+      }
+    }
+
+    this._colorToCopy = container.dataset.color;
+    return true;
+  },
+
+  _isPropertyName: function() {
+    let nodeInfo = this._getClickedNodeInfo();
+    if (!nodeInfo) {
+      return false;
+    }
+    return nodeInfo.type == overlays.VIEW_NODE_PROPERTY_TYPE;
+  },
+
+  /**
+   * Check if the current node (clicked node) is an image URL
+   * @return {Boolean} true if the node is an image url
+   */
+  _isImageUrl: function() {
+    let nodeInfo = this._getClickedNodeInfo();
+    if (!nodeInfo) {
+      return false;
+    }
+    return nodeInfo.type == overlays.VIEW_NODE_IMAGE_URL_TYPE;
+  },
+
+  /**
+   * Get the DOM Node container for the current popupNode.
+   * If popupNode is a textNode, return the parent node, otherwise return popupNode itself.
+   * @return {DOMNode}
+   */
+  _getClickedNode: function() {
+    let container = null;
+    let node = this.styleDocument.popupNode;
+
+    if (node) {
+      let isTextNode = node.nodeType == node.TEXT_NODE;
+      container = isTextNode ? node.parentElement : node;
+    }
+
+    return container;
+  },
+
+  /**
+   * Select all text.
+   */
+  _onSelectAll: function() {
+    let selection = this.styleWindow.getSelection();
+    selection.selectAllChildren(this.styleDocument.documentElement);
+  },
+
+  /**
+   * Copy the most recently selected color value to clipboard.
+   */
+  _onCopy: function(event) {
+    this.view.copySelection(this.styleDocument.popupNode);
+  },
+
+  /**
+   * Copy the most recently selected color value to clipboard.
+   */
+  _onCopyColor: function() {
+    clipboardHelper.copyString(this._colorToCopy);
+  },
+
+  /*
+   * Retrieve the url for the selected image and copy it to the clipboard
+   */
+  _onCopyUrl: function() {
+    clipboardHelper.copyString(this._clickedNodeInfo.value.url);
+  },
+
+  /**
+   * Retrieve the image data for the selected image url and copy it to the clipboard
+   */
+  _onCopyImageDataUrl: Task.async(function*() {
+    if (!this._clickedNodeInfo) {
+      return;
+    }
+
+    let message;
+    try {
+      let inspectorFront = this.inspector.inspector;
+      let imageUrl = this._clickedNodeInfo.value.url;
+      let data = yield inspectorFront.getImageDataFromURL(imageUrl);
+      message = yield data.data.string();
+    } catch (e) {
+      message = _strings.GetStringFromName("styleinspector.copyImageDataUrlError");
+    }
+
+    clipboardHelper.copyString(message);
+  }),
+
+  /**
+   *  Show docs from MDN for a CSS property.
+   */
+  _onShowMdnDocs: function() {
+    let cssPropertyName = this.styleDocument.popupNode.textContent;
+    let anchor = this.styleDocument.popupNode.parentNode;
+    let cssDocsTooltip = this.view.tooltips.cssDocs;
+    cssDocsTooltip.show(anchor, cssPropertyName);
+  },
+
+  /**
+   * Add a new rule to the current element.
+   */
+  _onAddNewRule: function() {
+    this.view._onAddRule();
+  },
+
+  /**
+   * Copy the rule source location of the current clicked node.
+   */
+  _onCopyLocation: function() {
+    if (!this._clickedNodeInfo) {
+      return;
+    }
+
+    clipboardHelper.copyString(this._clickedNodeInfo.value);
+  },
+
+  /**
+   * Copy the rule property declaration of the current clicked node.
+   */
+  _onCopyPropertyDeclaration: function() {
+    if (!this._clickedNodeInfo) {
+      return;
+    }
+
+    let textProp = this._clickedNodeInfo.value.textProperty;
+    clipboardHelper.copyString(textProp.stringifyProperty());
+  },
+
+  /**
+   * Copy the rule property name of the current clicked node.
+   */
+  _onCopyPropertyName: function() {
+    if (!this._clickedNodeInfo) {
+      return;
+    }
+
+    clipboardHelper.copyString(this._clickedNodeInfo.value.property);
+  },
+
+  /**
+   * Copy the rule property value of the current clicked node.
+   */
+  _onCopyPropertyValue: function() {
+    if (!this._clickedNodeInfo) {
+      return;
+    }
+
+    clipboardHelper.copyString(this._clickedNodeInfo.value.value);
+  },
+
+  /**
+   * Copy the rule of the current clicked node.
+   */
+  _onCopyRule: function() {
+    let ruleEditor = this.styleDocument.popupNode.parentNode.offsetParent._ruleEditor;
+    let rule = ruleEditor.rule;
+    clipboardHelper.copyString(rule.stringifyRule());
+  },
+
+  /**
+   * Copy the rule selector of the current clicked node.
+   */
+  _onCopySelector: function() {
+    if (!this._clickedNodeInfo) {
+      return;
+    }
+
+    clipboardHelper.copyString(this._clickedNodeInfo.value);
+  },
+
+  /**
+   *  Toggle the original sources pref.
+   */
+  _onToggleOrigSources: function() {
+    let isEnabled = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
+    Services.prefs.setBoolPref(PREF_ORIG_SOURCES, !isEnabled);
+  },
+
+  destroy: function() {
+    this._removeContextMenuItems();
+
+    // Destroy the context menu.
+    this._menupopup.removeEventListener("popupshowing", this._updateMenuItems);
+    this._menupopup.parentNode.removeChild(this._menupopup);
+    this._menupopup = null;
+
+    this.popupNode = null;
+    this.styleDocument.popupNode = null;
+    this.view = null;
+    this.inspector = null;
+    this.styleDocument = null;
+    this.styleWindow = null;
+  },
+
+  _removeContextMenuItems: function() {
+    this._removeContextMenuItem("menuitemAddRule", this._onAddNewRule);
+    this._removeContextMenuItem("menuitemCopy", this._onCopy);
+    this._removeContextMenuItem("menuitemCopyColor", this._onCopyColor);
+    this._removeContextMenuItem("menuitemCopyImageDataUrl", this._onCopyImageDataUrl);
+    this._removeContextMenuItem("menuitemCopyLocation", this._onCopyLocation);
+    this._removeContextMenuItem("menuitemCopyPropertyDeclaration", this._onCopyPropertyDeclaration);
+    this._removeContextMenuItem("menuitemCopyPropertyName", this._onCopyPropertyName);
+    this._removeContextMenuItem("menuitemCopyPropertyValue", this._onCopyPropertyValue);
+    this._removeContextMenuItem("menuitemCopyRule", this._onCopyRule);
+    this._removeContextMenuItem("menuitemCopySelector", this._onCopySelector);
+    this._removeContextMenuItem("menuitemCopyUrl", this._onCopyUrl);
+    this._removeContextMenuItem("menuitemSelectAll", this._onSelectAll);
+    this._removeContextMenuItem("menuitemShowMdnDocs", this._onShowMdnDocs);
+    this._removeContextMenuItem("menuitemSources", this._onToggleOrigSources);
+  },
+
+  _removeContextMenuItem: function(itemName, callback) {
+    if (this[itemName]) {
+      this[itemName].removeEventListener("command", callback);
+      this[itemName] = null;
+    }
+  }
+};
--- a/browser/devtools/styleinspector/style-inspector-overlays.js
+++ b/browser/devtools/styleinspector/style-inspector-overlays.js
@@ -36,17 +36,17 @@ const TOOLTIP_FONTFAMILY_TYPE = "font-fa
 const VIEW_NODE_SELECTOR_TYPE = exports.VIEW_NODE_SELECTOR_TYPE = 1;
 const VIEW_NODE_PROPERTY_TYPE = exports.VIEW_NODE_PROPERTY_TYPE = 2;
 const VIEW_NODE_VALUE_TYPE = exports.VIEW_NODE_VALUE_TYPE = 3;
 const VIEW_NODE_IMAGE_URL_TYPE = exports.VIEW_NODE_IMAGE_URL_TYPE = 4;
 const VIEW_NODE_LOCATION_TYPE = exports.VIEW_NODE_LOCATION_TYPE = 5;
 
 /**
  * Manages all highlighters in the style-inspector.
- * @param {CssRuleView|CssHtmlTree} view Either the rule-view or computed-view
+ * @param {CssRuleView|CssComputedView} view Either the rule-view or computed-view
  * panel
  */
 function HighlightersOverlay(view) {
   this.view = view;
 
   let {CssRuleView} = require("devtools/styleinspector/rule-view");
   this.isRuleView = view instanceof CssRuleView;
 
@@ -226,17 +226,17 @@ HighlightersOverlay.prototype = {
     this.highlighterUtils = null;
 
     this._isDestroyed = true;
   }
 };
 
 /**
  * Manages all tooltips in the style-inspector.
- * @param {CssRuleView|CssHtmlTree} view Either the rule-view or computed-view
+ * @param {CssRuleView|CssComputedView} view Either the rule-view or computed-view
  * panel
  */
 function TooltipsOverlay(view) {
   this.view = view;
 
   let {CssRuleView} = require("devtools/styleinspector/rule-view");
   this.isRuleView = view instanceof CssRuleView;
 
@@ -263,23 +263,24 @@ TooltipsOverlay.prototype = {
       return;
     }
 
     // Image, fonts, ... preview tooltip
     this.previewTooltip = new Tooltip(this.view.inspector.panelDoc);
     this.previewTooltip.startTogglingOnHover(this.view.element,
       this._onPreviewTooltipTargetHover.bind(this));
 
+    // MDN CSS help tooltip
+    this.cssDocs = new CssDocsTooltip(this.view.inspector.panelDoc);
+
     if (this.isRuleView) {
       // Color picker tooltip
       this.colorPicker = new SwatchColorPickerTooltip(this.view.inspector.panelDoc);
       // Cubic bezier tooltip
       this.cubicBezier = new SwatchCubicBezierTooltip(this.view.inspector.panelDoc);
-      // MDN CSS help tooltip
-      this.cssDocs = new CssDocsTooltip(this.view.inspector.panelDoc);
       // Filter editor tooltip
       this.filterEditor = new SwatchFilterTooltip(this.view.inspector.panelDoc);
     }
 
     this._isStarted = true;
   },
 
   /**
--- a/browser/devtools/styleinspector/style-inspector.js
+++ b/browser/devtools/styleinspector/style-inspector.js
@@ -16,19 +16,19 @@ loader.lazyGetter(this, "ComputedView", 
 loader.lazyGetter(this, "_strings", () => Services.strings
   .createBundle("chrome://global/locale/devtools/styleinspector.properties"));
 
 // This module doesn't currently export any symbols directly, it only
 // registers inspector tools.
 
 function RuleViewTool(inspector, window, iframe) {
   this.inspector = inspector;
-  this.doc = window.document;
+  this.document = window.document;
 
-  this.view = new RuleView.CssRuleView(inspector, this.doc);
+  this.view = new RuleView.CssRuleView(this.inspector, this.document);
 
   this.onLinkClicked = this.onLinkClicked.bind(this);
   this.onSelected = this.onSelected.bind(this);
   this.refresh = this.refresh.bind(this);
   this.clearUserProperties = this.clearUserProperties.bind(this);
   this.onPropertyChanged = this.onPropertyChanged.bind(this);
   this.onViewRefreshed = this.onViewRefreshed.bind(this);
   this.onPanelSelected = this.onPanelSelected.bind(this);
@@ -148,25 +148,25 @@ RuleViewTool.prototype = {
     this.inspector.sidebar.off("ruleview-selected", this.onPanelSelected);
 
     this.view.off("ruleview-linked-clicked", this.onLinkClicked);
     this.view.off("ruleview-changed", this.onPropertyChanged);
     this.view.off("ruleview-refreshed", this.onViewRefreshed);
 
     this.view.destroy();
 
-    this.view = this.doc = this.inspector = null;
+    this.view = this.document = this.inspector = null;
   }
 };
 
 function ComputedViewTool(inspector, window, iframe) {
   this.inspector = inspector;
-  this.doc = window.document;
+  this.document = window.document;
 
-  this.view = new ComputedView.CssHtmlTree(this, inspector.pageStyle);
+  this.view = new ComputedView.CssComputedView(this.inspector, this.document, this.inspector.pageStyle);
 
   this.onSelected = this.onSelected.bind(this);
   this.refresh = this.refresh.bind(this);
   this.onPanelSelected = this.onPanelSelected.bind(this);
 
   this.inspector.selection.on("detached", this.onSelected);
   this.inspector.selection.on("new-node-front", this.onSelected);
   this.inspector.on("layout-change", this.refresh);
@@ -233,15 +233,14 @@ ComputedViewTool.prototype = {
     this.inspector.off("layout-change", this.refresh);
     this.inspector.sidebar.off("computedview-selected", this.refresh);
     this.inspector.selection.off("pseudoclass", this.refresh);
     this.inspector.selection.off("new-node-front", this.onSelected);
     this.inspector.sidebar.off("computedview-selected", this.onPanelSelected);
 
     this.view.destroy();
 
-    this.view = this.cssLogic = this.cssHtmlTree = null;
-    this.doc = this.inspector = null;
+    this.view = this.document = this.inspector = null;
   }
 };
 
 exports.RuleViewTool = RuleViewTool;
 exports.ComputedViewTool = ComputedViewTool;
--- a/browser/devtools/styleinspector/test/browser_computedview_select-and-copy-styles.js
+++ b/browser/devtools/styleinspector/test/browser_computedview_select-and-copy-styles.js
@@ -70,18 +70,18 @@ function checkCopySelection(view) {
 }
 
 function checkSelectAll(view) {
   info("Testing select-all copy");
 
   let contentDoc = view.styleDocument;
   let prop = contentDoc.querySelector(".property-view");
 
-  info("Checking that _SelectAll() then copy returns the correct clipboard value");
-  view._onSelectAll();
+  info("Checking that _onSelectAll() then copy returns the correct clipboard value");
+  view._contextmenu._onSelectAll();
   let expectedPattern = "color: #FF0;[\\r\\n]+" +
                         "font-family: helvetica,sans-serif;[\\r\\n]+" +
                         "font-size: 16px;[\\r\\n]+" +
                         "font-variant-caps: small-caps;[\\r\\n]*";
 
   return waitForClipboard(() => {
     fireCopyEvent(prop);
   }, () => {
--- a/browser/devtools/styleinspector/test/browser_ruleview_add-property-cancel_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_add-property-cancel_02.js
@@ -38,39 +38,39 @@ add_task(function*() {
   is(inplaceEditor(elementRuleEditor.newPropSpan), editor, "The new property editor got focused.");
 
   info("Entering a value in the property name editor");
   editor.input.value = "color";
 
   info("Pressing return to commit and focus the new value field");
   let onValueFocus = once(elementRuleEditor.element, "focus", true);
   let onRuleViewChanged = view.once("ruleview-changed");
-  EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
   yield onValueFocus;
   yield onRuleViewChanged;
 
   // Getting the new value editor after focus
-  editor = inplaceEditor(view.doc.activeElement);
+  editor = inplaceEditor(view.styleDocument.activeElement);
   let textProp = elementRuleEditor.rule.textProps[1];
 
   is(elementRuleEditor.rule.textProps.length,  2, "Created a new text property.");
   is(elementRuleEditor.propertyList.children.length, 2, "Created a property editor.");
   is(editor, inplaceEditor(textProp.editor.valueSpan), "Editing the value span now.");
 
   info("Entering a property value");
   editor.input.value = "red";
 
   info("Escaping out of the field");
   onRuleViewChanged = view.once("ruleview-changed");
-  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
   yield onRuleViewChanged;
 
   info("Checking that the previous field is focused");
   let focusedElement = inplaceEditor(elementRuleEditor.rule.textProps[0].editor.valueSpan).input;
   is(focusedElement, focusedElement.ownerDocument.activeElement, "Correct element has focus");
 
   onRuleViewChanged = view.once("ruleview-changed");
-  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
   yield onRuleViewChanged;
 
   is(elementRuleEditor.rule.textProps.length,  1, "Removed the new text property.");
   is(elementRuleEditor.propertyList.children.length, 1, "Removed the property editor.");
 });
--- a/browser/devtools/styleinspector/test/browser_ruleview_add-property-cancel_03.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_add-property-cancel_03.js
@@ -45,17 +45,17 @@ function* testCancelNewOnEscape(inspecto
   // Start at the beginning: start to add a rule to the element's style
   // declaration, add some text, then press escape.
 
   let elementRuleEditor = getRuleViewRuleEditor(ruleView, 0);
   let editor = yield focusEditableField(ruleView, elementRuleEditor.closeBrace);
 
   is(inplaceEditor(elementRuleEditor.newPropSpan), editor, "Next focused editor should be the new property editor.");
 
-  EventUtils.sendString("background", ruleView.doc.defaultView)
+  EventUtils.sendString("background", ruleView.styleWindow)
 
   let onBlur = once(editor.input, "blur");
   EventUtils.synthesizeKey("VK_ESCAPE", {});
   yield onBlur;
 
   ok(!elementRuleEditor.rule._applyingModifications, "Shouldn't have an outstanding modification request after a cancel.");
   is(elementRuleEditor.rule.textProps.length, 0, "Should have canceled creating a new text property.");
   ok(!elementRuleEditor.propertyList.hasChildNodes(), "Should not have any properties.");
--- a/browser/devtools/styleinspector/test/browser_ruleview_add-property-svg.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_add-property-svg.js
@@ -34,29 +34,29 @@ function* testCreateNew(ruleView) {
 
   let input = editor.input;
 
   info("Entering the property name");
   input.value = "fill";
 
   info("Pressing RETURN and waiting for the value field focus");
   let onFocus = once(elementRuleEditor.element, "focus", true);
-  EventUtils.sendKey("return", ruleView.doc.defaultView);
+  EventUtils.sendKey("return", ruleView.styleWindow);
   yield onFocus;
   yield elementRuleEditor.rule._applyingModifications;
 
-  editor = inplaceEditor(ruleView.doc.activeElement);
+  editor = inplaceEditor(ruleView.styleDocument.activeElement);
 
   is(elementRuleEditor.rule.textProps.length,  1, "Should have created a new text property.");
   is(elementRuleEditor.propertyList.children.length, 1, "Should have created a property editor.");
   let textProp = elementRuleEditor.rule.textProps[0];
   is(editor, inplaceEditor(textProp.editor.valueSpan), "Should be editing the value span now.");
 
   editor.input.value = "red";
   let onBlur = once(editor.input, "blur");
-  EventUtils.sendKey("return", ruleView.doc.defaultView);
+  EventUtils.sendKey("return", ruleView.styleWindow);
   yield onBlur;
   yield elementRuleEditor.rule._applyingModifications;
 
   is(textProp.value, "red", "Text prop should have been changed.");
 
   is((yield getComputedStyleProperty(TEST_SELECTOR, null, "fill")), "rgb(255, 0, 0)", "The fill was changed to red");
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_add-property_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_add-property_01.js
@@ -48,22 +48,22 @@ function* testCreateNew(view) {
   let input = editor.input;
 
   info("Entering background-color in the property name editor");
   input.value = "background-color";
 
   info("Pressing return to commit and focus the new value field");
   let onValueFocus = once(elementRuleEditor.element, "focus", true);
   let onModifications = elementRuleEditor.rule._applyingModifications;
-  EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
   yield onValueFocus;
   yield onModifications;
 
   // Getting the new value editor after focus
-  editor = inplaceEditor(view.doc.activeElement);
+  editor = inplaceEditor(view.styleDocument.activeElement);
   let textProp = elementRuleEditor.rule.textProps[0];
 
   is(elementRuleEditor.rule.textProps.length,  1, "Created a new text property.");
   is(elementRuleEditor.propertyList.children.length, 1, "Created a property editor.");
   is(editor, inplaceEditor(textProp.editor.valueSpan), "Editing the value span now.");
 
   info("Entering a value and bluring the field to expect a rule change");
   editor.input.value = "#XYZ";
--- a/browser/devtools/styleinspector/test/browser_ruleview_add-property_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_add-property_02.js
@@ -35,36 +35,36 @@ function* testCreateNew(inspector, ruleV
     "Next focused editor should be the new property editor.");
 
   let input = editor.input;
 
   ok(input.selectionStart === 0 && input.selectionEnd === input.value.length,
     "Editor contents are selected.");
 
   // Try clicking on the editor's input again, shouldn't cause trouble (see bug 761665).
-  EventUtils.synthesizeMouse(input, 1, 1, {}, ruleView.doc.defaultView);
+  EventUtils.synthesizeMouse(input, 1, 1, {}, ruleView.styleWindow);
   input.select();
 
   info("Entering the property name");
   input.value = "background-color";
 
   info("Pressing RETURN and waiting for the value field focus");
   let onFocus = once(elementRuleEditor.element, "focus", true);
-  EventUtils.sendKey("return", ruleView.doc.defaultView);
+  EventUtils.sendKey("return", ruleView.styleWindow);
   yield onFocus;
   yield elementRuleEditor.rule._applyingModifications;
 
-  editor = inplaceEditor(ruleView.doc.activeElement);
+  editor = inplaceEditor(ruleView.styleDocument.activeElement);
 
   is(elementRuleEditor.rule.textProps.length,  1, "Should have created a new text property.");
   is(elementRuleEditor.propertyList.children.length, 1, "Should have created a property editor.");
   let textProp = elementRuleEditor.rule.textProps[0];
   is(editor, inplaceEditor(textProp.editor.valueSpan), "Should be editing the value span now.");
 
   let onMutated = inspector.once("markupmutation");
   editor.input.value = "purple";
   let onBlur = once(editor.input, "blur");
-  EventUtils.sendKey("return", ruleView.doc.defaultView);
+  EventUtils.sendKey("return", ruleView.styleWindow);
   yield onBlur;
   yield onMutated;
 
   is(textProp.value, "purple", "Text prop should have been changed.");
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_add-rule_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_add-rule_01.js
@@ -56,28 +56,28 @@ function* runTestData(inspector, view, d
 
   info("Resetting page content");
   content.document.body.innerHTML = PAGE_CONTENT;
 }
 
 function* addNewRule(inspector, view, method) {
   if (method == "context-menu") {
     info("Waiting for context menu to be shown");
-    let onPopup = once(view._contextmenu, "popupshown");
-    let win = view.doc.defaultView;
+    let onPopup = once(view._contextmenu._menupopup, "popupshown");
+    let win = view.styleWindow;
 
     EventUtils.synthesizeMouseAtCenter(view.element,
       {button: 2, type: "contextmenu"}, win);
     yield onPopup;
 
-    ok(!view.menuitemAddRule.hidden, "Add rule is visible");
+    ok(!view._contextmenu.menuitemAddRule.hidden, "Add rule is visible");
 
     info("Adding the new rule");
-    view.menuitemAddRule.click();
-    view._contextmenu.hidePopup();
+    view._contextmenu.menuitemAddRule.click();
+    view._contextmenu._menupopup.hidePopup();
   }
   else {
     info("Adding the new rule using the button");
     view.addRuleButton.click();
   }
   info("Waiting for rule view to change");
   yield view.once("ruleview-changed");
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_completion-existing-property_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_completion-existing-property_01.js
@@ -60,17 +60,17 @@ let TEST_URL = "data:text/html;charset=u
 add_task(function*() {
   yield addTab(TEST_URL);
   let {toolbox, inspector, view} = yield openRuleView();
 
   info("Selecting the test node");
   yield selectNode("h1", inspector);
 
   info("Focusing the css property editable field");
-  let propertyName = view.doc.querySelectorAll(".ruleview-propertyname")[0];
+  let propertyName = view.styleDocument.querySelectorAll(".ruleview-propertyname")[0];
   let editor = yield focusEditableField(view, propertyName);
 
   info("Starting to test for css property completion");
   for (let i = 0; i < testData.length; i ++) {
     yield testCompletion(testData[i], editor, view);
   }
 });
 
@@ -84,17 +84,17 @@ function* testCompletion([key, completio
     info("Adding event listener for left|right|back_space|escape|home|end|page_up|page_down keys");
     onSuggest = once(editor.input, "keypress");
   } else {
     info("Waiting for after-suggest event on the editor");
     onSuggest = editor.once("after-suggest");
   }
 
   info("Synthesizing key " + key);
-  EventUtils.synthesizeKey(key, {}, view.doc.defaultView);
+  EventUtils.synthesizeKey(key, {}, view.styleWindow);
 
   yield onSuggest;
   yield wait(1); // Equivalent of executeSoon
 
   info("Checking the state");
   if (completion != null) {
     is(editor.input.value, completion, "Correct value is autocompleted");
   }
--- a/browser/devtools/styleinspector/test/browser_ruleview_completion-existing-property_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_completion-existing-property_02.js
@@ -42,55 +42,55 @@ let TEST_URL = "data:text/html;charset=u
 add_task(function*() {
   yield addTab(TEST_URL);
   let {toolbox, inspector, view} = yield openRuleView();
 
   info("Selecting the test node");
   yield selectNode("h1", inspector);
 
   info("Focusing the css property editable value");
-  let value = view.doc.querySelectorAll(".ruleview-propertyvalue")[0];
+  let value = view.styleDocument.querySelectorAll(".ruleview-propertyvalue")[0];
   let editor = yield focusEditableField(view, value);
 
   info("Starting to test for css property completion");
   for (let i = 0; i < testData.length; i ++) {
     // Re-define the editor at each iteration, because the focus may have moved
     // from property to value and back
-    editor = inplaceEditor(view.doc.activeElement);
+    editor = inplaceEditor(view.styleDocument.activeElement);
     yield testCompletion(testData[i], editor, view);
   }
 });
 
 function* testCompletion([key, modifiers, completion, index, total], editor, view) {
   info("Pressing key " + key);
   info("Expecting " + completion + ", " + index + ", " + total);
 
   let onKeyPress;
 
   if (/tab/ig.test(key)) {
     info("Waiting for the new property or value editor to get focused");
-    let brace = view.doc.querySelector(".ruleview-ruleclose");
+    let brace = view.styleDocument.querySelector(".ruleview-ruleclose");
     onKeyPress = once(brace.parentNode, "focus", true);
   } else if (/(right|return|back_space)/ig.test(key)) {
     info("Adding event listener for right|return|back_space keys");
     onKeyPress = once(editor.input, "keypress");
   } else {
     info("Waiting for after-suggest event on the editor");
     onKeyPress = editor.once("after-suggest");
   }
 
   info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
-  EventUtils.synthesizeKey(key, modifiers, view.doc.defaultView);
+  EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
 
   yield onKeyPress;
   yield wait(1); // Equivalent of executeSoon
 
   // The key might have been a TAB or shift-TAB, in which case the editor will
   // be a new one
-  editor = inplaceEditor(view.doc.activeElement);
+  editor = inplaceEditor(view.styleDocument.activeElement);
 
   info("Checking the state");
   if (completion != null) {
     is(editor.input.value, completion, "Correct value is autocompleted");
   }
   if (total == 0) {
     ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
   } else {
--- a/browser/devtools/styleinspector/test/browser_ruleview_completion-new-property_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_completion-new-property_01.js
@@ -43,17 +43,17 @@ let TEST_URL = "data:text/html;charset=u
 add_task(function*() {
   yield addTab(TEST_URL);
   let {toolbox, inspector, view} = yield openRuleView();
 
   info("Selecting the test node");
   yield selectNode("h1", inspector);
 
   info("Focusing the css property editable field");
-  let brace = view.doc.querySelector(".ruleview-ruleclose");
+  let brace = view.styleDocument.querySelector(".ruleview-ruleclose");
   let editor = yield focusEditableField(view, brace);
 
   info("Starting to test for css property completion");
   for (let i = 0; i < testData.length; i ++) {
     yield testCompletion(testData[i], editor, view);
   }
 });
 
@@ -67,17 +67,17 @@ function* testCompletion([key, completio
     info("Adding event listener for right|back_space|escape keys");
     onSuggest = once(editor.input, "keypress");
   } else {
     info("Waiting for after-suggest event on the editor");
     onSuggest = editor.once("after-suggest");
   }
 
   info("Synthesizing key " + key);
-  EventUtils.synthesizeKey(key, {}, view.doc.defaultView);
+  EventUtils.synthesizeKey(key, {}, view.styleWindow);
 
   yield onSuggest;
   yield wait(1); // Equivalent of executeSoon
 
   info("Checking the state");
   if (completion != null) {
     is(editor.input.value, completion, "Correct value is autocompleted");
   }
--- a/browser/devtools/styleinspector/test/browser_ruleview_completion-new-property_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_completion-new-property_02.js
@@ -45,58 +45,58 @@ let TEST_URL = "data:text/html;charset=u
 add_task(function*() {
   yield addTab(TEST_URL);
   let {toolbox, inspector, view} = yield openRuleView();
 
   info("Selecting the test node");
   yield selectNode("h1", inspector);
 
   info("Focusing a new css property editable property");
-  let brace = view.doc.querySelectorAll(".ruleview-ruleclose")[1];
+  let brace = view.styleDocument.querySelectorAll(".ruleview-ruleclose")[1];
   let editor = yield focusEditableField(view, brace);
 
   info("Starting to test for css property completion");
   for (let i = 0; i < testData.length; i ++) {
     // Re-define the editor at each iteration, because the focus may have moved
     // from property to value and back
-    editor = inplaceEditor(view.doc.activeElement);
+    editor = inplaceEditor(view.styleDocument.activeElement);
     yield testCompletion(testData[i], editor, view);
   }
 });
 
 function* testCompletion([key, modifiers, completion, index, total], editor, view) {
   info("Pressing key " + key);
   info("Expecting " + completion + ", " + index + ", " + total);
 
   let onKeyPress;
 
   if (/tab/ig.test(key)) {
     info("Waiting for the new property or value editor to get focused");
-    let brace = view.doc.querySelectorAll(".ruleview-ruleclose")[1];
+    let brace = view.styleDocument.querySelectorAll(".ruleview-ruleclose")[1];
     onKeyPress = once(brace.parentNode, "focus", true);
   } else if (/(right|back_space|escape|return)/ig.test(key) ||
              (modifiers.accelKey || modifiers.ctrlKey)) {
     info("Adding event listener for right|escape|back_space|return keys");
     onKeyPress = once(editor.input, "keypress");
   } else {
     info("Waiting for after-suggest event on the editor");
     onKeyPress = editor.once("after-suggest");
   }
 
   info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
-  EventUtils.synthesizeKey(key, modifiers, view.doc.defaultView);
+  EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
 
   yield onKeyPress;
   yield wait(1); // Equivalent of executeSoon
 
   info("Checking the state");
   if (completion != null) {
     // The key might have been a TAB or shift-TAB, in which case the editor will
     // be a new one
-    editor = inplaceEditor(view.doc.activeElement);
+    editor = inplaceEditor(view.styleDocument.activeElement);
     is(editor.input.value, completion, "Correct value is autocompleted");
   }
   if (total == 0) {
     ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
   } else {
     ok(editor.popup._panel.state == "open" || editor.popup._panel.state == "showing", "Popup is open");
     is(editor.popup.getItems().length, total, "Number of suggestions match");
     is(editor.popup.selectedIndex, index, "Correct item is selected");
--- a/browser/devtools/styleinspector/test/browser_ruleview_content_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_content_02.js
@@ -44,33 +44,33 @@ add_task(function*() {
   let inspector = toolbox.getPanel("inspector");
   yield inspector.once("inspector-updated");
 
   let view = inspector.sidebar.getWindowForTab("ruleview")["ruleview"].view;
 
   checkRuleViewContent(view);
 });
 
-function checkRuleViewContent({doc}) {
+function checkRuleViewContent({styleDocument}) {
   info("Making sure the rule-view contains the expected content");
 
-  let headers = [...doc.querySelectorAll(".ruleview-header")];
+  let headers = [...styleDocument.querySelectorAll(".ruleview-header")];
   is(headers.length, 3, "There are 3 headers for inherited rules");
 
   is(headers[0].textContent,
     STRINGS.formatStringFromName("rule.inheritedFrom", ["p"], 1),
     "The first header is correct");
   is(headers[1].textContent,
     STRINGS.formatStringFromName("rule.inheritedFrom", ["div"], 1),
     "The second header is correct");
   is(headers[2].textContent,
     STRINGS.formatStringFromName("rule.inheritedFrom", ["body"], 1),
     "The third header is correct");
 
-  let rules = doc.querySelectorAll(".ruleview-rule");
+  let rules = styleDocument.querySelectorAll(".ruleview-rule");
   is(rules.length, 4, "There are 4 rules in the view");
 
   for (let rule of rules) {
     let selector = rule.querySelector(".ruleview-selectorcontainer");
     is(selector.textContent,
       STRINGS.GetStringFromName("rule.sourceElement"),
       "The rule's selector is correct");
 
--- a/browser/devtools/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-01.js
@@ -57,34 +57,33 @@ add_task(function* () {
  *   depending on popupNode
  */
 function* testMdnContextMenuItemVisibility(view) {
   info("Test that MDN context menu item is shown only when it should be.");
 
   let root = rootElement(view);
   for (let node of iterateNodes(root)) {
     info("Setting " + node + " as popupNode");
-    view.doc.popupNode = node;
+    view.styleDocument.popupNode = node;
 
     info("Updating context menu state");
-    view._contextMenuUpdate();
-    let isVisible = !view.menuitemShowMdnDocs.hidden;
+    view._contextmenu._updateMenuItems();
+    let isVisible = !view._contextmenu.menuitemShowMdnDocs.hidden;
     let shouldBeVisible = isPropertyNameNode(node);
     let message = shouldBeVisible? "shown": "hidden";
     is(isVisible, shouldBeVisible,
-       "The MDN context menu item is " + message);
+       "The MDN context menu item is " + message + " ; content : " + node.textContent + " ; type : " + node.nodeType);
   }
 }
 
 /**
  * Check if a node is a property name.
  */
 function isPropertyNameNode(node) {
-  return ((node.nodeType === node.TEXT_NODE) &&
-          (node.textContent === "font-family"));
+  return node.textContent === "font-family";
 }
 
 /**
  * A generator that iterates recursively through all child nodes of baseNode.
  */
 function* iterateNodes(baseNode) {
   yield baseNode;
 
--- a/browser/devtools/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-02.js
@@ -42,24 +42,24 @@ add_task(function* () {
 
 function* testShowMdnTooltip(view) {
   setBaseCssDocsUrl(TEST_URL_ROOT);
 
   info("Setting the popupNode for the MDN docs tooltip");
 
   let {nameSpan} = getRuleViewProperty(view, "element", PROPERTYNAME);
 
-  view.doc.popupNode = nameSpan.firstChild;
-  view._contextMenuUpdate();
+  view.styleDocument.popupNode = nameSpan.firstChild;
+  view._contextmenu._updateMenuItems();
 
   let cssDocs = view.tooltips.cssDocs;
 
   info("Showing the MDN docs tooltip");
   let onShown = cssDocs.tooltip.once("shown");
-  view.menuitemShowMdnDocs.click();
+  view._contextmenu.menuitemShowMdnDocs.click();
   yield onShown;
   ok(true, "The MDN docs tooltip was shown");
 }
 
 /**
  * Test that:
  *  - the MDN tooltip is shown when we click the context menu item
  *  - the tooltip's contents have been initialized (we don't fully
--- a/browser/devtools/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-03.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_context-menu-show-mdn-docs-03.js
@@ -96,21 +96,21 @@ function* setBooleanPref(pref, state) {
  */
 function* testMdnContextMenuItemVisibility(view, shouldBeVisible) {
   let message = shouldBeVisible? "shown": "hidden";
   info("Test that MDN context menu item is " + message);
 
   info("Set a CSS property name as popupNode");
   let root = rootElement(view);
   let node = root.querySelector("." + PROPERTY_NAME_CLASS).firstChild;
-  view.doc.popupNode = node;
+  view.styleDocument.popupNode = node;
 
   info("Update context menu state");
-  view._contextMenuUpdate();
-  let isVisible = !view.menuitemShowMdnDocs.hidden;
+  view._contextmenu._updateMenuItems();
+  let isVisible = !view._contextmenu.menuitemShowMdnDocs.hidden;
   is(isVisible, shouldBeVisible,
      "The MDN context menu item is " + message);
 }
 
 /**
  * Returns the root element for the rule view.
  */
 let rootElement = view => (view.element) ? view.element : view.styleDocument;
--- a/browser/devtools/styleinspector/test/browser_ruleview_copy_styles.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_copy_styles.js
@@ -13,68 +13,68 @@ XPCOMUtils.defineLazyGetter(this, "osStr
   return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
 });
 
 let TEST_URI = TEST_URL_ROOT + "doc_copystyles.html";
 
 add_task(function*() {
   yield addTab(TEST_URI);
   let { inspector, view } = yield openRuleView();
-
+  let contextmenu = view._contextmenu;
   yield selectNode("#testid", inspector);
 
   let ruleEditor = getRuleViewRuleEditor(view, 1);
 
   let data = [
     {
       desc: "Test Copy Property Name",
       node: ruleEditor.rule.textProps[0].editor.nameSpan,
-      menuItem: view.menuitemCopyPropertyName,
+      menuItem: contextmenu.menuitemCopyPropertyName,
       expectedPattern: "color",
       hidden: {
         copyLocation: true,
         copyPropertyDeclaration: false,
         copyPropertyName: false,
         copyPropertyValue: true,
         copySelector: true,
         copyRule: false
       }
     },
     {
       desc: "Test Copy Property Value",
       node: ruleEditor.rule.textProps[2].editor.valueSpan,
-      menuItem: view.menuitemCopyPropertyValue,
+      menuItem: contextmenu.menuitemCopyPropertyValue,
       expectedPattern: "12px",
       hidden: {
         copyLocation: true,
         copyPropertyDeclaration: false,
         copyPropertyName: true,
         copyPropertyValue: false,
         copySelector: true,
         copyRule: false
       }
     },
     {
       desc: "Test Copy Property Declaration",
       node: ruleEditor.rule.textProps[2].editor.nameSpan,
-      menuItem: view.menuitemCopyPropertyDeclaration,
+      menuItem: contextmenu.menuitemCopyPropertyDeclaration,
       expectedPattern: "font-size: 12px;",
       hidden: {
         copyLocation: true,
         copyPropertyDeclaration: false,
         copyPropertyName: false,
         copyPropertyValue: true,
         copySelector: true,
         copyRule: false
       }
     },
     {
       desc: "Test Copy Rule",
       node: ruleEditor.rule.textProps[2].editor.nameSpan,
-      menuItem: view.menuitemCopyRule,
+      menuItem: contextmenu.menuitemCopyRule,
       expectedPattern: "#testid {[\\r\\n]+" +
                        "\tcolor: #F00;[\\r\\n]+" +
                        "\tbackground-color: #00F;[\\r\\n]+" +
                        "\tfont-size: 12px;[\\r\\n]+" +
                        "}",
       hidden: {
         copyLocation: true,
         copyPropertyDeclaration: false,
@@ -82,31 +82,31 @@ add_task(function*() {
         copyPropertyValue: true,
         copySelector: true,
         copyRule: false
       }
     },
     {
       desc: "Test Copy Selector",
       node: ruleEditor.selectorText,
-      menuItem: view.menuitemCopySelector,
+      menuItem: contextmenu.menuitemCopySelector,
       expectedPattern: "html, body, #testid",
       hidden: {
         copyLocation: true,
         copyPropertyDeclaration: true,
         copyPropertyName: true,
         copyPropertyValue: true,
         copySelector: false,
         copyRule: false
       }
     },
     {
       desc: "Test Copy Location",
       node: ruleEditor.source,
-      menuItem: view.menuitemCopyLocation,
+      menuItem: contextmenu.menuitemCopyLocation,
       expectedPattern: "http://example.com/browser/browser/devtools/" +
                        "styleinspector/test/doc_copystyles.css",
       hidden: {
         copyLocation: false,
         copyPropertyDeclaration: true,
         copyPropertyName: true,
         copyPropertyValue: true,
         copySelector: true,
@@ -114,17 +114,17 @@ add_task(function*() {
       }
     },
     {
       setup: function*() {
         yield disableProperty(view);
       },
       desc: "Test Copy Rule with Disabled Property",
       node: ruleEditor.rule.textProps[2].editor.nameSpan,
-      menuItem: view.menuitemCopyRule,
+      menuItem: contextmenu.menuitemCopyRule,
       expectedPattern: "#testid {[\\r\\n]+" +
                        "\t\/\\* color: #F00; \\*\/[\\r\\n]+" +
                        "\tbackground-color: #00F;[\\r\\n]+" +
                        "\tfont-size: 12px;[\\r\\n]+" +
                        "}",
       hidden: {
         copyLocation: true,
         copyPropertyDeclaration: false,
@@ -132,17 +132,17 @@ add_task(function*() {
         copyPropertyValue: true,
         copySelector: true,
         copyRule: false
       }
     },
     {
       desc: "Test Copy Property Declaration with Disabled Property",
       node: ruleEditor.rule.textProps[0].editor.nameSpan,
-      menuItem: view.menuitemCopyPropertyDeclaration,
+      menuItem: contextmenu.menuitemCopyPropertyDeclaration,
       expectedPattern: "\/\\* color: #F00; \\*\/",
       hidden: {
         copyLocation: true,
         copyPropertyDeclaration: false,
         copyPropertyName: false,
         copyPropertyValue: true,
         copySelector: true,
         copyRule: false
@@ -156,63 +156,61 @@ add_task(function*() {
     }
 
     info(desc);
     yield checkCopyStyle(view, node, menuItem, expectedPattern, hidden);
   }
 });
 
 function* checkCopyStyle(view, node, menuItem, expectedPattern, hidden) {
-  let win = view.doc.defaultView;
-
-  let onPopup = once(view._contextmenu, "popupshown");
+  let onPopup = once(view._contextmenu._menupopup, "popupshown");
   EventUtils.synthesizeMouseAtCenter(node,
-    {button: 2, type: "contextmenu"}, win);
+    {button: 2, type: "contextmenu"}, view.styleWindow);
   yield onPopup;
 
-  is(view.menuitemCopy.hidden, true, "Copy hidden is as expected: true");
+  is(view._contextmenu.menuitemCopy.hidden, true, "Copy hidden is as expected: true");
 
-  is(view.menuitemCopyLocation.hidden,
+  is(view._contextmenu.menuitemCopyLocation.hidden,
      hidden.copyLocation,
      "Copy Location hidden attribute is as expected: " +
      hidden.copyLocation);
 
-  is(view.menuitemCopyPropertyDeclaration.hidden,
+  is(view._contextmenu.menuitemCopyPropertyDeclaration.hidden,
      hidden.copyPropertyDeclaration,
      "Copy Property Declaration hidden attribute is as expected: " +
      hidden.copyPropertyDeclaration);
 
-  is(view.menuitemCopyPropertyName.hidden,
+  is(view._contextmenu.menuitemCopyPropertyName.hidden,
      hidden.copyPropertyName,
      "Copy Property Name hidden attribute is as expected: " +
      hidden.copyPropertyName);
 
-  is(view.menuitemCopyPropertyValue.hidden,
+  is(view._contextmenu.menuitemCopyPropertyValue.hidden,
      hidden.copyPropertyValue,
      "Copy Property Value hidden attribute is as expected: " +
      hidden.copyPropertyValue);
 
-  is(view.menuitemCopySelector.hidden,
+  is(view._contextmenu.menuitemCopySelector.hidden,
      hidden.copySelector,
      "Copy Selector hidden attribute is as expected: " +
      hidden.copySelector);
 
-  is(view.menuitemCopyRule.hidden,
+  is(view._contextmenu.menuitemCopyRule.hidden,
      hidden.copyRule,
      "Copy Rule hidden attribute is as expected: " +
      hidden.copyRule);
 
   try {
     yield waitForClipboard(() => menuItem.click(),
       () => checkClipboardData(expectedPattern));
   } catch(e) {
     failedClipboard(expectedPattern);
   }
 
-  view._contextmenu.hidePopup();
+  view._contextmenu._menupopup.hidePopup();
 }
 
 function* disableProperty(view) {
   let ruleEditor = getRuleViewRuleEditor(view, 1);
   let propEditor = ruleEditor.rule.textProps[0].editor;
 
   info("Disabling a property");
   propEditor.enable.click();
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-property-commit.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-property-commit.js
@@ -61,17 +61,17 @@ function* runTestData(view, {value, comm
 
   info("Focusing the inplace editor field");
 
   let editor = yield focusEditableField(view, propEditor.valueSpan);
   is(inplaceEditor(propEditor.valueSpan), editor, "Focused editor should be the value span.");
 
   info("Entering test data " + value);
   let onRuleViewChanged = view.once("ruleview-changed");
-  EventUtils.sendString(value, view.doc.defaultView);
+  EventUtils.sendString(value, view.styleWindow);
 
   info("Waiting for focus on the field");
   let onBlur = once(editor.input, "blur");
 
   info("Entering the commit key " + commitKey + " " + modifiers);
   EventUtils.synthesizeKey(commitKey, modifiers);
   yield onBlur;
   // No matter if we escape or commit the change, the preview throttle is going
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-property-computed.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-property-computed.js
@@ -30,17 +30,17 @@ function* editAndCheck(view) {
 
   info("Focusing the inplace editor field");
   let editor = yield focusEditableField(view, propEditor.valueSpan);
   is(inplaceEditor(propEditor.valueSpan), editor, "Focused editor should be the value span.");
 
   let onPropertyChange = waitForComputedStyleProperty("#testid", null, "padding-top", newPaddingValue);
 
   info("Entering a new value");
-  EventUtils.sendString(newPaddingValue, view.doc.defaultView);
+  EventUtils.sendString(newPaddingValue, view.styleWindow);
 
   info("Waiting for the throttled previewValue to apply the changes to document");
   yield onPropertyChange;
 
   let onBlur = once(editor.input, "blur");
 
   info("Entering the commit key and finishing edit");
   EventUtils.synthesizeKey("VK_RETURN", {});
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-property-increments.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-property-increments.js
@@ -168,17 +168,17 @@ function* testIncrement(editor, options,
   is(input.value, options.start, "Value initialized at " + options.start);
 
   let onRuleViewChanged = view.once("ruleview-changed");
   let onKeyUp = once(input, "keyup");
   let key;
   key = options.down ? "VK_DOWN" : "VK_UP";
   key = options.pageDown ? "VK_PAGE_DOWN" : options.pageUp ? "VK_PAGE_UP" : key;
   EventUtils.synthesizeKey(key, {altKey: options.alt, shiftKey: options.shift},
-    view.doc.defaultView);
+    view.styleWindow);
   yield onKeyUp;
   // Only expect a change if the value actually changed!
   if (options.start !== options.end) {
     yield onRuleViewChanged;
   }
 
   is(input.value, options.end, "Value changed to " + options.end);
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-property_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-property_02.js
@@ -36,60 +36,60 @@ function* testEditProperty(inspector, ru
 
   let editor = yield focusEditableField(ruleView, propEditor.nameSpan);
   let input = editor.input;
   is(inplaceEditor(propEditor.nameSpan), editor, "Next focused editor should be the name editor.");
 
   ok(input.selectionStart === 0 && input.selectionEnd === input.value.length, "Editor contents are selected.");
 
   // Try clicking on the editor's input again, shouldn't cause trouble (see bug 761665).
-  EventUtils.synthesizeMouse(input, 1, 1, {}, ruleView.doc.defaultView);
+  EventUtils.synthesizeMouse(input, 1, 1, {}, ruleView.styleWindow);
   input.select();
 
   info("Entering property name \"border-color\" followed by a colon to focus the value");
   let onFocus = once(idRuleEditor.element, "focus", true);
-  EventUtils.sendString("border-color:", ruleView.doc.defaultView);
+  EventUtils.sendString("border-color:", ruleView.styleWindow);
   yield onFocus;
   yield idRuleEditor.rule._applyingModifications;
 
   info("Verifying that the focused field is the valueSpan");
-  editor = inplaceEditor(ruleView.doc.activeElement);
+  editor = inplaceEditor(ruleView.styleDocument.activeElement);
   input = editor.input;
   is(inplaceEditor(propEditor.valueSpan), editor, "Focus should have moved to the value.");
   ok(input.selectionStart === 0 && input.selectionEnd === input.value.length, "Editor contents are selected.");
 
   info("Entering a value following by a semi-colon to commit it");
   let onBlur = once(editor.input, "blur");
   // Use sendChar() to pass each character as a string so that we can test propEditor.warning.hidden after each character.
   for (let ch of "red;") {
-    EventUtils.sendChar(ch, ruleView.doc.defaultView);
+    EventUtils.sendChar(ch, ruleView.styleWindow);
     is(propEditor.warning.hidden, true,
       "warning triangle is hidden or shown as appropriate");
   }
   yield onBlur;
   yield idRuleEditor.rule._applyingModifications;
 
   let newValue = yield executeInContent("Test:GetRulePropertyValue", {
     styleSheetIndex: 0,
     ruleIndex: 0,
     name: "border-color"
   });
   is(newValue, "red", "border-color should have been set.");
 
   info("Entering property name \"color\" followed by a colon to focus the value");
   onFocus = once(idRuleEditor.element, "focus", true);
-  EventUtils.sendString("color:", ruleView.doc.defaultView);
+  EventUtils.sendString("color:", ruleView.styleWindow);
   yield onFocus;
 
   info("Verifying that the focused field is the valueSpan");
-  editor = inplaceEditor(ruleView.doc.activeElement);
+  editor = inplaceEditor(ruleView.styleDocument.activeElement);
 
   info("Entering a value following by a semi-colon to commit it");
   onBlur = once(editor.input, "blur");
-  EventUtils.sendString("red;", ruleView.doc.defaultView);
+  EventUtils.sendString("red;", ruleView.styleWindow);
   yield onBlur;
   yield idRuleEditor.rule._applyingModifications;
 
   let props = ruleView.element.querySelectorAll(".ruleview-property");
   for (let i = 0; i < props.length; i++) {
     is(props[i].hasAttribute("dirty"), i <= 1,
       "props[" + i + "] marked dirty as appropriate");
   }
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-selector-commit.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-selector-commit.js
@@ -82,17 +82,17 @@ function* runTestData(inspector, view, d
       "The selector editor got focused");
 
   info("Enter the new selector value: " + value);
   editor.input.value = value;
 
   info("Entering the commit key " + commitKey + " " + modifiers);
   EventUtils.synthesizeKey(commitKey, modifiers);
 
-  let activeElement = view.doc.activeElement;
+  let activeElement = view.styleDocument.activeElement;
 
   if (commitKey === "VK_ESCAPE") {
     is(idRuleEditor.rule.selectorText, expected,
         "Value is as expected: " + expected);
     is(idRuleEditor.isEditing, false, "Selector is not being edited.");
     is(idRuleEditor.selectorText, activeElement,
        "Focus is on selector span.");
     return;
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-selector_04.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-selector_04.js
@@ -30,17 +30,17 @@ add_task(function*() {
 
 function* testSelectorHighlight(view, name) {
   info("Test creating selector highlighter");
 
   info("Clicking on a selector icon");
   let icon = getRuleViewSelectorHighlighterIcon(view, name);
 
   let onToggled = view.once("ruleview-selectorhighlighter-toggled");
-  EventUtils.synthesizeMouseAtCenter(icon, {}, view.doc.defaultView);
+  EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
   let isVisible = yield onToggled;
 
   ok(view.selectorHighlighter, "The selectorhighlighter instance was created");
   ok(isVisible, "The toggle event says the highlighter is visible");
 }
 
 function* testEditSelector(view, name) {
   info("Test editing existing selector fields");
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-selector_05.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-selector_05.js
@@ -77,22 +77,22 @@ function* testAddProperty(view) {
   let input = editor.input;
 
   info("Entering text-align in the property name editor");
   input.value = "text-align";
 
   info("Pressing return to commit and focus the new value field");
   let onValueFocus = once(ruleEditor.element, "focus", true);
   let onRuleViewChanged = view.once("ruleview-changed");
-  EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
   yield onValueFocus;
   yield onRuleViewChanged;
 
   // Getting the new value editor after focus
-  editor = inplaceEditor(view.doc.activeElement);
+  editor = inplaceEditor(view.styleDocument.activeElement);
   let textProp = ruleEditor.rule.textProps[0];
 
   is(ruleEditor.rule.textProps.length,  1, "Created a new text property.");
   is(ruleEditor.propertyList.children.length, 1, "Created a property editor.");
   is(editor, inplaceEditor(textProp.editor.valueSpan),
     "Editing the value span now.");
 
   info("Entering a value and bluring the field to expect a rule change");
--- a/browser/devtools/styleinspector/test/browser_ruleview_filtereditor-commit-on-ENTER.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_filtereditor-commit-on-ENTER.js
@@ -24,14 +24,14 @@ add_task(function*() {
   let widget = yield filterTooltip.widget;
 
   widget.setCssValue("blur(2px)");
   yield waitForComputedStyleProperty("body", null, "filter", "blur(2px)");
 
   ok(true, "Changes previewed on the element");
 
   info("Pressing RETURN to commit changes");
-  EventUtils.sendKey("RETURN", widget.doc.defaultView);
+  EventUtils.sendKey("RETURN", widget.styleWindow);
 
   const computed = content.getComputedStyle(content.document.body);
   is(computed.filter, "blur(2px)",
      "The elemenet's filter was kept after RETURN");
 });
--- a/browser/devtools/styleinspector/test/browser_ruleview_filtereditor-revert-on-ESC.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_filtereditor-revert-on-ESC.js
@@ -24,15 +24,15 @@ add_task(function*() {
   let widget = yield filterTooltip.widget;
 
   widget.setCssValue("blur(2px)");
   yield waitForComputedStyleProperty("body", null, "filter", "blur(2px)");
 
   ok(true, "Changes previewed on the element");
 
   info("Pressing ESCAPE to close the tooltip");
-  EventUtils.sendKey("ESCAPE", widget.doc.defaultView);
+  EventUtils.sendKey("ESCAPE", widget.styleWindow);
 
   yield waitForSuccess(() => {
     const computed = content.getComputedStyle(content.document.body);
     return computed.filter === "blur(2px) contrast(2)";
   }, "Waiting for the change to be reverted on the element");
 });
--- a/browser/devtools/styleinspector/test/browser_ruleview_keybindings.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_keybindings.js
@@ -10,17 +10,17 @@
 add_task(function*() {
   yield addTab("data:text/html;charset=utf-8,<h1>Some header text</h1>");
   let {toolbox, inspector, view} = yield openRuleView();
 
   info("Selecting the test node");
   yield selectNode("h1", inspector);
 
   info("Getting the ruleclose brace element");
-  let brace = view.doc.querySelector(".ruleview-ruleclose");
+  let brace = view.styleDocument.querySelector(".ruleview-ruleclose");
 
   info("Clicking on the brace element to focus the new property field");
   let onFocus = once(brace.parentNode, "focus", true);
   brace.click();
   yield onFocus;
 
   info("Entering a property name");
   let editor = getCurrentInplaceEditor(view);
@@ -46,10 +46,10 @@ add_task(function*() {
   EventUtils.sendKey("return");
   yield onFocus;
   yield onRuleViewChanged;
   ok(true, "The new property name field was focused");
   getCurrentInplaceEditor(view).input.blur();
 });
 
 function getCurrentInplaceEditor(view) {
-  return inplaceEditor(view.doc.activeElement);
+  return inplaceEditor(view.styleDocument.activeElement);
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_livepreview.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_livepreview.js
@@ -42,17 +42,17 @@ function* testLivePreviewData(data, rule
   let idRuleEditor = getRuleViewRuleEditor(ruleView, 1);
   let propEditor = idRuleEditor.rule.textProps[0].editor;
 
   info("Focusing the property value inplace-editor");
   let editor = yield focusEditableField(ruleView, propEditor.valueSpan);
   is(inplaceEditor(propEditor.valueSpan), editor, "The focused editor is the value");
 
   info("Enter a value in the editor")
-  EventUtils.sendString(data.value, ruleView.doc.defaultView);
+  EventUtils.sendString(data.value, ruleView.styleWindow);
   if (data.escape) {
     EventUtils.synthesizeKey("VK_ESCAPE", {});
   } else {
     EventUtils.synthesizeKey("VK_RETURN", {});
   }
 
   // Wait for the modifyproperties request to complete before
   // checking the computed style.
--- a/browser/devtools/styleinspector/test/browser_ruleview_multiple-properties-unfinished_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_multiple-properties-unfinished_01.js
@@ -42,19 +42,19 @@ function* testCreateNewMultiUnfinished(i
   yield createNewRuleViewProperty(ruleEditor,
     "color:blue;background : orange   ; text-align:center; border-color: ");
   yield onMutation;
   yield onRuleViewChanged;
 
   is(ruleEditor.rule.textProps.length, 4, "Should have created new text properties.");
   is(ruleEditor.propertyList.children.length, 4, "Should have created property editors.");
 
-  EventUtils.sendString("red", view.doc.defaultView);
+  EventUtils.sendString("red", view.styleWindow);
   onRuleViewChanged = view.once("ruleview-changed");
-  EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
   yield onRuleViewChanged;
 
   is(ruleEditor.rule.textProps.length, 4, "Should have the same number of text properties.");
   is(ruleEditor.propertyList.children.length, 5, "Should have added the changed value editor.");
 
   is(ruleEditor.rule.textProps[0].name, "color", "Should have correct property name");
   is(ruleEditor.rule.textProps[0].value, "blue", "Should have correct property value");
 
--- a/browser/devtools/styleinspector/test/browser_ruleview_multiple-properties-unfinished_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_multiple-properties-unfinished_02.js
@@ -29,17 +29,17 @@ function* testCreateNewMultiPartialUnfin
 
   is(ruleEditor.rule.textProps.length, 2, "Should have created a new text property.");
   is(ruleEditor.propertyList.children.length, 2, "Should have created a property editor.");
 
   // Value is focused, lets add multiple rules here and make sure they get added
   onMutation = inspector.once("markupmutation");
   let valueEditor = ruleEditor.propertyList.children[1].querySelector("input");
   valueEditor.value = "10px;background:orangered;color: black;";
-  EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
   yield onMutation;
 
   is(ruleEditor.rule.textProps.length, 4, "Should have added the changed value.");
   is(ruleEditor.propertyList.children.length, 5, "Should have added the changed value editor.");
 
   is(ruleEditor.rule.textProps[0].name, "width", "Should have correct property name");
   is(ruleEditor.rule.textProps[0].value, "100px", "Should have correct property value");
 
--- a/browser/devtools/styleinspector/test/browser_ruleview_multiple_properties_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_multiple_properties_02.js
@@ -27,23 +27,23 @@ function* testMultiValues(inspector, rul
 
   is(ruleEditor.rule.textProps.length, 1, "Should have created a new text property.");
   is(ruleEditor.propertyList.children.length, 1, "Should have created a property editor.");
 
   // Value is focused, lets add multiple rules here and make sure they get added
   let onMutation = inspector.once("markupmutation");
   let valueEditor = ruleEditor.propertyList.children[0].querySelector("input");
   valueEditor.value = "height: 10px;color:blue"
-  EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
   yield onMutation;
 
   is(ruleEditor.rule.textProps.length, 2, "Should have added the changed value.");
   is(ruleEditor.propertyList.children.length, 3, "Should have added the changed value editor.");
 
-  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
+  EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
   is(ruleEditor.propertyList.children.length, 2, "Should have removed the value editor.");
 
   is(ruleEditor.rule.textProps[0].name, "width", "Should have correct property name");
   is(ruleEditor.rule.textProps[0].value, "height: 10px", "Should have correct property value");
 
   is(ruleEditor.rule.textProps[1].name, "color", "Should have correct property name");
   is(ruleEditor.rule.textProps[1].value, "blue", "Should have correct property value");
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_pseudo-element_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_pseudo-element_01.js
@@ -47,17 +47,17 @@ function* testTopLeft(inspector, view) {
 
   expander.click();
   ok(view.element.firstChild.classList.contains("show-expandable-container"),
      "Pseudo Elements are expanded again");
 
   info("Make sure that dblclicking on the header container also toggles " +
        "the pseudo elements");
   EventUtils.synthesizeMouseAtCenter(gutters[0], {clickCount: 2},
-                                     view.doc.defaultView);
+                                     view.styleWindow);
   ok(!view.element.firstChild.classList.contains("show-expandable-container"),
      "Pseudo Elements are collapsed by dblclicking");
 
   let elementRule = rules.elementRules[0];
   let elementRuleView = getRuleViewRuleEditor(view, 3);
 
   let elementFirstLineRule = rules.firstLineRules[0];
   let elementFirstLineRuleView = [...view.element.children[1].children].filter(e => {
--- a/browser/devtools/styleinspector/test/browser_ruleview_refresh-on-attribute-change_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_refresh-on-attribute-change_01.js
@@ -42,17 +42,17 @@ add_task(function*() {
   testElement.setAttribute("id", "testid");
   yield ruleViewRefreshed;
 
   info("Checking that the rule-view has all the selectors again");
   checkRuleViewContent(view, ["element", "#testid", ".testclass"]);
 });
 
 function checkRuleViewContent(view, expectedSelectors) {
-  let selectors = view.doc.querySelectorAll(".ruleview-selectorcontainer");
+  let selectors = view.styleDocument.querySelectorAll(".ruleview-selectorcontainer");
 
   is(selectors.length, expectedSelectors.length,
     expectedSelectors.length + " selectors are displayed");
 
   for (let i = 0; i < expectedSelectors.length; i ++) {
     is(selectors[i].textContent.indexOf(expectedSelectors[i]), 0,
       "Selector " + (i + 1) + " is " + expectedSelectors[i]);
   }
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_01.js
@@ -26,17 +26,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_02.js
@@ -26,17 +26,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_03.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_03.js
@@ -26,17 +26,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_04.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_04.js
@@ -26,17 +26,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_05.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_05.js
@@ -26,17 +26,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_06.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_06.js
@@ -27,17 +27,17 @@ add_task(function*() {
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
   yield testRemoveTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
@@ -63,17 +63,17 @@ function* testAddTextInFilter(inspector,
     "margin-bottom computed property is correctly highlighted.");
   ok(computed.children[3].classList.contains("ruleview-highlight"),
     "margin-left computed property is correctly highlighted.");
 }
 
 function* testRemoveTextInFilter(inspector, ruleView) {
   info("Press backspace and set filter text to \"margin\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   EventUtils.synthesizeKey("VK_BACK_SPACE", {}, win);
   yield inspector.once("ruleview-filtered");
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_07.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_07.js
@@ -23,17 +23,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode(".testclass", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_clear.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_clear.js
@@ -27,22 +27,21 @@ add_task(function*() {
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
   yield testClearSearchFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
-  synthesizeKeys(SEARCH, win);
+  synthesizeKeys(SEARCH, ruleView.styleWindow);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
   is(ruleView.element.children.length, 2, "Should have 2 rules.");
   is(getRuleViewRuleEditor(ruleView, 0).rule.selectorText, "element",
     "First rule is inline element.");
 
   let rule = getRuleViewRuleEditor(ruleView, 1).rule;
@@ -63,30 +62,28 @@ function* testAddTextInFilter(inspector,
     "margin-bottom computed property is not highlighted.");
   ok(computed.children[3].classList.contains("ruleview-highlight"),
     "margin-left computed property is correctly highlighted.");
 }
 
 function* testClearSearchFilter(inspector, ruleView) {
   info("Clearing the search filter");
 
-  let doc = ruleView.doc;
-  let win = ruleView.doc.defaultView;
   let searchField = ruleView.searchField;
   let searchClearButton = ruleView.searchClearButton;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
-  EventUtils.synthesizeMouseAtCenter(searchClearButton, {}, win);
+  EventUtils.synthesizeMouseAtCenter(searchClearButton, {}, ruleView.styleWindow);
 
   yield onRuleViewFiltered;
 
   info("Check the search filter is cleared and no rules are highlighted");
   is(ruleView.element.children.length, 3, "Should have 3 rules.");
   ok(!searchField.value, "Search filter is cleared");
-  ok(!doc.querySelectorAll(".ruleview-highlight").length,
+  ok(!ruleView.styleDocument.querySelectorAll(".ruleview-highlight").length,
     "No rules are higlighted");
 
   let ruleEditor = getRuleViewRuleEditor(ruleView, 1).rule.textProps[0].editor;
   let computed = ruleEditor.computed;
 
   ok(!ruleEditor.expander.getAttribute("open"), "Expander is closed.");
   ok(!computed.hasAttribute("filter-open"), "margin computed list is closed.");
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_expander.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter-computed-list_expander.js
@@ -25,29 +25,28 @@ add_task(function*() {
   yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testOpenExpanderAndAddTextInFilter(inspector, view);
   yield testClearSearchFilter(inspector, view);
 });
 
 function* testOpenExpanderAndAddTextInFilter(inspector, ruleView) {
-  let win = ruleView.doc.defaultView;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
   let rule = getRuleViewRuleEditor(ruleView, 1).rule;
   let ruleEditor = rule.textProps[0].editor;
   let computed = ruleEditor.computed;
 
   info("Opening the computed list of margin property")
   ruleEditor.expander.click();
 
   info("Setting filter text to \"" + SEARCH + "\"");
   searchField.focus();
-  synthesizeKeys(SEARCH, win);
+  synthesizeKeys(SEARCH, ruleView.styleWindow);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
   is(ruleView.element.children.length, 2, "Should have 2 rules.");
   is(getRuleViewRuleEditor(ruleView, 0).rule.selectorText, "element",
     "First rule is inline element.");
 
   is(rule.selectorText, "#testid", "Second rule is #testid.");
@@ -67,30 +66,28 @@ function* testOpenExpanderAndAddTextInFi
     "margin-bottom computed property is not highlighted.");
   ok(computed.children[3].classList.contains("ruleview-highlight"),
     "margin-left computed property is correctly highlighted.");
 }
 
 function* testClearSearchFilter(inspector, ruleView) {
   info("Clearing the search filter");
 
-  let doc = ruleView.doc;
-  let win = ruleView.doc.defaultView;
   let searchField = ruleView.searchField;
   let searchClearButton = ruleView.searchClearButton;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
-  EventUtils.synthesizeMouseAtCenter(searchClearButton, {}, win);
+  EventUtils.synthesizeMouseAtCenter(searchClearButton, {}, ruleView.styleWindow);
 
   yield onRuleViewFiltered;
 
   info("Check the search filter is cleared and no rules are highlighted");
   is(ruleView.element.children.length, 3, "Should have 3 rules.");
   ok(!searchField.value, "Search filter is cleared");
-  ok(!doc.querySelectorAll(".ruleview-highlight").length,
+  ok(!ruleView.styleDocument.querySelectorAll(".ruleview-highlight").length,
     "No rules are higlighted");
 
   let ruleEditor = getRuleViewRuleEditor(ruleView, 1).rule.textProps[0].editor;
   let computed = ruleEditor.computed;
 
   ok(ruleEditor.expander.getAttribute("open"), "Expander is open.");
   ok(!computed.hasAttribute("filter-open"),
     "margin computed list does not contain filter-open class.");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_01.js
@@ -25,17 +25,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_02.js
@@ -26,17 +26,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_03.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_03.js
@@ -25,17 +25,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFilter = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFilter;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_04.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_04.js
@@ -14,17 +14,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#boxy", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFilter = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFilter;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_05.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_05.js
@@ -25,17 +25,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFilter = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFilter;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_06.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_06.js
@@ -25,17 +25,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_07.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_07.js
@@ -25,17 +25,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_08.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_08.js
@@ -25,17 +25,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_09.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_09.js
@@ -22,17 +22,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_10.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_10.js
@@ -27,17 +27,17 @@ add_task(function*() {
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
   yield testRemoveTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
@@ -50,17 +50,17 @@ function* testAddTextInFilter(inspector,
   is(rule.selectorText, "#testid", "Second rule is #testid.");
   ok(rule.textProps[0].editor.container.classList.contains("ruleview-highlight"),
     "background-color text property is correctly highlighted.");
 }
 
 function* testRemoveTextInFilter(inspector, ruleView) {
   info("Press backspace and set filter text to \"00\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   EventUtils.synthesizeKey("VK_BACK_SPACE", {}, win);
   yield inspector.once("ruleview-filtered");
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_11.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_11.js
@@ -25,17 +25,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_12.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_12.js
@@ -14,17 +14,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode(".relative1", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_13.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_13.js
@@ -15,17 +15,17 @@ add_task(function*() {
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode(".relative1", inspector);
   yield testAddTextInFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_clear.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_clear.js
@@ -26,17 +26,17 @@ add_task(function*() {
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
   yield testClearSearchFilter(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"" + SEARCH + "\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys(SEARCH, win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
@@ -49,18 +49,18 @@ function* testAddTextInFilter(inspector,
   is(rule.selectorText, "#testid", "Second rule is #testid.");
   ok(rule.textProps[0].editor.container.classList.contains("ruleview-highlight"),
     "background-color text property is correctly highlighted.");
 }
 
 function* testClearSearchFilter(inspector, ruleView) {
   info("Clearing the search filter");
 
-  let doc = ruleView.doc;
-  let win = ruleView.doc.defaultView;
+  let doc = ruleView.styleDocument;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let searchClearButton = ruleView.searchClearButton;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   EventUtils.synthesizeMouseAtCenter(searchClearButton, {}, win);
 
   yield onRuleViewFiltered;
 
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_context-menu.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_context-menu.js
@@ -12,17 +12,17 @@ add_task(function*() {
   yield addTab("data:text/html;charset=utf-8,<h1>test filter context menu</h1>");
 
   info("Opening the rule-view");
   let {toolbox, inspector, view} = yield openRuleView();
 
   info("Selecting the test node");
   yield selectNode("h1", inspector);
 
-  let win = view.doc.defaultView;
+  let win = view.styleWindow;
   let searchField = view.searchField;
   let searchContextMenu = toolbox.textboxContextMenuPopup;
   ok(searchContextMenu,
     "The search filter context menu is loaded in the rule view");
 
   let cmdUndo = searchContextMenu.querySelector("[command=cmd_undo]");
   let cmdDelete = searchContextMenu.querySelector("[command=cmd_delete]");
   let cmdSelectAll = searchContextMenu.querySelector("[command=cmd_selectAll]");
--- a/browser/devtools/styleinspector/test/browser_ruleview_search-filter_escape-keypress.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_search-filter_escape-keypress.js
@@ -25,17 +25,17 @@ add_task(function*() {
   yield selectNode("#testid", inspector);
   yield testAddTextInFilter(inspector, view);
   yield testEscapeKeypress(inspector, view);
 });
 
 function* testAddTextInFilter(inspector, ruleView) {
   info("Setting filter text to \"00F\"");
 
-  let win = ruleView.doc.defaultView;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   synthesizeKeys("00F", win);
   yield onRuleViewFiltered;
 
   info("Check that the correct rules are visible");
@@ -48,18 +48,18 @@ function* testAddTextInFilter(inspector,
   is(rule.selectorText, "#testid", "Second rule is #testid.");
   ok(rule.textProps[0].editor.container.classList.contains("ruleview-highlight"),
     "background-color text property is correctly highlighted.");
 }
 
 function* testEscapeKeypress(inspector, ruleView) {
   info("Pressing the escape key on search filter");
 
-  let doc = ruleView.doc;
-  let win = ruleView.doc.defaultView;
+  let doc = ruleView.styleDocument;
+  let win = ruleView.styleWindow;
   let searchField = ruleView.searchField;
   let onRuleViewFiltered = inspector.once("ruleview-filtered");
 
   searchField.focus();
   EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
   yield onRuleViewFiltered;
 
   info("Check the search filter is cleared and no rules are highlighted");
--- a/browser/devtools/styleinspector/test/browser_ruleview_select-and-copy-styles.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_select-and-copy-styles.js
@@ -40,88 +40,88 @@ add_task(function*() {
 
   yield checkCopySelection(view);
   yield checkSelectAll(view);
 });
 
 function* checkCopySelection(view) {
   info("Testing selection copy");
 
-  let contentDoc = view.doc;
-  let win = contentDoc.defaultView;
+  let contentDoc = view.styleDocument;
+  let win = view.styleWindow;
   let prop = contentDoc.querySelector(".ruleview-property");
   let values = contentDoc.querySelectorAll(".ruleview-propertyvaluecontainer");
 
   let range = contentDoc.createRange();
   range.setStart(prop, 0);
   range.setEnd(values[4], 2);
-  view.doc.defaultView.getSelection().addRange(range);
+  win.getSelection().addRange(range);
 
   info("Checking that _Copy() returns the correct clipboard value");
 
   let expectedPattern = "    margin: 10em;[\\r\\n]+" +
                         "    font-size: 14pt;[\\r\\n]+" +
                         "    font-family: helvetica,sans-serif;[\\r\\n]+" +
                         "    color: #AAA;[\\r\\n]+" +
                         "}[\\r\\n]+" +
                         "html {[\\r\\n]+" +
                         "    color: #000;[\\r\\n]*";
 
-  let onPopup = once(view._contextmenu, "popupshown");
+  let onPopup = once(view._contextmenu._menupopup, "popupshown");
   EventUtils.synthesizeMouseAtCenter(prop,
     {button: 2, type: "contextmenu"}, win);
   yield onPopup;
 
-  ok(!view.menuitemCopy.hidden, "Copy menu item is not hidden as expected");
+  ok(!view._contextmenu.menuitemCopy.hidden, "Copy menu item is not hidden as expected");
 
   try {
-    yield waitForClipboard(() => view.menuitemCopy.click(),
+    yield waitForClipboard(() => view._contextmenu.menuitemCopy.click(),
       () => checkClipboardData(expectedPattern));
   } catch(e) {
     failedClipboard(expectedPattern);
   }
 
-  view._contextmenu.hidePopup();
+  view._contextmenu._menupopup.hidePopup();
 }
 
 function* checkSelectAll(view) {
   info("Testing select-all copy");
 
-  let contentDoc = view.doc;
-  let win = contentDoc.defaultView;
+  let contentDoc = view.styleDocument;
+  let win = view.styleWindow;
   let prop = contentDoc.querySelector(".ruleview-property");
 
   info("Checking that _SelectAll() then copy returns the correct clipboard value");
-  view._onSelectAll();
+  view._contextmenu._onSelectAll();
   let expectedPattern = "[\\r\\n]+" +
                         "element {[\\r\\n]+" +
                         "    margin: 10em;[\\r\\n]+" +
                         "    font-size: 14pt;[\\r\\n]+" +
                         "    font-family: helvetica,sans-serif;[\\r\\n]+" +
                         "    color: #AAA;[\\r\\n]+" +
                         "}[\\r\\n]+" +
                         "html {[\\r\\n]+" +
                         "    color: #000;[\\r\\n]+" +
                         "}[\\r\\n]*";
 
-  let onPopup = once(view._contextmenu, "popupshown");
+  let onPopup = once(view._contextmenu._menupopup, "popupshown");
   EventUtils.synthesizeMouseAtCenter(prop,
     {button: 2, type: "contextmenu"}, win);
   yield onPopup;
 
-  ok(!view.menuitemCopy.hidden, "Copy menu item is not hidden as expected");
+  ok(!view._contextmenu.menuitemCopy.hidden, "Copy menu item is not hidden as expected");
 
   try {
-    yield waitForClipboard(() => view.menuitemCopy.click(),
+    yield waitForClipboard(() => view._contextmenu.menuitemCopy.click(),
       () => checkClipboardData(expectedPattern));
   } catch(e) {
     failedClipboard(expectedPattern);
   }
 
-  view._contextmenu.hidePopup();
+  view._contextmenu._menupopup.hidePopup();
 }
 
 function checkClipboardData(expectedPattern) {
   let actual = SpecialPowers.getClipboardData("text/unicode");
   let expectedRegExp = new RegExp(expectedPattern, "g");
   return expectedRegExp.test(actual);
 }
 
--- a/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_01.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_01.js
@@ -21,14 +21,14 @@ add_task(function*() {
 
   let {view} = yield openRuleView();
   ok(!view.selectorHighlighter, "No selectorhighlighter exist in the rule-view");
 
   info("Clicking on a selector icon");
   let icon = getRuleViewSelectorHighlighterIcon(view, "body, p, td");
 
   let onToggled = view.once("ruleview-selectorhighlighter-toggled");
-  EventUtils.synthesizeMouseAtCenter(icon, {}, view.doc.defaultView);
+  EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
   let isVisible = yield onToggled;
 
   ok(view.selectorHighlighter, "The selectorhighlighter instance was created");
   ok(isVisible, "The toggle event says the highlighter is visible");
 });
--- a/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_02.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_02.js
@@ -75,11 +75,11 @@ add_task(function*() {
   is(HighlighterFront.nodeFront.tagName, "BODY",
     "The right NodeFront is passed to the highlighter (2)");
   is(HighlighterFront.options.selector, "body",
     "The right selector option is passed to the highlighter (2)");
 });
 
 function* clickSelectorIcon(icon, view) {
   let onToggled = view.once("ruleview-selectorhighlighter-toggled");
-  EventUtils.synthesizeMouseAtCenter(icon, {}, view.doc.defaultView);
+  EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
   yield onToggled;
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_03.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_selector-highlighter_03.js
@@ -74,11 +74,11 @@ add_task(function*() {
   icon = getRuleViewSelectorHighlighterIcon(view, "div");
   yield clickSelectorIcon(icon, view);
   ok(!HighlighterFront.isShown,
     "The highlighter is hidden now that the same selector was clicked");
 });
 
 function* clickSelectorIcon(icon, view) {
   let onToggled = view.once("ruleview-selectorhighlighter-toggled");
-  EventUtils.synthesizeMouseAtCenter(icon, {}, view.doc.defaultView);
+  EventUtils.synthesizeMouseAtCenter(icon, {}, view.styleWindow);
   yield onToggled;
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_style-editor-link.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_style-editor-link.js
@@ -141,17 +141,17 @@ function validateStyleEditorSheet(editor
      "loaded stylesheet index matches document stylesheet");
 
   let sheet = content.document.styleSheets[expectedSheetIndex];
   is(editor.styleSheet.href, sheet.href, "loaded stylesheet href matches document stylesheet");
 }
 
 function testRuleViewLinkLabel(view) {
   let link = getRuleViewLinkByIndex(view, 2);
-  let labelElem = link.querySelector(".source-link-label");
+  let labelElem = link.querySelector(".ruleview-rule-source-label");
   let value = labelElem.getAttribute("value");
   let tooltipText = labelElem.getAttribute("tooltiptext");
 
   is(value, EXTERNAL_STYLESHEET_FILE_NAME + ":1",
     "rule view stylesheet display value matches filename and line number");
   is(tooltipText, EXTERNAL_STYLESHEET_URL + ":1",
     "rule view stylesheet tooltip text matches the full URI path");
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_urls-clickable.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_urls-clickable.js
@@ -21,41 +21,41 @@ function* selectNodes(inspector, ruleVie
   let relative2 = ".relative2";
   let absolute = ".absolute";
   let inline = ".inline";
   let base64 = ".base64";
   let noimage = ".noimage";
   let inlineresolved = ".inline-resolved";
 
   yield selectNode(relative1, inspector);
-  let relativeLink = ruleView.doc.querySelector(".ruleview-propertyvaluecontainer a");
+  let relativeLink = ruleView.styleDocument.querySelector(".ruleview-propertyvaluecontainer a");
   ok(relativeLink, "Link exists for relative1 node");
   is(relativeLink.getAttribute("href"), TEST_IMAGE, "href matches");
 
   yield selectNode(relative2, inspector);
-  relativeLink = ruleView.doc.querySelector(".ruleview-propertyvaluecontainer a");
+  relativeLink = ruleView.styleDocument.querySelector(".ruleview-propertyvaluecontainer a");
   ok(relativeLink, "Link exists for relative2 node");
   is(relativeLink.getAttribute("href"), TEST_IMAGE, "href matches");
 
   yield selectNode(absolute, inspector);
-  let absoluteLink = ruleView.doc.querySelector(".ruleview-propertyvaluecontainer a");
+  let absoluteLink = ruleView.styleDocument.querySelector(".ruleview-propertyvaluecontainer a");
   ok(absoluteLink, "Link exists for absolute node");
   is(absoluteLink.getAttribute("href"), TEST_IMAGE, "href matches");
 
   yield selectNode(inline, inspector);
-  let inlineLink = ruleView.doc.querySelector(".ruleview-propertyvaluecontainer a");
+  let inlineLink = ruleView.styleDocument.querySelector(".ruleview-propertyvaluecontainer a");
   ok(inlineLink, "Link exists for inline node");
   is(inlineLink.getAttribute("href"), TEST_IMAGE, "href matches");
 
   yield selectNode(base64, inspector);
-  let base64Link = ruleView.doc.querySelector(".ruleview-propertyvaluecontainer a");
+  let base64Link = ruleView.styleDocument.querySelector(".ruleview-propertyvaluecontainer a");
   ok(base64Link, "Link exists for base64 node");
   is(base64Link.getAttribute("href"), BASE_64_URL, "href matches");
 
   yield selectNode(inlineresolved, inspector);
-  let inlineResolvedLink = ruleView.doc.querySelector(".ruleview-propertyvaluecontainer a");
+  let inlineResolvedLink = ruleView.styleDocument.querySelector(".ruleview-propertyvaluecontainer a");
   ok(inlineResolvedLink, "Link exists for style tag node");
   is(inlineResolvedLink.getAttribute("href"), TEST_IMAGE, "href matches");
 
   yield selectNode(noimage, inspector);
-  let noimageLink = ruleView.doc.querySelector(".ruleview-propertyvaluecontainer a");
+  let noimageLink = ruleView.styleDocument.querySelector(".ruleview-propertyvaluecontainer a");
   ok(!noimageLink, "There is no link for the node with no background image");
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_user-property-reset.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_user-property-reset.js
@@ -30,17 +30,17 @@ add_task(function*() {
 
   yield selectNode("#id1", inspector);
   yield assertRuleAndMarkupViewWidth("id1", "200px", view, inspector);
   yield selectNode("#id2", inspector);
   yield assertRuleAndMarkupViewWidth("id2", "100px", view, inspector);
 });
 
 function getStyleRule(ruleView) {
-  return ruleView.doc.querySelector(".ruleview-rule");
+  return ruleView.styleDocument.querySelector(".ruleview-rule");
 }
 
 function* modifyRuleViewWidth(value, ruleView, inspector) {
   info("Getting the property value element");
   let valueSpan = getStyleRule(ruleView).querySelector(".ruleview-propertyvalue");
 
   info("Focusing the property value to set it to edit mode");
   let editor = yield focusEditableField(ruleView, valueSpan.parentNode);
@@ -52,17 +52,17 @@ function* modifyRuleViewWidth(value, rul
   info("Pressing return and waiting for the field to blur and for the markup-view to show the mutation");
   let onBlur = once(editor.input, "blur", true);
   let onMutation = inspector.once("markupmutation");
   EventUtils.sendKey("return");
   yield onBlur;
   yield onMutation;
 
   info("Escaping out of the new property field that has been created after the value was edited");
-  let onNewFieldBlur = once(ruleView.doc.activeElement, "blur", true);
+  let onNewFieldBlur = once(ruleView.styleDocument.activeElement, "blur", true);
   EventUtils.sendKey("escape");
   yield onNewFieldBlur;
 }
 
 function* getContainerStyleAttrValue(id, {walker, markup}) {
   let front = yield walker.querySelector(walker.rootNode, "#" + id);
   let container = markup.getContainer(front);
 
--- a/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_01.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_01.js
@@ -75,35 +75,30 @@ function testIsColorPopupOnAllNodes(view
   for (let node of iterateNodes(root)) {
     testIsColorPopupOnNode(view, node);
   }
 }
 
 /**
  * Test result of _isColorPopup with given node.
  * @param object view
- *               A CSSRuleView or CssHtmlTree instance.
+ *               A CSSRuleView or CssComputedView instance.
  * @param Node node
  *             A node to check.
  */
 function testIsColorPopupOnNode(view, node) {
   info("Testing node " + node);
-  if (view.doc) {
-    view.doc.popupNode = node;
-  }
-  else {
-    view.popupNode = node;
-  }
-  view._colorToCopy = "";
+  view.styleDocument.popupNode = node;
+  view._contextmenu._colorToCopy = "";
 
-  let result = view._isColorPopup();
+  let result = view._contextmenu._isColorPopup();
   let correct = isColorValueNode(node);
 
   is(result, correct, "_isColorPopup returned the expected value " + correct);
-  is(view._colorToCopy, (correct) ? TEST_COLOR : "",
+  is(view._contextmenu._colorToCopy, (correct) ? TEST_COLOR : "",
      "_colorToCopy was set to the expected value");
 }
 
 /**
  * Check if a node is part of color value i.e. it has parent with a 'data-color'
  * attribute.
  */
 function isColorValueNode(node) {
--- a/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_02.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_02.js
@@ -27,70 +27,72 @@ add_task(function* () {
   yield testColorPickerEdit(inspector, view);
 });
 
 function* testCopyToClipboard(inspector, view) {
   info("Testing that color is copied to clipboard");
 
   yield selectNode("div", inspector);
 
-  let win = view.doc.defaultView;
+  let win = view.styleWindow;
   let element = getRuleViewProperty(view, "div", "color").valueSpan
     .querySelector(".ruleview-colorswatch");
 
-  let popup = once(view._contextmenu, "popupshown");
+  let popup = once(view._contextmenu._menupopup, "popupshown");
   EventUtils.synthesizeMouseAtCenter(element, {button: 2, type: "contextmenu"}, win);
   yield popup;
 
-  ok(!view.menuitemCopyColor.hidden, "Copy color is visible");
+  ok(!view._contextmenu.menuitemCopyColor.hidden, "Copy color is visible");
 
-  yield waitForClipboard(() => view.menuitemCopyColor.click(), TEST_COLOR);
-  view._contextmenu.hidePopup();
+  yield waitForClipboard(() => view._contextmenu.menuitemCopyColor.click(), TEST_COLOR);
+  view._contextmenu._menupopup.hidePopup();
 }
 
 function* testManualEdit(inspector, view) {
   info("Testing manually edited colors");
   yield selectNode("div", inspector);
 
   let {valueSpan} = getRuleViewProperty(view, "div", "color");
 
   let newColor = "#C9184E"
   let editor = yield focusEditableField(view, valueSpan);
 
   info("Typing new value");
   let input = editor.input;
   let onBlur = once(input, "blur");
-  EventUtils.sendString(newColor + ";", view.doc.defaultView);
+  EventUtils.sendString(newColor + ";", view.styleWindow);
   yield onBlur;
   yield wait(1);
 
-  let colorValue = getRuleViewProperty(view, "div", "color").valueSpan.firstChild;
-  is(colorValue.dataset.color, newColor, "data-color was updated");
+  let colorValueElement = getRuleViewProperty(view, "div", "color").valueSpan.firstChild;
+  is(colorValueElement.dataset.color, newColor, "data-color was updated");
 
-  view.doc.popupNode = colorValue;
-  view._isColorPopup();
+  view.styleDocument.popupNode = colorValueElement;
 
-  is(view._colorToCopy, newColor, "_colorToCopy has the new value");
+  let contextMenu = view._contextmenu;
+  contextMenu._isColorPopup();
+  is(contextMenu._colorToCopy, newColor, "_colorToCopy has the new value");
 }
 
 function* testColorPickerEdit(inspector, view) {
   info("Testing colors edited via color picker");
   yield selectNode("div", inspector);
 
-  let swatch = getRuleViewProperty(view, "div", "color").valueSpan
+  let swatchElement = getRuleViewProperty(view, "div", "color").valueSpan
     .querySelector(".ruleview-colorswatch");
 
   info("Opening the color picker");
   let picker = view.tooltips.colorPicker;
   let onShown = picker.tooltip.once("shown");
-  swatch.click();
+  swatchElement.click();
   yield onShown;
 
   let rgbaColor = [83, 183, 89, 1];
   let rgbaColorText = "rgba(83, 183, 89, 1)";
   yield simulateColorPickerChange(view, picker, rgbaColor);
 
-  is(swatch.parentNode.dataset.color, rgbaColorText, "data-color was updated");
-  view.doc.popupNode = swatch;
-  view._isColorPopup();
+  is(swatchElement.parentNode.dataset.color, rgbaColorText, "data-color was updated");
+  view.styleDocument.popupNode = swatchElement;
 
-  is(view._colorToCopy, rgbaColorText, "_colorToCopy has the new value");
+  let contextMenu = view._contextmenu;
+  contextMenu._isColorPopup();
+  is(contextMenu._colorToCopy, rgbaColorText, "_colorToCopy has the new value");
 }
--- a/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-urls.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-urls.js
@@ -62,41 +62,41 @@ function* testCopyUrlToClipboard({view, 
   yield selectNode(selector, inspector);
 
   info("Retrieve background-image link for selected node in current styleinspector view");
   let property = getBackgroundImageProperty(view, selector);
   let imageLink = property.valueSpan.querySelector(".theme-link");
   ok(imageLink, "Background-image link element found");
 
   info("Simulate right click on the background-image URL");
-  let popup = once(view._contextmenu, "popupshown");
+  let popup = once(view._contextmenu._menupopup, "popupshown");
 
   // Cannot rely on synthesizeMouseAtCenter here. The image URL can be displayed on several lines.
   // A click simulated at the exact center may click between the lines and miss the target
   // Instead, using the top-left corner of first client rect, with an offset of 2 pixels.
   let rect = imageLink.getClientRects()[0];
   let x = rect.left + 2;
   let y = rect.top + 2;
 
   EventUtils.synthesizeMouseAtPoint(x, y, {button: 2, type: "contextmenu"}, getViewWindow(view));
   yield popup;
 
   info("Context menu is displayed");
-  ok(!view.menuitemCopyImageDataUrl.hidden, "\"Copy Image Data-URL\" menu entry is displayed");
+  ok(!view._contextmenu.menuitemCopyImageDataUrl.hidden, "\"Copy Image Data-URL\" menu entry is displayed");
 
   if (type == "data-uri") {
     info("Click Copy Data URI and wait for clipboard");
-    yield waitForClipboard(() => view.menuitemCopyImageDataUrl.click(), expected);
+    yield waitForClipboard(() => view._contextmenu.menuitemCopyImageDataUrl.click(), expected);
   } else {
     info("Click Copy URL and wait for clipboard");
-    yield waitForClipboard(() => view.menuitemCopyUrl.click(), expected);
+    yield waitForClipboard(() => view._contextmenu.menuitemCopyUrl.click(), expected);
   }
 
   info("Hide context menu");
-  view._contextmenu.hidePopup();
+  view._contextmenu._menupopup.hidePopup();
 }
 
 function getBackgroundImageProperty(view, selector) {
   let isRuleView = view instanceof CssRuleView;
   if (isRuleView) {
     return getRuleViewProperty(view, selector, "background-image");
   } else {
     return getComputedViewProperty(view, "background-image");
--- a/browser/devtools/styleinspector/test/browser_styleinspector_tooltip-background-image.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_tooltip-background-image.js
@@ -90,22 +90,22 @@ function* testTooltipAppearsEvenInEditMo
   info("Switching to edit mode in the rule view");
   let editor = yield turnToEditMode(view);
 
   info("Now trying to show the preview tooltip");
   let {valueSpan} = getRuleViewProperty(view, ".test-element", "background");
   let uriSpan = valueSpan.querySelector(".theme-link");
   yield assertHoverTooltipOn(view.tooltips.previewTooltip, uriSpan);
 
-  is(view.doc.activeElement, editor.input,
+  is(view.styleDocument.activeElement, editor.input,
     "Tooltip was shown in edit mode, and inplace-editor still focused");
 }
 
 function turnToEditMode(ruleView) {
-  let brace = ruleView.doc.querySelector(".ruleview-ruleclose");
+  let brace = ruleView.styleDocument.querySelector(".ruleview-ruleclose");
   return focusEditableField(ruleView, brace);
 }
 
 function* testComputedView(view) {
   let tooltip = view.tooltips.previewTooltip;
   ok(tooltip, "The computed-view has a tooltip defined");
 
   let panel = tooltip.panel;
--- a/browser/devtools/styleinspector/test/head.js
+++ b/browser/devtools/styleinspector/test/head.js
@@ -3,17 +3,17 @@
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const Cu = Components.utils;
 let {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
 let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
 let TargetFactory = devtools.TargetFactory;
-let {CssHtmlTree} = devtools.require("devtools/styleinspector/computed-view");
+let {CssComputedView} = devtools.require("devtools/styleinspector/computed-view");
 let {CssRuleView, _ElementStyle} = devtools.require("devtools/styleinspector/rule-view");
 let {CssLogic, CssSelector} = devtools.require("devtools/styleinspector/css-logic");
 let DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils");
 let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 let {editableField, getInplaceEditorForSpan: inplaceEditor} = devtools.require("devtools/shared/inplace-editor");
 let {console} = Components.utils.import("resource://gre/modules/devtools/Console.jsm", {});
 
 // All tests are asynchronous
@@ -639,17 +639,17 @@ function synthesizeKeys(input, win) {
  * selector
  * @param {CssRuleView} view The instance of the rule-view panel
  * @param {String} selectorText The selector in the rule-view for which the rule
  * object is wanted
  * @return {DOMNode}
  */
 function getRuleViewRule(view, selectorText) {
   let rule;
-  for (let r of view.doc.querySelectorAll(".ruleview-rule")) {
+  for (let r of view.styleDocument.querySelectorAll(".ruleview-rule")) {
     let selector = r.querySelector(".ruleview-selectorcontainer, " +
                                    ".ruleview-selector-matched");
     if (selector && selector.textContent === selectorText) {
       rule = r;
       break;
     }
   }
 
@@ -758,29 +758,29 @@ let simulateColorPickerChange = Task.asy
 
 /**
  * Get a rule-link from the rule-view given its index
  * @param {CssRuleView} view The instance of the rule-view panel
  * @param {Number} index The index of the link to get
  * @return {DOMNode} The link if any at this index
  */
 function getRuleViewLinkByIndex(view, index) {
-  let links = view.doc.querySelectorAll(".ruleview-rule-source");
+  let links = view.styleDocument.querySelectorAll(".ruleview-rule-source");
   return links[index];
 }
 
 /**
  * Get rule-link text from the rule-view given its index
  * @param {CssRuleView} view The instance of the rule-view panel
  * @param {Number} index The index of the link to get
  * @return {String} The string at this index
  */
 function getRuleViewLinkTextByIndex(view, index) {
   let link = getRuleViewLinkByIndex(view, index);
-  return link.querySelector(".source-link-label").value;
+  return link.querySelector(".ruleview-rule-source-label").value;
 }
 
 /**
  * Get the rule editor from the rule-view given its index
  * @param {CssRuleView} view The instance of the rule-view panel
  * @param {Number} childrenIndex The children index of the element to get
  * @param {Number} nodeIndex The child node index of the element to get
  * @return {DOMNode} The rule editor if any at this index
@@ -841,17 +841,17 @@ let createNewRuleViewProperty = Task.asy
  * *********************************************
  * Computed-view related utility functions.
  * Allows to get properties, links, expand properties, ...
  */
 
 /**
  * Get references to the name and value span nodes corresponding to a given
  * property name in the computed-view
- * @param {CssHtmlTree} view The instance of the computed view panel
+ * @param {CssComputedView} view The instance of the computed view panel
  * @param {String} name The name of the property to retrieve
  * @return an object {nameSpan, valueSpan}
  */
 function getComputedViewProperty(view, name) {
   let prop;
   for (let property of view.styleDocument.querySelectorAll(".property-view")) {
     let nameSpan = property.querySelector(".property-name");
     let valueSpan = property.querySelector(".property-value");
@@ -861,17 +861,17 @@ function getComputedViewProperty(view, n
       break;
     }
   }
   return prop;
 }
 
 /**
  * Get an instance of PropertyView from the computed-view.
- * @param {CssHtmlTree} view The instance of the computed view panel
+ * @param {CssComputedView} view The instance of the computed view panel
  * @param {String} name The name of the property to retrieve
  * @return {PropertyView}
  */
 function getComputedViewPropertyView(view, name) {
   let propView;
   for (let propertyView of view.propertyViews) {
     if (propertyView._propertyInfo.name === name) {
       propView = propertyView;
@@ -883,17 +883,17 @@ function getComputedViewPropertyView(vie
 
 /**
  * Get a reference to the property-content element for a given property name in
  * the computed-view.
  * A property-content element always follows (nextSibling) the property itself
  * and is only shown when the twisty icon is expanded on the property.
  * A property-content element contains matched rules, with selectors, properties,
  * values and stylesheet links
- * @param {CssHtmlTree} view The instance of the computed view panel
+ * @param {CssComputedView} view The instance of the computed view panel
  * @param {String} name The name of the property to retrieve
  * @return {Promise} A promise that resolves to the property matched rules
  * container
  */
 let getComputedViewMatchedRules = Task.async(function*(view, name) {
   let expander;
   let propertyContent;
   for (let property of view.styleDocument.querySelectorAll(".property-view")) {
@@ -913,29 +913,29 @@ let getComputedViewMatchedRules = Task.a
   }
 
   return propertyContent;
 });
 
 /**
  * Get the text value of the property corresponding to a given name in the
  * computed-view
- * @param {CssHtmlTree} view The instance of the computed view panel
+ * @param {CssComputedView} view The instance of the computed view panel
  * @param {String} name The name of the property to retrieve
  * @return {String} The property value
  */
 function getComputedViewPropertyValue(view, name, propertyName) {
   return getComputedViewProperty(view, name, propertyName)
     .valueSpan.textContent;
 }
 
 /**
  * Expand a given property, given its index in the current property list of
  * the computed view
- * @param {CssHtmlTree} view The instance of the computed view panel
+ * @param {CssComputedView} view The instance of the computed view panel
  * @param {Number} index The index of the property to be expanded
  * @return a promise that resolves when the property has been expanded, or
  * rejects if the property was not found
  */
 function expandComputedViewPropertyByIndex(view, index) {
   info("Expanding property " + index + " in the computed view");
   let expandos = view.styleDocument.querySelectorAll(".expandable");
   if (!expandos.length || !expandos[index]) {
@@ -944,17 +944,17 @@ function expandComputedViewPropertyByInd
 
   let onExpand = view.inspector.once("computed-view-property-expanded");
   expandos[index].click();
   return onExpand;
 }
 
 /**
  * Get a rule-link from the computed-view given its index
- * @param {CssHtmlTree} view The instance of the computed view panel
+ * @param {CssComputedView} view The instance of the computed view panel
  * @param {Number} index The index of the link to be retrieved
  * @return {DOMNode} The link at the given index, if one exists, null otherwise
  */
 function getComputedViewLinkByIndex(view, index) {
   let links = view.styleDocument.querySelectorAll(".rule-link .link");
   return links[index];
 }
 
--- a/browser/devtools/webide/themes/panel-listing.css
+++ b/browser/devtools/webide/themes/panel-listing.css
@@ -1,46 +1,125 @@
 /* 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/. */
 
 html {
   font: message-box;
   font-size: 12px;
-  font-weight: normal;
+  font-weight: 400;
 }
 
-.panel-item, label, #project-panel-projects, #runtime-panel-projects {
+label,
+.panel-item,
+#project-panel-projects,
+#runtime-panel-projects {
   display: block;
   float: left;
   width: auto;
+  text-align: left;
 }
 
-.project-image, .panel-item span {
+.project-image,
+.panel-item span {
   display: inline-block;
   float: left;
   line-height: 20px;
 }
 
 .project-image {
   margin-right: 10px;
   max-height: 20px;
 }
 
 .panel-header {
   color: #ACACAC;
   text-transform: uppercase;
   line-height: 200%;
-  margin: 5px 0;
-  font-size: 100%;
-  font-weight: bold;
+  margin: 5px 5px 0 5px;
+  font-size: 10%;
+  font-weight: 700;
   width: 100%;
 }
 
-.panel-item {
-  cursor: default;
-  padding: 5px 0;
-  min-width: 130px;
+.panel-header:first-child {
+  margin-top: 0;
 }
 
 .panel-header[hidden] {
   display: none;
 }
+
+#runtime-panel-simulator,
+.panel-item-complex {
+  clear: both;
+  position: relative;
+}
+
+.panel-item {
+  padding: 3%;
+  display: block;
+  background-color: #fff;
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+  border-top: 1px solid #ededed;
+  border-left: 0;
+  width: 94%;
+}
+
+button.panel-item {
+  background-position: 8px 8px;
+  background-repeat: no-repeat;
+  background-size: 14px 14px;
+  padding-left: 25px;
+  width: 100%;
+}
+
+.panel-item:disabled {
+  background-color: #FFF;
+  color: #5A5A5A;
+  opacity: 0.5;
+}
+
+.panel-item:not(:disabled):hover {
+  background-color: #CCF0FD;
+}
+
+.configure-button {
+  display: inline-block;
+  height: 30px;
+  width: 30px;
+  background-color: transparent;
+  background-image: -moz-image-rect(url("icons.png"), 104, 462, 129, 438);
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: 14px 14px;
+  position: absolute;
+  top: 0;
+  right: 0;
+  border: 0;
+}
+
+.configure-button:hover {
+  cursor: pointer;
+}
+
+.project-panel-item-openpackaged  { background-image: -moz-image-rect(url("icons.png"), 260, 438, 286, 412); }
+.runtime-panel-item-simulator     { background-image: -moz-image-rect(url("icons.png"), 0, 438, 26, 412); }
+.runtime-panel-item-other         { background-image: -moz-image-rect(url("icons.png"), 26, 438, 52, 412); }
+#runtime-permissions              { background-image: -moz-image-rect(url("icons.png"), 105, 438, 131, 412); }
+#runtime-screenshot               { background-image: -moz-image-rect(url("icons.png"), 131, 438, 156, 412); }
+
+#runtime-preferences,
+#runtime-settings                 { background-image: -moz-image-rect(url("icons.png"), 105, 464, 131, 438); }
+
+#runtime-panel-nousbdevice,
+#runtime-details                  { background-image: -moz-image-rect(url("icons.png"), 156, 438, 182, 412);  }
+
+.runtime-panel-item-usb,
+#runtime-disconnect               { background-image: -moz-image-rect(url("icons.png"), 52, 438, 78, 412); }
+
+.runtime-panel-item-wifi,
+.project-panel-item-openhosted    { background-image: -moz-image-rect(url("icons.png"), 208, 438, 234, 412); }
+
+.project-panel-item-newapp,
+#runtime-panel-noadbhelper,
+#runtime-panel-installsimulator   { background-image: -moz-image-rect(url("icons.png"), 234, 438, 260, 412); }
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -765,23 +765,25 @@ you can use these alternative items. Oth
 <!ENTITY mixedContentBlocked2.options "Options">
 <!ENTITY mixedContentBlocked2.unblock.label "Disable protection for now">
 <!ENTITY mixedContentBlocked2.unblock.accesskey "D">
 <!ENTITY mixedContentBlocked2.block.label "Enable protection">
 <!ENTITY mixedContentBlocked2.block.accesskey "E">
 <!ENTITY mixedContentBlocked2.disabled.message "Protection is disabled">
 
 <!ENTITY trackingProtection.title "Tracking Protection">
-<!ENTITY trackingProtection.detectedBlocked "Attempts to track your online behavior have been blocked.">
-<!ENTITY trackingProtection.detectedNotBlocked "Tracking elements detected. You have disabled protection on this site.">
-<!ENTITY trackingProtection.notDetected "No tracking elements detected on this website.">
+<!ENTITY trackingProtection.detectedBlocked2 "&brandShortName; is blocking attempts to track your browsing.">
+<!ENTITY trackingProtection.detectedNotBlocked2 "This site includes content that tracks your browsing. You have disabled protection.">
+<!ENTITY trackingProtection.notDetected2 "This site doesn’t include any content that tracks your browsing.">
 <!ENTITY trackingProtection.unblock.label "Disable protection for this site">
 <!ENTITY trackingProtection.unblock.accesskey "D">
-<!ENTITY trackingProtection.block.label "Enable protection for this site">
-<!ENTITY trackingProtection.block.accesskey "E">
+<!-- LOCALIZATION NOTE (trackingProtection.unblockPrivate.label): Uses trackingProtection.unblock.accesskey as its accesskey. -->
+<!ENTITY trackingProtection.unblockPrivate.label "Disable protection for this session">
+<!ENTITY trackingProtection.block2.label "Enable protection">
+<!ENTITY trackingProtection.block2.accesskey "E">
 
 <!ENTITY trackingContentBlocked.message "Tracking">
 <!ENTITY trackingContentBlocked.moreinfo "Parts of the page that track your online activity have been blocked.">
 <!ENTITY trackingContentBlocked.learnMore "Learn More">
 <!ENTITY trackingContentBlocked.options "Options">
 <!ENTITY trackingContentBlocked.unblock2.label "Disable protection for this site">
 <!ENTITY trackingContentBlocked.unblock2.accesskey "D">
 <!ENTITY trackingContentBlocked.block.label "Enable protection">
--- a/browser/locales/en-US/chrome/browser/devtools/sourceeditor.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/sourceeditor.properties
@@ -94,8 +94,18 @@ moveLineDown.commandkey=Alt-Down
 
 # LOCALIZATION NOTE  (autocomplete.commandkey): This is the key to use
 # in conjunction with Ctrl for autocompletion.
 autocompletion.commandkey=Space
 
 # LOCALIZATION NOTE  (showInformation2.commandkey): This is the key to use to
 # show more information, like type inference.
 showInformation2.commandkey=Shift-Ctrl-Space
+
+# LOCALIZATION NOTE  (find.commandkey): This is the key to use in
+# conjunction with accel (Command on Mac or Ctrl on other platforms) to find
+# the typed search
+find.commandkey=F
+
+# LOCALIZATION NOTE  (findAgain.commandkey): This is the key to use in
+# conjunction with accel (Command on Mac or Ctrl on other platforms) to find
+# again the typed search
+findAgain.commandkey=G
--- a/browser/modules/WebappManager.jsm
+++ b/browser/modules/WebappManager.jsm
@@ -202,22 +202,19 @@ this.WebappManager = {
         );
       }
     };
 
     let requestingURI = chromeWin.makeURI(aData.from);
     let app = aData.app;
     let manifest = new ManifestHelper(jsonManifest, app.origin, app.manifestURL);
 
-    let options = {};
-    try {
-      options.displayOrigin = requestingURI.host;
-    } catch(e) {
-      options.displayOrigin = requestingURI.spec;
-    }
+    let options = {
+      displayURI: requestingURI,
+    };
 
     let message = bundle.getFormattedString("webapps.requestInstall2",
                                             [manifest.name]);
 
     let gBrowser = chromeWin.gBrowser;
     if (gBrowser) {
       let windowID = aData.oid;
 
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -140,16 +140,17 @@ browser.jar:
   skin/classic/browser/loop/toolbar.png               (loop/toolbar.png)
   skin/classic/browser/loop/toolbar@2x.png            (loop/toolbar@2x.png)
   skin/classic/browser/loop/toolbar-inverted.png      (loop/toolbar-inverted.png)
   skin/classic/browser/loop/toolbar-inverted@2x.png   (loop/toolbar-inverted@2x.png)
 * skin/classic/browser/controlcenter/panel.css        (controlcenter/panel.css)
   skin/classic/browser/controlcenter/arrow-subview.svg  (../shared/controlcenter/arrow-subview.svg)
   skin/classic/browser/controlcenter/conn-not-secure.svg  (../shared/controlcenter/conn-not-secure.svg)
   skin/classic/browser/controlcenter/conn-secure.svg  (../shared/controlcenter/conn-secure.svg)
+  skin/classic/browser/controlcenter/conn-degraded.svg  (../shared/controlcenter/conn-degraded.svg)
   skin/classic/browser/controlcenter/mcb-disabled.svg  (../shared/controlcenter/mcb-disabled.svg)
   skin/classic/browser/controlcenter/permissions.svg  (../shared/controlcenter/permissions.svg)
   skin/classic/browser/controlcenter/tracking-protection.svg                 (../shared/controlcenter/tracking-protection.svg)
   skin/classic/browser/controlcenter/tracking-protection-disabled.svg        (../shared/controlcenter/tracking-protection-disabled.svg)
   skin/classic/browser/customizableui/background-noise-toolbar.png  (customizableui/background-noise-toolbar.png)
   skin/classic/browser/customizableui/customize-illustration.png  (../shared/customizableui/customize-illustration.png)
   skin/classic/browser/customizableui/customize-illustration-rtl.png  (../shared/customizableui/customize-illustration-rtl.png)
   skin/classic/browser/customizableui/customizeMode-gridTexture.png  (customizableui/customizeMode-gridTexture.png)
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -184,16 +184,17 @@ browser.jar:
   skin/classic/browser/yosemite/loop/menuPanel.png          (loop/menuPanel-yosemite.png)
   skin/classic/browser/yosemite/loop/menuPanel@2x.png       (loop/menuPanel-yosemite@2x.png)
   skin/classic/browser/yosemite/loop/toolbar.png            (loop/toolbar-yosemite.png)
   skin/classic/browser/yosemite/loop/toolbar@2x.png         (loop/toolbar-yosemite@2x.png)
 * skin/classic/browser/controlcenter/panel.css        (controlcenter/panel.css)
   skin/classic/browser/controlcenter/arrow-subview.svg  (../shared/controlcenter/arrow-subview.svg)
   skin/classic/browser/controlcenter/conn-not-secure.svg  (../shared/controlcenter/conn-not-secure.svg)
   skin/classic/browser/controlcenter/conn-secure.svg  (../shared/controlcenter/conn-secure.svg)
+  skin/classic/browser/controlcenter/conn-degraded.svg  (../shared/controlcenter/conn-degraded.svg)
   skin/classic/browser/controlcenter/mcb-disabled.svg  (../shared/controlcenter/mcb-disabled.svg)
   skin/classic/browser/controlcenter/permissions.svg  (../shared/controlcenter/permissions.svg)
   skin/classic/browser/controlcenter/tracking-protection.svg                 (../shared/controlcenter/tracking-protection.svg)
   skin/classic/browser/controlcenter/tracking-protection-disabled.svg        (../shared/controlcenter/tracking-protection-disabled.svg)
   skin/classic/browser/customizableui/background-noise-toolbar.png  (customizableui/background-noise-toolbar.png)
   skin/classic/browser/customizableui/customize-titleBar-toggle.png  (customizableui/customize-titleBar-toggle.png)
   skin/classic/browser/customizableui/customize-titleBar-toggle@2x.png  (customizableui/customize-titleBar-toggle@2x.png)
   skin/classic/browser/customizableui/customize-illustration.png  (../shared/customizableui/customize-illustration.png)
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/controlcenter/conn-degraded.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+     width="24" height="24" viewBox="0 0 24 24">
+  <style>
+    .icon-default {
+      fill: #808080;
+    }
+  </style>
+
+  <defs>
+    <rect id="shape-lock-clasp-outer" x="5" y="1" width="14" height="20" rx="7" ry="7" />
+    <rect id="shape-lock-clasp-inner" x="8" y="4" width="8" height="14" rx="4" ry="4" />
+    <rect id="shape-lock-base" x="3" y="10" width="18" height="13" rx="1.5" ry="1.5" />
+
+    <mask id="mask-clasp-cutout">
+      <rect width="24" height="24" fill="#000" />
+      <use xlink:href="#shape-lock-clasp-outer" fill="#fff" />
+      <use xlink:href="#shape-lock-clasp-inner" fill="#000" />
+    </mask>
+  </defs>
+
+  <use xlink:href="#shape-lock-clasp-outer" mask="url(#mask-clasp-cutout)" class="icon-default" />
+  <use xlink:href="#shape-lock-base" class="icon-default" />
+</svg>
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -218,16 +218,25 @@
 
 #identity-popup-securityView.verifiedDomain,
 #identity-popup-securityView.verifiedIdentity,
 #identity-popup-security-content.verifiedDomain,
 #identity-popup-security-content.verifiedIdentity {
   background-image: url(chrome://browser/skin/controlcenter/conn-secure.svg);
 }
 
+#identity-popup-securityView.weakCipher,
+#identity-popup-securityView.mixedDisplayContent,
+#identity-popup-securityView.mixedDisplayContentLoadedActiveBlocked,
+#identity-popup-security-content.weakCipher,
+#identity-popup-security-content.mixedDisplayContent,
+#identity-popup-security-content.mixedDisplayContentLoadedActiveBlocked {
+  background-image: url(chrome://browser/skin/controlcenter/conn-degraded.svg);
+}
+
 #identity-popup-securityView.mixedActiveContent,
 #identity-popup-security-content.mixedActiveContent {
   background-image: url(chrome://browser/skin/controlcenter/mcb-disabled.svg);
 }
 
 #identity-popup-securityView-header {
   border-bottom: 1px solid #e5e5e5;
   padding-bottom: 1em;
@@ -253,23 +262,27 @@
   background-image: url("chrome://browser/skin/controlcenter/tracking-protection.svg");
 }
 
 #tracking-protection-content[state="loaded-tracking-content"]  {
   background-image: url("chrome://browser/skin/controlcenter/tracking-protection-disabled.svg");
 }
 
 #tracking-action-block,
-#tracking-action-unblock {
+#tracking-action-unblock,
+#tracking-action-unblock-private {
   margin: 1em 0 0;
 }
 
 #tracking-protection-content[state] > #tracking-not-detected,
 #tracking-protection-content:not([state="blocked-tracking-content"]) > #tracking-blocked,
+#main-window[privatebrowsingmode] #tracking-action-unblock,
+#main-window:not([privatebrowsingmode]) #tracking-action-unblock-private,
 #tracking-protection-content:not([state="blocked-tracking-content"]) #tracking-action-unblock,
+#tracking-protection-content:not([state="blocked-tracking-content"]) #tracking-action-unblock-private,
 #tracking-protection-content:not([state="loaded-tracking-content"]) > #tracking-loaded,
 #tracking-protection-content:not([state="loaded-tracking-content"]) #tracking-action-block,
 #tracking-protection-content:not([state]) > #tracking-actions {
   display: none;
 }
 
 /* PERMISSIONS */
 
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -397,10 +397,10 @@ description > html|a {
 }
 
 #fxaSyncComputerName.plain {
   background-color: transparent;
   opacity: 1;
 }
 
 #tosPP-small-ToS {
-  margin-right: 3em;
+  margin-bottom: 1em;
 }
--- a/browser/themes/windows/browser-aero.css
+++ b/browser/themes/windows/browser-aero.css
@@ -81,64 +81,210 @@
     #urlbar:not(:-moz-lwtheme)[focused],
     .searchbar-textbox:not(:-moz-lwtheme)[focused] {
       border-color: hsla(206,100%,60%,.65) hsla(206,100%,55%,.65) hsla(206,100%,50%,.65);
     }
   }
 }
 
 @media (-moz-windows-compositor) {
-  /* These should be hidden w/ glass enabled. Windows draws its own buttons. */
-  .titlebar-button {
-    display: none;
+  #main-window {
+    -moz-appearance: -moz-win-glass;
   }
 
-  #main-window[sizemode="maximized"] #titlebar-buttonbox {
-    -moz-margin-end: 3px;
-  }
-
-  #main-window {
-    -moz-appearance: -moz-win-glass;
-    background: transparent;
-  }
 
   /* On win10, if we don't set this on the entire browser container including
    * the sidebar, if the sidebar is open the accent color bleeds through in
    * the titlebar */
   #browser {
     -moz-appearance: -moz-win-exclude-glass;
   }
 
+  @media not all and (-moz-os-version: windows-vista) {
+    @media not all and (-moz-os-version: windows-win7) {
+      @media not all and (-moz-os-version: windows-win8) {
+        @media (-moz-windows-default-theme) {
+          #main-window {
+            background-color: hsl(0, 0%, 78%);
+          }
+        }
+
+        #titlebar-buttonbox,
+        .titlebar-button {
+          -moz-appearance: none !important;
+        }
+
+        .titlebar-button {
+          border: none;
+          margin: 0 !important;
+          padding: 12px 17px;
+        }
+
+        #main-window[sizemode=maximized] .titlebar-button {
+          padding-top: 8px;
+          padding-bottom: 8px;
+        }
+
+        .titlebar-button > .toolbarbutton-icon {
+          width: 12px;
+          height: 12px;
+        }
+
+        #titlebar-min {
+          list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize);
+        }
+
+        #titlebar-max {
+          list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize);
+        }
+
+        #main-window[sizemode="maximized"] #titlebar-max {
+          list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore);
+        }
+
+        #titlebar-close {
+          list-style-image: url(chrome://browser/skin/caption-buttons.svg#close);
+        }
+        #titlebar-close:hover {
+          list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-highlight);
+        }
+
+        /* the 12px image renders a 10px icon, and the 10px upscaled gets rounded to 12.5, which
+         * rounds up to 13px, which makes the icon one pixel too big on 1.25dppx. Fix: */
+        @media (min-resolution: 1.20dppx) and (max-resolution: 1.45dppx) {
+          .titlebar-button > .toolbarbutton-icon {
+            width: 11.5px;
+            height: 11.5px;
+          }
+        }
+
+        /* 175% dpi should result in the same device pixel sizes as 150% dpi. */
+        @media (min-resolution: 1.70dppx) and (max-resolution: 1.95dppx) {
+          .titlebar-button {
+            padding-left: 14.1px;
+            padding-right: 14.1px;
+          }
+
+          .titlebar-button > .toolbarbutton-icon {
+            width: 10.8px;
+            height: 10.8px;
+          }
+        }
+
+        /* 225% dpi should result in the same device pixel sizes as 200% dpi. */
+        @media (min-resolution: 2.20dppx) and (max-resolution: 2.45dppx) {
+          .titlebar-button {
+            padding-left: 15.3333px;
+            padding-right: 15.3333px;
+          }
+
+          .titlebar-button > .toolbarbutton-icon {
+            width: 10.8px;
+            height: 10.8px;
+          }
+        }
+
+        /* 275% dpi should result in the same device pixel sizes as 250% dpi. */
+        @media (min-resolution: 2.70dppx) and (max-resolution: 2.95dppx) {
+          /* NB: todo: this should also change padding on the buttons
+           * themselves, but without a device to test this on, it's
+           * impossible to know by how much. */
+          .titlebar-button > .toolbarbutton-icon {
+            width: 10.8px;
+            height: 10.8px;
+          }
+        }
+
+        @media (-moz-windows-default-theme) {
+          .titlebar-button:hover {
+            background-color: hsla(0, 0%, 0%, .12);
+          }
+
+          .titlebar-button:hover:active {
+            background-color: hsla(0, 0%, 0%, .22);
+          }
+
+          .titlebar-button:not(:hover) > .toolbarbutton-icon:-moz-window-inactive {
+            opacity: 0.5;
+          }
+
+          #titlebar-close:hover {
+            background-color: hsl(355, 86%, 49%);
+          }
+
+          #titlebar-close:hover:active {
+            background-color: hsl(355, 82%, 69%);
+          }
+        }
+        @media not all and (-moz-windows-default-theme) {
+          .titlebar-button {
+            background-color: -moz-field;
+          }
+          .titlebar-button:hover {
+            background-color: Highlight;
+          }
+
+          #titlebar-min:hover {
+            list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize-highlight);
+          }
+
+          #titlebar-max:hover {
+            list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize-highlight);
+          }
+
+          #main-window[sizemode="maximized"] #titlebar-max:hover {
+            list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore-highlight);
+          }
+
+          #titlebar-close:hover {
+            list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-highlight);
+          }
+        }
+      }
+    }
+  }
+
   @media (-moz-os-version: windows-vista),
-         (-moz-os-version: windows-win7) {
+         (-moz-os-version: windows-win7),
+         (-moz-os-version: windows-win8) {
+    #main-window[sizemode="maximized"] #titlebar-buttonbox {
+      -moz-margin-end: 3px;
+    }
+
     #main-window {
+      background-color: transparent;
       -moz-appearance: -moz-win-borderless-glass;
     }
 
+    /* These should be hidden w/ glass enabled. Windows draws its own buttons. */
+    .titlebar-button {
+      display: none;
+    }
+
     /* The borders on the glass frame are ours, and inside #browser, and on
      * vista and win7 we want to make sure they are "glassy", so we can't use
      * #browser as the exclude-glass container. We use #appcontent instead. */
     #browser {
       -moz-appearance: none;
     }
 
     #appcontent {
       -moz-appearance: -moz-win-exclude-glass;
     }
-  }
-
 
-  /* Artificially draw window borders that are covered by lwtheme, see bug 591930. */
-  #main-window[sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
-    border-top: 2px solid;
-    -moz-border-top-colors: @glassActiveBorderColor@ rgba(255,255,255,.6);
-  }
+    /* Artificially draw window borders that are covered by lwtheme, see bug 591930.
+     * Not necessary on windows 10+ */
+    #main-window[sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
+      border-top: 2px solid;
+      -moz-border-top-colors: @glassActiveBorderColor@ rgba(255,255,255,.6);
+    }
 
-  #main-window[sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
-    -moz-border-top-colors: @glassInactiveBorderColor@ rgba(255,255,255,.6);
+    #main-window[sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
+      -moz-border-top-colors: @glassInactiveBorderColor@ rgba(255,255,255,.6);
+    }
   }
 
   @media (-moz-windows-default-theme) {
     #toolbar-menubar:not(:-moz-lwtheme),
     #TabsToolbar:not(:-moz-lwtheme) {
       color: black;
     }
 
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -13,16 +13,18 @@
 %filter substitution
 %define toolbarShadowColor hsla(209,67%,12%,0.35)
 %define navbarTextboxCustomBorder border-color: rgba(0,0,0,.32);
 %define forwardTransitionLength 150ms
 %define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper
 %define conditionalForwardWithUrlbarWidth 30
 
 :root {
+  --space-above-tabbar: 15px;
+
   --toolbarbutton-vertical-inner-padding: 2px;
   --toolbarbutton-vertical-outer-padding: 8px;
 
   --toolbarbutton-hover-background: hsla(210,4%,10%,.08);
   --toolbarbutton-hover-bordercolor: hsla(210,4%,10%,.1);
   --toolbarbutton-hover-boxshadow: none;
 
   --toolbarbutton-active-background: hsla(210,4%,10%,.12);
@@ -65,17 +67,17 @@
    of by the (light) outer shadow of the tab, the remaining 3/15 are these margins. */
 #toolbar-menubar:not([moz-collapsed=true]):not([autohide=true]) ~ #TabsToolbar,
 #toolbar-menubar:not([moz-collapsed=true])[autohide=true]:not([inactive]) ~ #TabsToolbar {
   margin-top: 3px;
 }
 
 #main-window[tabsintitlebar][sizemode="normal"]:not([inFullscreen])[chromehidden~="menubar"] #toolbar-menubar ~ #TabsToolbar,
 #main-window[tabsintitlebar][sizemode="normal"]:not([inFullscreen]) #toolbar-menubar[autohide="true"][inactive] ~ #TabsToolbar {
-  margin-top: 15px;
+  margin-top: var(--space-above-tabbar);
 }
 
 #toolbar-menubar:not([autohide="true"]) {
   -moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar-drag");
 }
 
 #main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #toolbar-menubar[customizing-dragovertarget].customization-target::before,
 #main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #TabsToolbar[customizing-dragovertarget].customization-target::before,
new file mode 100644
--- /dev/null
+++ b/browser/themes/windows/caption-buttons.svg
@@ -0,0 +1,46 @@
+<svg width="12" height="12" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<!-- 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/. -->
+  <style>
+    g {
+      stroke: ButtonText;
+      stroke-width: 0.9px;
+      fill: none;
+    }
+
+    g:not(#close) {
+      shape-rendering: crispEdges;
+    }
+
+    g:not(:target) {
+      display: none;
+    }
+
+    use:target > g {
+      display: initial;
+    }
+
+    .highlight > g {
+      stroke: HighlightText;
+    }
+  </style>
+  <g id="close">
+    <line x1="1" y1="1" x2="11" y2="11"/>
+    <line x1="11" y1="1" x2="1" y2="11"/>
+  </g>
+  <g id="maximize">
+    <rect x="1.5" y="1.5" width="9" height="9"/>
+  </g>
+  <g id="minimize">
+    <line x1="1" y1="5.5" x2="11" y2="5.5"/>
+  </g>
+  <g id="restore">
+    <rect x="1.5" y="3.5" width="7" height="7"/>
+    <polyline points="3.5,3.5 3.5,1.5 10.5,1.5 10.5,8.5 8.5,8.5"/>
+  </g>
+  <use id="close-highlight" class="highlight" xlink:href="#close"/>
+  <use id="maximize-highlight" class="highlight" xlink:href="#maximize"/>
+  <use id="minimize-highlight" class="highlight" xlink:href="#minimize"/>
+  <use id="restore-highlight" class="highlight" xlink:href="#restore"/>
+</svg>
--- a/browser/themes/windows/devedition.css
+++ b/browser/themes/windows/devedition.css
@@ -87,141 +87,157 @@
   padding-top: 2px;
   padding-bottom: 2px;
 }
 
 .tabbrowser-tab {
   background-color: var(--tab-background-color);
 }
 
-/* It'd be nice if there was an element in the scrollbox's inner content
-   that collapsed to the current width of the tabs. Since there isn't we
-   need to handle overflowing and non-overflowing tabs separately.
-
-   In the case of overflowing tabs, set a border-top on the entire container,
-   otherwise we need to set it on each element individually */
-#main-window[sizemode=normal] .tabbrowser-tabs[overflow="true"] {
-  background-clip: padding-box;
-  border-top: 1px solid var(--chrome-nav-bar-separator-color);
-  -moz-border-end: 1px solid var(--chrome-nav-bar-separator-color);
-  background-color: var(--tab-background-color); /* Make sure there is no transparent gap during tab close animation */
-}
-
-/* Add a border to the left of the first tab (or scroll arrow).  Using .tabbrowser-tabs
-   instead of #TabsToolbar because it will work even in customize mode. */
-#main-window[sizemode=normal] .tabbrowser-tabs {
-  background-clip: padding-box;
-  -moz-border-start: 1px solid var(--chrome-nav-bar-separator-color);
-  -moz-border-end: 1px solid transparent;
-}
-
-#main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-tab,
-#main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-arrowscrollbox > .scrollbutton-down,
-#main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-arrowscrollbox > .scrollbutton-up,
-#main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabs-newtab-button {
-  background-clip: padding-box;
-  border-top: 1px solid var(--chrome-nav-bar-separator-color);
-}
-
-/* Allow the border-top rule to take effect */
-#main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-tab {
-  -moz-border-top-colors: none;
-}
-
-#main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .closing-tabs-spacer {
-  background-clip: padding-box;
-  -moz-border-start: 1px solid var(--chrome-nav-bar-separator-color);
-}
-
-.tabs-newtab-button {
-  background: var(--tab-background-color);
-}
-
-/* Use default window colors when in non-maximized mode */
-#tabbrowser-tabs,
-#TabsToolbar,
-#browser-panel,
-#titlebar-content {
-  background: transparent;
-}
-
-/* Ensure that the entire background is styled when maximized */
-#main-window[sizemode="maximized"]:not([customizing]) #browser-panel {
-  background: var(--chrome-background-color) !important;
-}
-
-/* The menu items need to be visible when the entire background is styled */
-#main-window[sizemode="maximized"] #main-menubar {
-  color: var(--chrome-color);
-  background-color: transparent;
-}
-
-#main-window[sizemode="maximized"] #main-menubar > menu:not(:-moz-window-inactive) {
-  color: inherit;
-}
-
-/* Use proper menu text styling in Win7 classic mode (copied from browser.css) */
-@media not all and (-moz-windows-compositor),
-       not all and (-moz-windows-default-theme) {
-  #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar,
-  #main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar {
-    color: CaptionText;
-  }
-
-  #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar:-moz-window-inactive,
-  #main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar:-moz-window-inactive {
-    color: InactiveCaptionText;
-  }
-
-  #main-window[tabsintitlebar] #main-menubar > menu {
-    color: inherit;
-  }
-}
-
-/* Use less opacity than normal since this is very dark, and on top of the default toolbar color */
-.tabbrowser-arrowscrollbox > .scrollbutton-up[disabled],
-.tabbrowser-arrowscrollbox > .scrollbutton-down[disabled] {
-  opacity: .6;
-}
-
-/* Override scrollbutton gradients in normal and hover state */
-.tabbrowser-arrowscrollbox > .scrollbutton-down,
-.tabbrowser-arrowscrollbox > .scrollbutton-up {
-  background-image: none !important;
-  transition: none; /* scrollbutton-down has an unwanted transition on background color */
-}
-
-/* Restore draggable space on the sides of tabs when maximized */
-#main-window[sizemode="maximized"] .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox {
-  padding-left: 15px;
-  padding-right: 15px;
-}
-
 #toolbar-menubar {
   text-shadow: none !important;
 }
 
-/* Override the padding that's intended to compensate for tabs that can overlap border-radius on nav-bar in default theme. */
-#main-window[sizemode=normal]:not([customizing]) #TabsToolbar {
-  padding-left: 0;
-  padding-right: 0;
-}
-
 /* This rule is specific to the dark theme, because we only set the dropdown image there */
 :root[devtoolstheme="dark"] .searchbar-dropmarker-image {
   /* Reset image-region from the windows theme */
   -moz-image-region: auto !important;
   /* Add margin otherwise it looks weird */
   -moz-margin-start: 2px;
 }
 
 /* Tab styling - make sure to use an inverted icon for the selected tab
    (brighttext only covers the unselected tabs) */
 .tab-close-button[visuallyselected=true]:not(:hover) {
   -moz-image-region: rect(0, 64px, 16px, 48px);
 }
 
 @media (min-resolution: 1.1dppx) {
   .tab-close-button[visuallyselected=true]:not(:hover) {
-    -moz-image-region: rect(0px, 128px, 32px, 96px);
+    -moz-image-region: rect(0, 128px, 32px, 96px);
   }
 }
 
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7),
+       (-moz-os-version: windows-win8) {
+  :root {
+    --space-above-tabbar: 15px;
+  }
+
+  /* It'd be nice if there was an element in the scrollbox's inner content
+     that collapsed to the current width of the tabs. Since there isn't we
+     need to handle overflowing and non-overflowing tabs separately.
+
+     In the case of overflowing tabs, set a border-top on the entire container,
+     otherwise we need to set it on each element individually */
+  #main-window[sizemode=normal] .tabbrowser-tabs[overflow="true"] {
+    background-clip: padding-box;
+    border-top: 1px solid var(--chrome-nav-bar-separator-color);
+    -moz-border-end: 1px solid var(--chrome-nav-bar-separator-color);
+    background-color: var(--tab-background-color); /* Make sure there is no transparent gap during tab close animation */
+  }
+
+  /* Add a border to the left of the first tab (or scroll arrow).  Using .tabbrowser-tabs
+     instead of #TabsToolbar because it will work even in customize mode. */
+  #main-window[sizemode=normal] .tabbrowser-tabs {
+    background-clip: padding-box;
+    -moz-border-start: 1px solid var(--chrome-nav-bar-separator-color);
+    -moz-border-end: 1px solid transparent;
+  }
+
+  #main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-tab,
+  #main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-arrowscrollbox > .scrollbutton-down,
+  #main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-arrowscrollbox > .scrollbutton-up,
+  #main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabs-newtab-button {
+    background-clip: padding-box;
+    border-top: 1px solid var(--chrome-nav-bar-separator-color);
+  }
+
+  /* Allow the border-top rule to take effect */
+  #main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .tabbrowser-tab {
+    -moz-border-top-colors: none;
+  }
+
+  #main-window[sizemode=normal] .tabbrowser-tabs:not([overflow="true"]) .closing-tabs-spacer {
+    background-clip: padding-box;
+    -moz-border-start: 1px solid var(--chrome-nav-bar-separator-color);
+  }
+
+  .tabs-newtab-button {
+    background: var(--tab-background-color);
+  }
+
+  /* Use default window colors when in non-maximized mode */
+  #tabbrowser-tabs,
+  #TabsToolbar,
+  #browser-panel,
+  #titlebar-content {
+    background: transparent;
+  }
+
+  /* Ensure that the entire background is styled when maximized */
+  #main-window[sizemode="maximized"]:not([customizing]) #browser-panel {
+    background: var(--chrome-background-color) !important;
+  }
+
+  /* The menu items need to be visible when the entire background is styled */
+  #main-window[sizemode="maximized"] #main-menubar {
+    color: var(--chrome-color);
+    background-color: transparent;
+  }
+
+  #main-window[sizemode="maximized"] #main-menubar > menu:not(:-moz-window-inactive) {
+    color: inherit;
+  }
+
+  /* Use proper menu text styling in Win7 classic mode (copied from browser.css) */
+  @media not all and (-moz-windows-compositor),
+         not all and (-moz-windows-default-theme) {
+    #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar,
+    #main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar {
+      color: CaptionText;
+    }
+
+    #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar:-moz-window-inactive,
+    #main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar:-moz-window-inactive {
+      color: InactiveCaptionText;
+    }
+
+    #main-window[tabsintitlebar] #main-menubar > menu {
+      color: inherit;
+    }
+  }
+
+  /* Use less opacity than normal since this is very dark, and on top of the default toolbar color */
+  .tabbrowser-arrowscrollbox > .scrollbutton-up[disabled],
+  .tabbrowser-arrowscrollbox > .scrollbutton-down[disabled] {
+    opacity: .6;
+  }
+
+  /* Override scrollbutton gradients in normal and hover state */
+  .tabbrowser-arrowscrollbox > .scrollbutton-down,
+  .tabbrowser-arrowscrollbox > .scrollbutton-up {
+    background-image: none !important;
+    transition: none; /* scrollbutton-down has an unwanted transition on background color */
+  }
+
+  /* Restore draggable space on the sides of tabs when maximized */
+  #main-window[sizemode="maximized"] .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox {
+    padding-left: 15px;
+    padding-right: 15px;
+  }
+
+  /* Override the padding that's intended to compensate for tabs that can overlap border-radius on nav-bar in default theme. */
+  #main-window[sizemode=normal]:not([customizing]) #TabsToolbar {
+    padding-left: 0;
+    padding-right: 0;
+  }
+}
+
+@media (-moz-os-version: windows-win10) {
+  /* Always keep draggable space on the sides of tabs since there is no top margin on Win10 */
+  #main-window .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox {
+    padding-left: 15px;
+    padding-right: 15px;
+  }
+}
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -28,16 +28,17 @@ browser.jar:
         skin/classic/browser/addons/addon-install-error.svg          (../shared/addons/addon-install-error.svg)
         skin/classic/browser/addons/addon-install-installed.svg      (../shared/addons/addon-install-installed.svg)
         skin/classic/browser/addons/addon-install-restart.svg        (../shared/addons/addon-install-restart.svg)
         skin/classic/browser/addons/addon-install-warning.svg        (../shared/addons/addon-install-warning.svg)
         skin/classic/browser/addons/addon-install-anchor.svg         (../shared/addons/addon-install-anchor.svg)
 *       skin/classic/browser/browser.css
 *       skin/classic/browser/devedition.css
 *       skin/classic/browser/browser-lightweightTheme.css
+        skin/classic/browser/caption-buttons.svg
         skin/classic/browser/click-to-play-warning-stripes.png
         skin/classic/browser/content-contextmenu.svg
         skin/classic/browser/drm-icon.svg                            (../shared/drm-icon.svg)
 *       skin/classic/browser/engineManager.css
         skin/classic/browser/fullscreen-darknoise.png
         skin/classic/browser/Geolocation-16.png
         skin/classic/browser/Geolocation-64.png
         skin/classic/browser/Push-16.png
@@ -188,16 +189,17 @@ browser.jar:
         skin/classic/browser/loop/toolbar-lunaSilver@2x.png          (loop/toolbar-lunaSilver@2x.png)
         skin/classic/browser/loop/toolbar-win8.png                   (loop/toolbar-win8.png)
         skin/classic/browser/loop/toolbar-win8@2x.png                (loop/toolbar-win8@2x.png)
         skin/classic/browser/loop/toolbar-XP.png                     (loop/toolbar-XP.png)
         skin/classic/browser/loop/toolbar-XP@2x.png                  (loop/toolbar-XP@2x.png)
 *       skin/classic/browser/controlcenter/panel.css                 (controlcenter/panel.css)
         skin/classic/browser/controlcenter/arrow-subview.svg  (../shared/controlcenter/arrow-subview.svg)
         skin/classic/browser/controlcenter/conn-not-secure.svg  (../shared/controlcenter/conn-not-secure.svg)
+        skin/classic/browser/controlcenter/conn-degraded.svg  (../shared/controlcenter/conn-degraded.svg)
         skin/classic/browser/controlcenter/conn-secure.svg  (../shared/controlcenter/conn-secure.svg)
         skin/classic/browser/controlcenter/mcb-disabled.svg  (../shared/controlcenter/mcb-disabled.svg)
         skin/classic/browser/controlcenter/permissions.svg  (../shared/controlcenter/permissions.svg)
         skin/classic/browser/controlcenter/tracking-protection.svg                 (../shared/controlcenter/tracking-protection.svg)
         skin/classic/browser/controlcenter/tracking-protection-disabled.svg        (../shared/controlcenter/tracking-protection-disabled.svg)
         skin/classic/browser/customizableui/background-noise-toolbar.png  (customizableui/background-noise-toolbar.png)
         skin/classic/browser/customizableui/customizeFavicon.ico  (../shared/customizableui/customizeFavicon.ico)
         skin/classic/browser/customizableui/customize-illustration.png  (../shared/customizableui/customize-illustration.png)
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -228,17 +228,17 @@ def bootstrap(topsrcdir, mozilla_dir=Non
 
         Currently, our goal is to ensure developers periodically run
         `mach mercurial-setup` (when applicable) to ensure their Mercurial
         tools are up to date.
         """
         # Don't do anything when...
 
         # The user is performing a maintenance command.
-        if handler.name in ('bootstrap', 'doctor', 'mercurial-setup'):
+        if handler.name in ('bootstrap', 'doctor', 'mach-commands', 'mercurial-setup'):
             return
 
         # We are running in automation.
         if 'MOZ_AUTOMATION' in os.environ or 'TASK_ID' in os.environ:
             return
 
         # We are a curmudgeon who has found this undocumented variable.
         if 'I_PREFER_A_SUBOPTIMAL_MERCURIAL_EXPERIENCE' in os.environ:
--- a/build/mobile/robocop/FennecNativeActions.java
+++ b/build/mobile/robocop/FennecNativeActions.java
@@ -18,17 +18,17 @@ import org.mozilla.gecko.util.GeckoEvent
 
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.database.Cursor;
 import android.os.SystemClock;
 import android.text.TextUtils;
 import android.view.KeyEvent;
 
-import com.robotium.solo.Solo;
+import com.jayway.android.robotium.solo.Solo;
 
 public class FennecNativeActions implements Actions {
     private static final String LOGTAG = "FennecNativeActions";
 
     private Solo mSolo;
     private Instrumentation mInstr;
     private Assert mAsserter;
 
@@ -362,17 +362,17 @@ public class FennecNativeActions impleme
                 break;
         }
     }
 
     public void sendKeyCode(int keyCode) {
         if (keyCode <= 0 || keyCode > KeyEvent.getMaxKeyCode()) {
             mAsserter.ok(false, "sendKeyCode", "Unknown keyCode " + keyCode);
         }
-        mSolo.sendKey(keyCode);
+        mInstr.sendCharacterSync(keyCode);
     }
 
     @Override
     public void sendKeys(String input) {
         mInstr.sendStringSync(input);
     }
 
     public void drag(int startingX, int endingX, int startingY, int endingY) {
--- a/build/mobile/robocop/FennecNativeDriver.java
+++ b/build/mobile/robocop/FennecNativeDriver.java
@@ -23,17 +23,17 @@ import org.json.JSONObject;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.gfx.PanningPerfAPI;
 import org.mozilla.gecko.util.GeckoEventListener;
 
 import android.app.Activity;
 import android.util.Log;
 import android.view.View;
 
-import com.robotium.solo.Solo;
+import com.jayway.android.robotium.solo.Solo;
 
 public class FennecNativeDriver implements Driver {
     private static final int FRAME_TIME_THRESHOLD = 25;     // allow 25ms per frame (40fps)
 
     private final Activity mActivity;
     private final Solo mSolo;
     private final String mRootPath;
 
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -3,17 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 mobile-tests := mobile/android/tests/browser/robocop
 TESTPATH     := $(topsrcdir)/$(mobile-tests)
 
 ANDROID_APK_NAME := robocop-debug
 
 ANDROID_EXTRA_JARS += \
-  $(srcdir)/robotium-solo-5.4.1.jar \
+  $(srcdir)/robotium-solo-4.3.1.jar \
   $(NULL)
 
 ANDROID_ASSETS_DIR := $(TESTPATH)/assets
 
 _JAVA_HARNESS := \
   Actions.java \
   Assert.java \
   Driver.java \
new file mode 100644
index 0000000000000000000000000000000000000000..56af9985f6eef8ed1d4dddcc060fb51923b24f3f
GIT binary patch
literal 106789
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
DW4v<m
deleted file mode 100644
index ea2cc7377c2212a27a88920f58467d1843bf5bbb..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
--- a/dom/presentation/provider/PresentationDeviceProviderModule.cpp
+++ b/dom/presentation/provider/PresentationDeviceProviderModule.cpp
@@ -23,18 +23,18 @@ static const mozilla::Module::CIDEntry k
 };
 
 static const mozilla::Module::ContractIDEntry kPresentationDeviceProviderContracts[] = {
   { MULTICAST_DNS_PROVIDER_CONTRACT_ID, &kMULTICAST_DNS_PROVIDER_CID },
   { nullptr }
 };
 
 static const mozilla::Module::CategoryEntry kPresentationDeviceProviderCategories[] = {
-#if 0 // defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 16
-  { PRESENTATION_DEVICE_PROVIDER_CATEGORY, "MulticastDNSDeviceProvider", MULTICAST_DNS_PROVIDER_CONTRACT_ID},
+#if defined(MOZ_WIDGET_ANDROID) // || (defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 16)
+  { PRESENTATION_DEVICE_PROVIDER_CATEGORY, "MulticastDNSDeviceProvider", MULTICAST_DNS_PROVIDER_CONTRACT_ID },
 #endif
   { nullptr }
 };
 
 static const mozilla::Module kPresentationDeviceProviderModule = {
   mozilla::Module::kVersion,
   kPresentationDeviceProviderCIDs,
   kPresentationDeviceProviderContracts,
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -114,17 +114,17 @@ SystemWorkerManager::Shutdown()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   mShutdown = true;
 
   ShutdownAutoMounter();
 
 #ifdef MOZ_B2G_RIL
-  RilConsumer::Shutdown();
+  RilWorker::Shutdown();
 #endif
 
   nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
   if (wifi) {
     wifi->Shutdown();
     wifi = nullptr;
   }
   mWifiWorker = nullptr;
@@ -196,17 +196,17 @@ SystemWorkerManager::RegisterRilWorker(u
 
   WorkerCrossThreadDispatcher *wctd =
     GetWorkerCrossThreadDispatcher(aCx, aWorker);
   if (!wctd) {
     NS_WARNING("Failed to GetWorkerCrossThreadDispatcher for ril");
     return NS_ERROR_FAILURE;
   }
 
-  return RilConsumer::Register(aClientId, wctd);
+  return RilWorker::Register(aClientId, wctd);
 #endif // MOZ_B2G_RIL
 }
 
 nsresult
 SystemWorkerManager::InitWifi(JSContext *cx)
 {
   nsCOMPtr<nsIWorkerHolder> worker = do_CreateInstance(kWifiWorkerCID);
   NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -2971,161 +2971,16 @@ CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BA
 CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL] = ICC_CB_FACILITY_BAOIC;
 CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME] = ICC_CB_FACILITY_BAOICxH;
 CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_INCOMING] = ICC_CB_FACILITY_BAIC;
 CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_INCOMING_ROAMING] = ICC_CB_FACILITY_BAICr;
 CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_SERVICE] = ICC_CB_FACILITY_BA_ALL;
 CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_SERVICE] = ICC_CB_FACILITY_BA_MO;
 CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_INCOMING_SERVICE] = ICC_CB_FACILITY_BA_MT;
 
-// CLIR constants. Must be in sync with nsIMobileConnectionService interface
-this.CLIR_DEFAULT = 0;
-this.CLIR_INVOCATION  = 1;
-this.CLIR_SUPPRESSION = 2;
-
-// MMI procedure as defined in TS.22.030 6.5.2
-this.MMI_PROCEDURE_ACTIVATION = "*";
-this.MMI_PROCEDURE_DEACTIVATION = "#";
-this.MMI_PROCEDURE_INTERROGATION = "*#";
-this.MMI_PROCEDURE_REGISTRATION = "**";
-this.MMI_PROCEDURE_ERASURE = "##";
-
-this.MMI_PROC_TO_CF_ACTION = {};
-MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_ACTIVATION] = CALL_FORWARD_ACTION_ENABLE;
-MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_DEACTIVATION] = CALL_FORWARD_ACTION_DISABLE;
-MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_INTERROGATION] = CALL_FORWARD_ACTION_QUERY_STATUS;
-MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_REGISTRATION] = CALL_FORWARD_ACTION_REGISTRATION;
-MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_ERASURE] = CALL_FORWARD_ACTION_ERASURE;
-
-// MMI call forwarding service codes as defined in TS.22.030 Annex B
-this.MMI_SC_CFU = "21";
-this.MMI_SC_CF_BUSY = "67";
-this.MMI_SC_CF_NO_REPLY = "61";
-this.MMI_SC_CF_NOT_REACHABLE = "62";
-this.MMI_SC_CF_ALL = "002";
-this.MMI_SC_CF_ALL_CONDITIONAL = "004";
-
-this.MMI_SC_TO_CF_REASON = {};
-MMI_SC_TO_CF_REASON[MMI_SC_CFU] = CALL_FORWARD_REASON_UNCONDITIONAL;
-MMI_SC_TO_CF_REASON[MMI_SC_CF_BUSY] = CALL_FORWARD_REASON_MOBILE_BUSY;
-MMI_SC_TO_CF_REASON[MMI_SC_CF_NO_REPLY] = CALL_FORWARD_REASON_NO_REPLY;
-MMI_SC_TO_CF_REASON[MMI_SC_CF_NOT_REACHABLE] = CALL_FORWARD_REASON_NOT_REACHABLE;
-MMI_SC_TO_CF_REASON[MMI_SC_CF_ALL] = CALL_FORWARD_REASON_ALL_CALL_FORWARDING;
-MMI_SC_TO_CF_REASON[MMI_SC_CF_ALL_CONDITIONAL] = CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING;
-
-// MMI service codes for PIN/PIN2/PUK/PUK2 management as defined in TS.22.030
-// sec 6.6
-this.MMI_SC_PIN = "04";
-this.MMI_SC_PIN2 = "042";
-this.MMI_SC_PUK = "05";
-this.MMI_SC_PUK2 = "052";
-
-// MMI service code for IMEI presentation as defined in TS.22.030 sec 6.7
-this.MMI_SC_IMEI = "06";
-
-// MMI called line presentation service codes
-this.MMI_SC_CLIP = "30";
-this.MMI_SC_CLIR = "31";
-
-// MMI call waiting service code
-this.MMI_SC_CALL_WAITING = "43";
-
-// MMI service code for registration new password as defined in TS 22.030 6.5.4
-this.MMI_SC_CHANGE_PASSWORD = "03";
-this.MMI_ZZ_BARRING_SERVICE = "330";
-
-// MMI call barring service codes
-this.MMI_SC_BAOC = "33";
-this.MMI_SC_BAOIC = "331";
-this.MMI_SC_BAOICxH = "332";
-this.MMI_SC_BAIC = "35";
-this.MMI_SC_BAICr = "351";
-this.MMI_SC_BA_ALL = "330";
-this.MMI_SC_BA_MO = "333";
-this.MMI_SC_BA_MT = "353";
-
-this.MMI_SC_TO_CB_FACILITY = {};
-
-MMI_SC_TO_CB_FACILITY[MMI_SC_BAOC] = ICC_CB_FACILITY_BAOC;
-MMI_SC_TO_CB_FACILITY[MMI_SC_BAOIC] = ICC_CB_FACILITY_BAOIC;
-MMI_SC_TO_CB_FACILITY[MMI_SC_BAOICxH] = ICC_CB_FACILITY_BAOICxH;
-MMI_SC_TO_CB_FACILITY[MMI_SC_BAIC] = ICC_CB_FACILITY_BAIC;
-MMI_SC_TO_CB_FACILITY[MMI_SC_BAICr] = ICC_CB_FACILITY_BAICr;
-MMI_SC_TO_CB_FACILITY[MMI_SC_BA_ALL] = ICC_CB_FACILITY_BA_ALL;
-MMI_SC_TO_CB_FACILITY[MMI_SC_BA_MO] = ICC_CB_FACILITY_BA_MO;
-MMI_SC_TO_CB_FACILITY[MMI_SC_BA_MT] = ICC_CB_FACILITY_BA_MT;
-
-// MMI service code key strings.
-this.MMI_KS_SC_CALL_BARRING = "scCallBarring";
-this.MMI_KS_SC_CALL_FORWARDING = "scCallForwarding";
-this.MMI_KS_SC_CLIP = "scClip";
-this.MMI_KS_SC_CLIR = "scClir";
-this.MMI_KS_SC_PWD = "scPwd";
-this.MMI_KS_SC_CALL_WAITING = "scCallWaiting";
-this.MMI_KS_SC_PIN = "scPin";
-this.MMI_KS_SC_PIN2 = "scPin2";
-this.MMI_KS_SC_PUK = "scPuk";
-this.MMI_KS_SC_PUK2 = "scPuk2";
-this.MMI_KS_SC_CHANGE_PASSWORD = "scChangePassword";
-this.MMI_KS_SC_IMEI = "scImei";
-this.MMI_KS_SC_USSD = "scUssd";
-this.MMI_KS_SC_CALL = "scCall";
-
-// MMI error messages key strings.
-this.MMI_ERROR_KS_ERROR = "emMmiError";
-this.MMI_ERROR_KS_NOT_SUPPORTED = "emMmiErrorNotSupported";
-this.MMI_ERROR_KS_INVALID_ACTION = "emMmiErrorInvalidAction";
-this.MMI_ERROR_KS_MISMATCH_PIN = "emMmiErrorMismatchPin";
-this.MMI_ERROR_KS_MISMATCH_PASSWORD = "emMmiErrorMismatchPassword";
-this.MMI_ERROR_KS_BAD_PIN = "emMmiErrorBadPin";
-this.MMI_ERROR_KS_BAD_PUK = "emMmiErrorBadPuk";
-this.MMI_ERROR_KS_INVALID_PIN = "emMmiErrorInvalidPin";
-this.MMI_ERROR_KS_INVALID_PASSWORD = "emMmiErrorInvalidPassword";
-this.MMI_ERROR_KS_NEEDS_PUK = "emMmiErrorNeedsPuk";
-this.MMI_ERROR_KS_SIM_BLOCKED = "emMmiErrorSimBlocked";
-
-// MMI status message.
-this.MMI_SM_KS_PASSWORD_CHANGED = "smPasswordChanged";
-this.MMI_SM_KS_PIN_CHANGED = "smPinChanged";
-this.MMI_SM_KS_PIN2_CHANGED = "smPin2Changed";
-this.MMI_SM_KS_PIN_UNBLOCKED = "smPinUnblocked";
-this.MMI_SM_KS_PIN2_UNBLOCKED = "smPin2Unblocked";
-this.MMI_SM_KS_SERVICE_ENABLED = "smServiceEnabled";
-this.MMI_SM_KS_SERVICE_ENABLED_FOR = "smServiceEnabledFor";
-this.MMI_SM_KS_SERVICE_DISABLED = "smServiceDisabled";
-this.MMI_SM_KS_SERVICE_REGISTERED = "smServiceRegistered";
-this.MMI_SM_KS_SERVICE_ERASED = "smServiceErased";
-this.MMI_SM_KS_SERVICE_INTERROGATED = "smServiceInterrogated";
-this.MMI_SM_KS_SERVICE_NOT_PROVISIONED = "smServiceNotProvisioned";
-this.MMI_SM_KS_CLIR_PERMANENT = "smClirPermanent";
-this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_ON = "smClirDefaultOnNextCallOn";
-this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_OFF = "smClirDefaultOnNextCallOff";
-this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_ON = "smClirDefaultOffNextCallOn";
-this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_OFF = "smClirDefaultOffNextCallOff";
-this.MMI_SM_KS_CALL_CONTROL = "smCallControl";
-
-// MMI Service class
-this.MMI_KS_SERVICE_CLASS_VOICE = "serviceClassVoice";
-this.MMI_KS_SERVICE_CLASS_DATA = "serviceClassData";
-this.MMI_KS_SERVICE_CLASS_FAX = "serviceClassFax";
-this.MMI_KS_SERVICE_CLASS_SMS = "serviceClassSms";
-this.MMI_KS_SERVICE_CLASS_DATA_SYNC = "serviceClassDataSync";
-this.MMI_KS_SERVICE_CLASS_DATA_ASYNC = "serviceClassDataAsync";
-this.MMI_KS_SERVICE_CLASS_PACKET = "serviceClassPacket";
-this.MMI_KS_SERVICE_CLASS_PAD = "serviceClassPad";
-
-this.MMI_KS_SERVICE_CLASS_MAPPING = {};
-MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_VOICE] = MMI_KS_SERVICE_CLASS_VOICE;
-MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_DATA] = MMI_KS_SERVICE_CLASS_DATA;