Merge m-c to inbound. a=merge

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2015-07-17 10:27:24 -04:00
commit e2dac14c42
263 changed files with 6556 additions and 4185 deletions

View File

@ -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() {

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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 -->

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"
}

View File

@ -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 -->

View File

@ -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"/>

View File

@ -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

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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");
}
},

View File

@ -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},

View File

@ -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() {

View File

@ -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.");
});

View File

@ -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;

View File

@ -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>

View File

@ -87,7 +87,7 @@ function configureFxAccountIdentity() {
};
let token = {
endpoint: Weave.Svc.Prefs.get("tokenServerURI"),
endpoint: null,
duration: 300,
id: "id",
key: "key",

View File

@ -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;
}

View File

@ -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;

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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:
*

View File

@ -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>

View File

@ -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");

View File

@ -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>

View File

@ -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:
*

View File

@ -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>

View File

@ -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);
});

View File

@ -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

View File

@ -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.

View File

@ -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]

View File

@ -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");
}

View File

@ -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();
}
});
/**

View File

@ -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];

View File

@ -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", () => {

View File

@ -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]

View 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);
});

View File

@ -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();

View File

@ -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;

View File

@ -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',
]

View File

@ -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);

View 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;
}
}
};

View File

@ -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);
}

View File

@ -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;
}
};

View File

@ -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]+" +

View File

@ -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.");

View File

@ -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", {});

View File

@ -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;

View File

@ -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.");

View File

@ -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;

View File

@ -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");

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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";
}
/**

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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");

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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,

View File

@ -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");

View File

@ -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.");

View File

@ -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)",

View File

@ -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);

View File

@ -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);
}

View File

@ -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 {

View File

@ -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.");

View File

@ -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.");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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