mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Merge m-c to inbound. a=merge
CLOSED TREE
This commit is contained in:
commit
e2dac14c42
@ -10,13 +10,9 @@ let isMulet = "ResponsiveUI" in browserWindow;
|
||||
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() {
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<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"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<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"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<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"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</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 -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<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"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<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"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<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"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<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"/>
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -17,10 +17,10 @@
|
||||
</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 -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<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"/>
|
||||
|
@ -407,7 +407,7 @@ pref("browser.search.order.3", "chrome://browser-region/locale/re
|
||||
// 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");
|
||||
@ -1863,6 +1863,9 @@ pref("identity.fxaccounts.remote.oauth.uri", "https://oauth.accounts.firefox.com
|
||||
// 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
|
||||
|
@ -47,15 +47,10 @@ const gXPInstallObserver = {
|
||||
|
||||
// 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)
|
||||
@ -200,15 +195,10 @@ const gXPInstallObserver = {
|
||||
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";
|
||||
@ -292,7 +282,13 @@ const gXPInstallObserver = {
|
||||
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;
|
||||
|
@ -1358,3 +1358,10 @@ toolbarpaletteitem[place="palette"][hidden] {
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -5174,6 +5174,8 @@ var TabsInTitlebar = {
|
||||
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:
|
||||
@ -7104,11 +7106,6 @@ var gIdentityHandler = {
|
||||
|
||||
// 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");
|
||||
@ -7123,6 +7120,7 @@ var gIdentityHandler = {
|
||||
onPopupHidden(event) {
|
||||
if (event.target == this._identityPopup) {
|
||||
window.removeEventListener("focus", this, true);
|
||||
this._identityBox.removeAttribute("open");
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -21,6 +21,9 @@ const kWhitelist = [
|
||||
{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},
|
||||
|
@ -58,7 +58,7 @@ function testBenignPage() {
|
||||
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",
|
||||
@ -68,7 +68,15 @@ function testTrackingPage() {
|
||||
|
||||
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");
|
||||
@ -101,7 +109,7 @@ function* testTrackingProtectionForTab(tab) {
|
||||
|
||||
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);
|
||||
@ -113,7 +121,7 @@ function* testTrackingProtectionForTab(tab) {
|
||||
tabReloadPromise = promiseTabLoadEvent(tab);
|
||||
clickButton("#tracking-action-block");
|
||||
yield tabReloadPromise;
|
||||
testTrackingPage();
|
||||
testTrackingPage(tab.ownerDocument.defaultView);
|
||||
}
|
||||
|
||||
add_task(function* testNormalBrowsing() {
|
||||
|
@ -29,8 +29,8 @@ add_task(function* () {
|
||||
// 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");
|
||||
@ -42,14 +42,10 @@ add_task(function* () {
|
||||
.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.");
|
||||
});
|
||||
|
||||
|
@ -3116,9 +3116,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
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;
|
||||
|
@ -44,23 +44,28 @@
|
||||
|
||||
<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-block"
|
||||
label="&trackingProtection.block.label;"
|
||||
<button id="tracking-action-unblock-private"
|
||||
label="&trackingProtection.unblockPrivate.label;"
|
||||
class="identity-popup-button"
|
||||
accesskey="&trackingProtection.block.accesskey;"
|
||||
accesskey="&trackingProtection.unblock.accesskey;"
|
||||
oncommand="TrackingProtection.disableForCurrentPage();" />
|
||||
<button id="tracking-action-block"
|
||||
label="&trackingProtection.block2.label;"
|
||||
class="identity-popup-button"
|
||||
accesskey="&trackingProtection.block2.accesskey;"
|
||||
oncommand="TrackingProtection.enableForCurrentPage();" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
@ -87,7 +87,7 @@ function configureFxAccountIdentity() {
|
||||
};
|
||||
|
||||
let token = {
|
||||
endpoint: Weave.Svc.Prefs.get("tokenServerURI"),
|
||||
endpoint: null,
|
||||
duration: 300,
|
||||
id: "id",
|
||||
key: "key",
|
||||
|
@ -215,7 +215,7 @@ body {
|
||||
|
||||
.new-room-view > .context {
|
||||
margin: .5rem 0 0;
|
||||
background-color: #DEEFF7;
|
||||
background-color: #dbf7ff;
|
||||
border-radius: 3px 3px 0 0;
|
||||
padding: .5rem;
|
||||
}
|
||||
@ -243,7 +243,7 @@ body {
|
||||
}
|
||||
|
||||
.new-room-view > .context > .checkbox-wrapper > label {
|
||||
color: #3c3c3c;
|
||||
color: #333;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
|
@ -520,7 +520,7 @@ html[dir="rtl"] .context-content {
|
||||
}
|
||||
|
||||
.context-wrapper {
|
||||
border: 1px solid #0096dd;
|
||||
border: 1px solid #5cccee;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
padding: .8em;
|
||||
|
@ -1465,14 +1465,20 @@ html[dir="rtl"] .standalone .room-conversation-wrapper .room-inner-info-area {
|
||||
.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;
|
||||
@ -1483,10 +1489,9 @@ html[dir="rtl"] .standalone .room-conversation-wrapper .room-inner-info-area {
|
||||
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;
|
||||
}
|
||||
@ -1534,7 +1539,7 @@ html[dir="rtl"] .text-chat-entry.received > p {
|
||||
|
||||
/* Text chat entry timestamp */
|
||||
.text-chat-entry-timestamp {
|
||||
margin: 0 .2em;
|
||||
margin: 0 .5em;
|
||||
color: #aaa;
|
||||
font-style: italic;
|
||||
font-size: .8em;
|
||||
@ -1669,7 +1674,32 @@ html[dir="rtl"] .text-chat-entry.received .text-chat-arrow {
|
||||
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 */
|
||||
|
@ -5,7 +5,7 @@
|
||||
<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"/>
|
||||
|
Before Width: | Height: | Size: 886 B After Width: | Height: | Size: 886 B |
@ -742,7 +742,20 @@ nsDefaultCommandLineHandler.prototype = {
|
||||
// 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);
|
||||
|
@ -2440,9 +2440,7 @@ ContentPermissionPrompt.prototype = {
|
||||
|
||||
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);
|
||||
|
@ -369,19 +369,6 @@ var gPrivacyPane = {
|
||||
|
||||
// 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:
|
||||
*
|
||||
|
@ -253,20 +253,16 @@
|
||||
<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>
|
||||
|
@ -187,15 +187,15 @@ let gSyncPane = {
|
||||
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);
|
||||
});
|
||||
@ -319,11 +319,11 @@ let gSyncPane = {
|
||||
// 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.)
|
||||
@ -332,12 +332,12 @@ let gSyncPane = {
|
||||
// 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;
|
||||
@ -345,8 +345,9 @@ let gSyncPane = {
|
||||
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");
|
||||
|
@ -345,13 +345,13 @@
|
||||
</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>
|
||||
|
@ -324,19 +324,6 @@ var gPrivacyPane = {
|
||||
|
||||
// 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:
|
||||
*
|
||||
|
@ -272,20 +272,16 @@
|
||||
|
||||
<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>
|
||||
|
@ -1,38 +1,15 @@
|
||||
/* 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
|
||||
@ -42,11 +19,7 @@ function test() {
|
||||
{ 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];
|
||||
@ -67,28 +40,28 @@ function test() {
|
||||
// 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
|
||||
@ -103,15 +76,24 @@ function test() {
|
||||
// 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);
|
||||
});
|
||||
|
@ -19,6 +19,7 @@
|
||||
"Services": true,
|
||||
"Task": true,
|
||||
"XPCOMUtils": true,
|
||||
"XPCNativeWrapper": true,
|
||||
},
|
||||
"rules": {
|
||||
// These are the rules that have been configured so far to match the
|
||||
|
@ -18,8 +18,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
|
||||
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"];
|
||||
|
||||
@ -134,7 +135,6 @@ function ResponsiveUI(aWindow, aTab)
|
||||
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);
|
||||
@ -219,11 +219,9 @@ function ResponsiveUI(aWindow, aTab)
|
||||
|
||||
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({
|
||||
@ -274,9 +272,7 @@ ResponsiveUI.prototype = {
|
||||
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);
|
||||
@ -295,8 +291,8 @@ ResponsiveUI.prototype = {
|
||||
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 = () => {
|
||||
@ -441,14 +437,12 @@ ResponsiveUI.prototype = {
|
||||
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);
|
||||
|
||||
@ -793,19 +787,13 @@ ResponsiveUI.prototype = {
|
||||
* 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() {
|
||||
@ -816,12 +804,12 @@ ResponsiveUI.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
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;
|
||||
@ -851,7 +839,7 @@ ResponsiveUI.prototype = {
|
||||
buttons);
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Change the size of the browser.
|
||||
|
@ -12,6 +12,5 @@ skip-if = e10s # Bug ??????
|
||||
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]
|
||||
|
@ -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";
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://mochi.test:8888/browser/browser/devtools/" +
|
||||
"responsivedesign/test/touch.html";
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = url;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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 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* 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* 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");
|
||||
}
|
||||
|
@ -14,8 +14,11 @@ 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();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@
|
||||
var div = document.querySelector("div");
|
||||
var initX, initY;
|
||||
|
||||
div.style.transform = "none";
|
||||
|
||||
div.addEventListener("touchstart", function(evt) {
|
||||
var touch = evt.changedTouches[0];
|
||||
|
@ -36,6 +36,8 @@ 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.
|
||||
@ -299,6 +301,62 @@ Editor.prototype = {
|
||||
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", () => {
|
||||
|
@ -28,6 +28,7 @@ support-files =
|
||||
[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]
|
||||
|
214
browser/devtools/sourceeditor/test/browser_editor_find_again.js
Normal file
214
browser/devtools/sourceeditor/test/browser_editor_find_again.js
Normal file
@ -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);
|
||||
});
|
@ -40,6 +40,11 @@ function promiseTab(aURL) {
|
||||
addTab(aURL, resolve));
|
||||
}
|
||||
|
||||
function promiseWaitForFocus() {
|
||||
return new Promise(resolve =>
|
||||
waitForFocus(resolve));
|
||||
}
|
||||
|
||||
function setup(cb, additionalOpts = {}) {
|
||||
cb = cb || function() {};
|
||||
let def = promise.defer();
|
||||
|
@ -4,17 +4,22 @@
|
||||
* 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");
|
||||
@ -24,7 +29,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||
|
||||
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
|
||||
@ -50,7 +54,7 @@ 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;
|
||||
@ -116,24 +120,24 @@ UpdateProcess.prototype = {
|
||||
};
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@ -146,13 +150,8 @@ function CssHtmlTree(aStyleInspector, aPageStyle)
|
||||
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);
|
||||
@ -188,19 +187,21 @@ function CssHtmlTree(aStyleInspector, aPageStyle)
|
||||
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();
|
||||
}
|
||||
@ -210,17 +211,17 @@ function CssHtmlTree(aStyleInspector, aPageStyle)
|
||||
* @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");
|
||||
});
|
||||
@ -230,7 +231,7 @@ XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function() {
|
||||
.getService(Ci.nsIClipboardHelper);
|
||||
});
|
||||
|
||||
CssHtmlTree.prototype = {
|
||||
CssComputedView.prototype = {
|
||||
// Cache the list of properties that match the selected element.
|
||||
_matchedProperties: null,
|
||||
|
||||
@ -264,7 +265,7 @@ CssHtmlTree.prototype = {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@ -395,7 +396,7 @@ CssHtmlTree.prototype = {
|
||||
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);
|
||||
@ -425,7 +426,7 @@ CssHtmlTree.prototype = {
|
||||
/**
|
||||
* Refresh the panel content.
|
||||
*/
|
||||
refreshPanel: function CssHtmlTree_refreshPanel()
|
||||
refreshPanel: function CssComputedView_refreshPanel()
|
||||
{
|
||||
if (!this.viewedElement) {
|
||||
return promise.resolve();
|
||||
@ -591,7 +592,7 @@ CssHtmlTree.prototype = {
|
||||
* 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 ?
|
||||
@ -599,7 +600,7 @@ CssHtmlTree.prototype = {
|
||||
CssLogic.FILTER.USER;
|
||||
},
|
||||
|
||||
_updateSourceLinks: function CssHtmlTree__updateSourceLinks()
|
||||
_onSourcePrefChanged: function CssComputedView__onSourcePrefChanged()
|
||||
{
|
||||
for (let propView of this.propertyViews) {
|
||||
propView.updateSourceLinks();
|
||||
@ -610,13 +611,13 @@ CssHtmlTree.prototype = {
|
||||
/**
|
||||
* 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
|
||||
@ -630,16 +631,16 @@ CssHtmlTree.prototype = {
|
||||
} 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 {
|
||||
@ -669,187 +670,11 @@ CssHtmlTree.prototype = {
|
||||
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) {
|
||||
@ -863,40 +688,21 @@ CssHtmlTree.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_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);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 = CssHtmlTree.l10n("styleinspector.copyImageDataUrlError");
|
||||
_onCopy: function(event) {
|
||||
this.copySelection();
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
clipboardHelper.copyString(message);
|
||||
}),
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy selected text.
|
||||
*
|
||||
* @param event The event object
|
||||
* Copy the current selection to the clipboard
|
||||
*/
|
||||
_onCopy: function(event)
|
||||
{
|
||||
copySelection: function() {
|
||||
try {
|
||||
let win = this.styleDocument.defaultView;
|
||||
let text = win.getSelection().toString().trim();
|
||||
@ -909,15 +715,12 @@ CssHtmlTree.prototype = {
|
||||
// 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 {
|
||||
@ -926,35 +729,22 @@ CssHtmlTree.prototype = {
|
||||
}
|
||||
|
||||
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
|
||||
@ -967,34 +757,10 @@ CssHtmlTree.prototype = {
|
||||
|
||||
// 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();
|
||||
|
||||
@ -1018,18 +784,17 @@ CssHtmlTree.prototype = {
|
||||
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();
|
||||
}
|
||||
|
||||
// The element that we're inspecting, and the document that it comes from.
|
||||
this.propertyViews = null;
|
||||
this.styleWindow = null;
|
||||
|
||||
this.inspector = null;
|
||||
this.styleDocument = null;
|
||||
this.styleInspector = null;
|
||||
this.styleWindow = null;
|
||||
|
||||
this._isDestroyed = true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1046,30 +811,11 @@ PropertyInfo.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
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.
|
||||
*/
|
||||
@ -1393,7 +1139,6 @@ PropertyView.prototype = {
|
||||
this._matchedSelectorViews.push(new SelectorView(this.tree, aSelectorInfo));
|
||||
}, this);
|
||||
}
|
||||
|
||||
return this._matchedSelectorViews;
|
||||
},
|
||||
|
||||
@ -1462,7 +1207,7 @@ PropertyView.prototype = {
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@ -1509,7 +1254,7 @@ SelectorView.prototype = {
|
||||
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');
|
||||
}
|
||||
@ -1600,7 +1345,6 @@ SelectorView.prototype = {
|
||||
if (!rule || !this.sheet) {
|
||||
let oldSource = this.source;
|
||||
this.source = CssLogic.l10n("rule.sourceElement");
|
||||
this.href = "#";
|
||||
return promise.resolve(oldSource);
|
||||
}
|
||||
|
||||
@ -1714,5 +1458,5 @@ function createChild(aParent, aTag, aAttributes={}) {
|
||||
return elt;
|
||||
}
|
||||
|
||||
exports.CssHtmlTree = CssHtmlTree;
|
||||
exports.CssComputedView = CssComputedView;
|
||||
exports.PropertyView = PropertyView;
|
||||
|
@ -11,6 +11,7 @@ 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',
|
||||
]
|
||||
|
@ -4,7 +4,8 @@
|
||||
* 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";
|
||||
|
||||
@ -25,10 +26,12 @@ const {
|
||||
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";
|
||||
@ -1141,9 +1144,8 @@ TextProperty.prototype = {
|
||||
* 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
|
||||
@ -1152,55 +1154,41 @@ TextProperty.prototype = {
|
||||
* 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);
|
||||
@ -1232,11 +1220,12 @@ function CssRuleView(aInspector, aDoc, aStore, aPageStyle) {
|
||||
autoSelect: true,
|
||||
theme: "auto"
|
||||
};
|
||||
this.popup = new AutocompletePopup(aDoc.defaultView.parent.document, options);
|
||||
this.popup = new AutocompletePopup(this.styleWindow.parent.document, options);
|
||||
|
||||
this._buildContextMenu();
|
||||
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();
|
||||
@ -1255,108 +1244,6 @@ CssRuleView.prototype = {
|
||||
// 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
|
||||
@ -1442,78 +1329,6 @@ CssRuleView.prototype = {
|
||||
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
|
||||
@ -1575,11 +1390,11 @@ CssRuleView.prototype = {
|
||||
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;
|
||||
@ -1589,130 +1404,51 @@ CssRuleView.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Retrieve the RuleEditor instance that should be stored on
|
||||
* the offset parent of the node
|
||||
*/
|
||||
_isColorPopup: function() {
|
||||
this._colorToCopy = "";
|
||||
|
||||
let container = this._getPopupNodeContainer();
|
||||
if (!container) {
|
||||
return false;
|
||||
_getRuleEditorForNode: function(node) {
|
||||
if (!node.offsetParent) {
|
||||
// some nodes don't have an offsetParent, but their parentNode does
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
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.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;
|
||||
let text = "";
|
||||
|
||||
if (event.target.nodeName === "menuitem") {
|
||||
target = this.doc.popupNode;
|
||||
}
|
||||
|
||||
if (target.nodeName == "input") {
|
||||
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");
|
||||
@ -1724,127 +1460,11 @@ CssRuleView.prototype = {
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
@ -1863,6 +1483,7 @@ CssRuleView.prototype = {
|
||||
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) {
|
||||
@ -1910,10 +1531,6 @@ CssRuleView.prototype = {
|
||||
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) {
|
||||
@ -1923,13 +1540,10 @@ CssRuleView.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
@ -1986,7 +1600,7 @@ CssRuleView.prototype = {
|
||||
*/
|
||||
_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) {
|
||||
@ -2018,8 +1632,6 @@ CssRuleView.prototype = {
|
||||
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;
|
||||
@ -2027,72 +1639,10 @@ CssRuleView.prototype = {
|
||||
|
||||
// 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();
|
||||
|
||||
@ -2119,6 +1669,10 @@ CssRuleView.prototype = {
|
||||
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);
|
||||
}
|
||||
@ -2253,7 +1807,7 @@ CssRuleView.prototype = {
|
||||
* 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;
|
||||
}
|
||||
|
||||
@ -2333,19 +1887,19 @@ CssRuleView.prototype = {
|
||||
* @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);
|
||||
|
||||
@ -2434,7 +1988,7 @@ CssRuleView.prototype = {
|
||||
// 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);
|
||||
@ -2442,7 +1996,7 @@ CssRuleView.prototype = {
|
||||
|
||||
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;
|
||||
@ -2678,7 +2232,7 @@ CssRuleView.prototype = {
|
||||
*/
|
||||
function RuleEditor(aRuleView, aRule) {
|
||||
this.ruleView = aRuleView;
|
||||
this.doc = this.ruleView.doc;
|
||||
this.doc = this.ruleView.styleDocument;
|
||||
this.rule = aRule;
|
||||
|
||||
this.isEditable = !aRule.isSystem;
|
||||
@ -2729,7 +2283,7 @@ RuleEditor.prototype = {
|
||||
}.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();
|
||||
@ -2809,7 +2363,7 @@ RuleEditor.prototype = {
|
||||
},
|
||||
|
||||
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 : "";
|
||||
@ -3904,32 +3458,6 @@ function createChild(aParent, aTag, aAttributes) {
|
||||
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);
|
||||
|
534
browser/devtools/styleinspector/style-inspector-menu.js
Normal file
534
browser/devtools/styleinspector/style-inspector-menu.js
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
@ -41,7 +41,7 @@ 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) {
|
||||
@ -231,7 +231,7 @@ HighlightersOverlay.prototype = {
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
@ -268,13 +268,14 @@ TooltipsOverlay.prototype = {
|
||||
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);
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ loader.lazyGetter(this, "_strings", () => Services.strings
|
||||
|
||||
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);
|
||||
@ -153,15 +153,15 @@ RuleViewTool.prototype = {
|
||||
|
||||
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);
|
||||
@ -238,8 +238,7 @@ ComputedViewTool.prototype = {
|
||||
|
||||
this.view.destroy();
|
||||
|
||||
this.view = this.cssLogic = this.cssHtmlTree = null;
|
||||
this.doc = this.inspector = null;
|
||||
this.view = this.document = this.inspector = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -75,8 +75,8 @@ function checkSelectAll(view) {
|
||||
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]+" +
|
||||
|
@ -43,12 +43,12 @@ add_task(function*() {
|
||||
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.");
|
||||
@ -60,7 +60,7 @@ add_task(function*() {
|
||||
|
||||
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");
|
||||
@ -68,7 +68,7 @@ add_task(function*() {
|
||||
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.");
|
||||
|
@ -50,7 +50,7 @@ function* testCancelNewOnEscape(inspector, ruleView) {
|
||||
|
||||
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", {});
|
||||
|
@ -39,11 +39,11 @@ function* testCreateNew(ruleView) {
|
||||
|
||||
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.");
|
||||
@ -52,7 +52,7 @@ function* testCreateNew(ruleView) {
|
||||
|
||||
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;
|
||||
|
||||
|
@ -53,12 +53,12 @@ function* testCreateNew(view) {
|
||||
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.");
|
||||
|
@ -40,7 +40,7 @@ function* testCreateNew(inspector, ruleView) {
|
||||
"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");
|
||||
@ -48,11 +48,11 @@ function* testCreateNew(inspector, ruleView) {
|
||||
|
||||
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.");
|
||||
@ -62,7 +62,7 @@ function* testCreateNew(inspector, ruleView) {
|
||||
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;
|
||||
|
||||
|
@ -61,18 +61,18 @@ function* runTestData(inspector, view, data, method) {
|
||||
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");
|
||||
|
@ -65,7 +65,7 @@ add_task(function*() {
|
||||
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");
|
||||
@ -89,7 +89,7 @@ function* testCompletion([key, completion, index, total], editor, view) {
|
||||
}
|
||||
|
||||
info("Synthesizing key " + key);
|
||||
EventUtils.synthesizeKey(key, {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey(key, {}, view.styleWindow);
|
||||
|
||||
yield onSuggest;
|
||||
yield wait(1); // Equivalent of executeSoon
|
||||
|
@ -47,14 +47,14 @@ add_task(function*() {
|
||||
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);
|
||||
}
|
||||
});
|
||||
@ -67,7 +67,7 @@ function* testCompletion([key, modifiers, completion, index, total], editor, vie
|
||||
|
||||
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");
|
||||
@ -78,14 +78,14 @@ function* testCompletion([key, modifiers, completion, index, total], editor, vie
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -48,7 +48,7 @@ add_task(function*() {
|
||||
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");
|
||||
@ -72,7 +72,7 @@ function* testCompletion([key, completion, index, total], editor, view) {
|
||||
}
|
||||
|
||||
info("Synthesizing key " + key);
|
||||
EventUtils.synthesizeKey(key, {}, view.doc.defaultView);
|
||||
EventUtils.synthesizeKey(key, {}, view.styleWindow);
|
||||
|
||||
yield onSuggest;
|
||||
yield wait(1); // Equivalent of executeSoon
|
||||
|
@ -50,14 +50,14 @@ add_task(function*() {
|
||||
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);
|
||||
}
|
||||
});
|
||||
@ -70,7 +70,7 @@ function* testCompletion([key, modifiers, completion, index, total], editor, vie
|
||||
|
||||
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)) {
|
||||
@ -82,7 +82,7 @@ function* testCompletion([key, modifiers, completion, index, total], editor, vie
|
||||
}
|
||||
|
||||
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
|
||||
@ -91,7 +91,7 @@ function* testCompletion([key, modifiers, completion, index, total], editor, vie
|
||||
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) {
|
||||
|
@ -49,10 +49,10 @@ add_task(function*() {
|
||||
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,
|
||||
@ -65,7 +65,7 @@ function checkRuleViewContent({doc}) {
|
||||
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) {
|
||||
|
@ -62,15 +62,15 @@ function* testMdnContextMenuItemVisibility(view) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,8 +78,7 @@ function* testMdnContextMenuItemVisibility(view) {
|
||||
* 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";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,14 +47,14 @@ function* testShowMdnTooltip(view) {
|
||||
|
||||
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");
|
||||
}
|
||||
|
@ -101,11 +101,11 @@ function* testMdnContextMenuItemVisibility(view, shouldBeVisible) {
|
||||
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);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ 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);
|
||||
@ -27,7 +27,7 @@ add_task(function*() {
|
||||
{
|
||||
desc: "Test Copy Property Name",
|
||||
node: ruleEditor.rule.textProps[0].editor.nameSpan,
|
||||
menuItem: view.menuitemCopyPropertyName,
|
||||
menuItem: contextmenu.menuitemCopyPropertyName,
|
||||
expectedPattern: "color",
|
||||
hidden: {
|
||||
copyLocation: true,
|
||||
@ -41,7 +41,7 @@ add_task(function*() {
|
||||
{
|
||||
desc: "Test Copy Property Value",
|
||||
node: ruleEditor.rule.textProps[2].editor.valueSpan,
|
||||
menuItem: view.menuitemCopyPropertyValue,
|
||||
menuItem: contextmenu.menuitemCopyPropertyValue,
|
||||
expectedPattern: "12px",
|
||||
hidden: {
|
||||
copyLocation: true,
|
||||
@ -55,7 +55,7 @@ add_task(function*() {
|
||||
{
|
||||
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,
|
||||
@ -69,7 +69,7 @@ add_task(function*() {
|
||||
{
|
||||
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]+" +
|
||||
@ -87,7 +87,7 @@ add_task(function*() {
|
||||
{
|
||||
desc: "Test Copy Selector",
|
||||
node: ruleEditor.selectorText,
|
||||
menuItem: view.menuitemCopySelector,
|
||||
menuItem: contextmenu.menuitemCopySelector,
|
||||
expectedPattern: "html, body, #testid",
|
||||
hidden: {
|
||||
copyLocation: true,
|
||||
@ -101,7 +101,7 @@ add_task(function*() {
|
||||
{
|
||||
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: {
|
||||
@ -119,7 +119,7 @@ add_task(function*() {
|
||||
},
|
||||
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]+" +
|
||||
@ -137,7 +137,7 @@ add_task(function*() {
|
||||
{
|
||||
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,
|
||||
@ -161,41 +161,39 @@ add_task(function*() {
|
||||
});
|
||||
|
||||
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);
|
||||
@ -207,7 +205,7 @@ function* checkCopyStyle(view, node, menuItem, expectedPattern, hidden) {
|
||||
failedClipboard(expectedPattern);
|
||||
}
|
||||
|
||||
view._contextmenu.hidePopup();
|
||||
view._contextmenu._menupopup.hidePopup();
|
||||
}
|
||||
|
||||
function* disableProperty(view) {
|
||||
|
@ -66,7 +66,7 @@ function* runTestData(view, {value, commitKey, modifiers, expected}) {
|
||||
|
||||
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");
|
||||
|
@ -35,7 +35,7 @@ function* editAndCheck(view) {
|
||||
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;
|
||||
|
@ -173,7 +173,7 @@ function* testIncrement(editor, options, view, {ruleEditor}) {
|
||||
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) {
|
||||
|
@ -41,17 +41,17 @@ function* testEditProperty(inspector, ruleView) {
|
||||
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.");
|
||||
@ -60,7 +60,7 @@ function* testEditProperty(inspector, ruleView) {
|
||||
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");
|
||||
}
|
||||
@ -76,15 +76,15 @@ function* testEditProperty(inspector, ruleView) {
|
||||
|
||||
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;
|
||||
|
||||
|
@ -87,7 +87,7 @@ function* runTestData(inspector, view, data) {
|
||||
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,
|
||||
|
@ -35,7 +35,7 @@ function* testSelectorHighlight(view, name) {
|
||||
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");
|
||||
|
@ -82,12 +82,12 @@ function* testAddProperty(view) {
|
||||
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.");
|
||||
|
@ -29,7 +29,7 @@ add_task(function*() {
|
||||
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)",
|
||||
|
@ -29,7 +29,7 @@ add_task(function*() {
|
||||
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);
|
||||
|
@ -15,7 +15,7 @@ add_task(function*() {
|
||||
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);
|
||||
@ -51,5 +51,5 @@ add_task(function*() {
|
||||
});
|
||||
|
||||
function getCurrentInplaceEditor(view) {
|
||||
return inplaceEditor(view.doc.activeElement);
|
||||
return inplaceEditor(view.styleDocument.activeElement);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ function* testLivePreviewData(data, ruleView, selector) {
|
||||
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 {
|
||||
|
@ -47,9 +47,9 @@ function* testCreateNewMultiUnfinished(inspector, ruleEditor, view) {
|
||||
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.");
|
||||
|
@ -34,7 +34,7 @@ function* testCreateNewMultiPartialUnfinished(inspector, ruleEditor, view) {
|
||||
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.");
|
||||
|
@ -32,13 +32,13 @@ function* testMultiValues(inspector, ruleEditor, view) {
|
||||
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");
|
||||
|
@ -52,7 +52,7 @@ function* testTopLeft(inspector, view) {
|
||||
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");
|
||||
|
||||
|
@ -47,7 +47,7 @@ add_task(function*() {
|
||||
});
|
||||
|
||||
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");
|
||||
|
@ -31,7 +31,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -31,7 +31,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -31,7 +31,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -31,7 +31,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -31,7 +31,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -32,7 +32,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
@ -68,7 +68,7 @@ function* testAddTextInFilter(inspector, ruleView) {
|
||||
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");
|
||||
|
||||
|
@ -28,7 +28,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -32,12 +32,11 @@ add_task(function*() {
|
||||
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");
|
||||
@ -68,20 +67,18 @@ function* testAddTextInFilter(inspector, ruleView) {
|
||||
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;
|
||||
|
@ -30,7 +30,6 @@ add_task(function*() {
|
||||
});
|
||||
|
||||
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;
|
||||
@ -42,7 +41,7 @@ function* testOpenExpanderAndAddTextInFilter(inspector, ruleView) {
|
||||
|
||||
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");
|
||||
@ -72,20 +71,18 @@ function* testOpenExpanderAndAddTextInFilter(inspector, ruleView) {
|
||||
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;
|
||||
|
@ -30,7 +30,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -31,7 +31,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -30,7 +30,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -19,7 +19,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -30,7 +30,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -30,7 +30,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -30,7 +30,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
@ -30,7 +30,7 @@ add_task(function*() {
|
||||
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");
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user