Merge fx-team to central, a=merge

MozReview-Commit-ID: 9LaKI6lIClP
This commit is contained in:
Wes Kocher 2016-02-26 12:19:25 -08:00
commit fda2ecf8ae
256 changed files with 3004 additions and 2350 deletions

View File

@ -81,7 +81,6 @@ browser/extensions/loop/**
# devtools/ exclusions
devtools/*.js
devtools/client/animationinspector/**
devtools/client/canvasdebugger/**
devtools/client/commandline/**
devtools/client/debugger/**
@ -92,7 +91,6 @@ devtools/client/framework/**
devtools/client/inspector/computed/**
devtools/client/inspector/fonts/**
devtools/client/inspector/markup/test/**
devtools/client/inspector/rules/**
devtools/client/inspector/shared/test/**
devtools/client/inspector/test/**
devtools/client/inspector/*.js

2
.gitignore vendored
View File

@ -23,6 +23,7 @@ ID
/.mozconfig*
/mozconfig
/configure
/old-configure
/config.cache
/config.log
/.clang_complete
@ -40,6 +41,7 @@ _OPT.OBJ/
# SpiderMonkey configury
js/src/configure
js/src/old-configure
js/src/autom4te.cache
# SpiderMonkey test result logs
js/src/tests/results-*.html

View File

@ -19,6 +19,7 @@
^\.mozconfig
^mozconfig*
^configure$
^old-configure$
^config\.cache$
^config\.log$
^\.clang_complete
@ -37,6 +38,7 @@ _OPT\.OBJ/
# SpiderMonkey configury
^js/src/configure$
^js/src/old-configure$
^js/src/autom4te.cache$
# SpiderMonkey test result logs
^js/src/tests/results-.*\.(html|txt)$

View File

@ -27,12 +27,13 @@ addEventListener("DOMContentLoaded", function() {
var gDOMTitleChangedByUs = false;
addEventListener("DOMTitleChanged", function(e) {
if (!gDOMTitleChangedByUs) {
sendAsyncMessage("DOMTitleChanged", {
sendAsyncMessage("Social:DOMTitleChanged", {
title: e.target.title
});
}
gDOMTitleChangedByUs = false;
});
var gHookedWindowCloseForPanelClose = false;
// Error handling class used to listen for network errors in the social frames
// and replace them with a social-specific error page
@ -117,6 +118,10 @@ SocialErrorListener = {
sendAsyncMessage("Social:FocusEnsured");
break;
case "Social:HookWindowCloseForPanelClose":
if (gHookedWindowCloseForPanelClose) {
break;
}
gHookedWindowCloseForPanelClose = true;
// We allow window.close() to close the panel, so add an event handler for
// this, then cancel the event (so the window itself doesn't die) and
// close the panel instead.
@ -127,7 +132,6 @@ SocialErrorListener = {
dwu.allowScriptsToClose();
content.addEventListener("DOMWindowClose", function _mozSocialDOMWindowClose(evt) {
sendAsyncMessage("DOMWindowClose");
// preventDefault stops the default window.close() function being called,
// which doesn't actually close anything but causes things to get into
// a bad state (an internal 'closed' flag is set and debug builds start
@ -136,6 +140,8 @@ SocialErrorListener = {
// default close behaviour, so even if we took no action above, we avoid
// the default close from doing anything.
evt.preventDefault();
sendAsyncMessage("Social:DOMWindowClose");
}, true);
break;
case "Social:ListenForEvents":

View File

@ -81,7 +81,7 @@
this._callbacks = null;
}
mm.addMessageListener("DOMTitleChanged", this);
mm.addMessageListener("Social:DOMTitleChanged", this);
mm.sendAsyncMessage("WaitForDOMContentLoaded");
mm.addMessageListener("DOMContentLoaded", function DOMContentLoaded(event) {
@ -216,7 +216,7 @@
// attached to a browser, we'll need to add the message listeners to
// the new messageManager. This is not a bug in swapDocShells, merely
// a design decision.
content.messageManager.addMessageListener("DOMTitleChanged", content);
content.messageManager.addMessageListener("Social:DOMTitleChanged", content);
]]></body>
</method>
@ -326,7 +326,7 @@
<parameter name="aMessage" />
<body><![CDATA[
switch (aMessage.name) {
case "DOMTitleChanged":
case "Social:DOMTitleChanged":
this.setTitle();
break;
}

View File

@ -901,28 +901,6 @@ WebContentConverterRegistrarContent.prototype = {
// do nothing, the next branch might have values
}
}
// We need to do this _after_ registering all of the available handlers,
// so that getWebContentHandlerByURI can return successfully.
let autoBranch;
try {
autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
} catch (e) {
// No auto branch yet, that's fine
//LOG("WCCR.init: There is no auto branch, benign");
}
if (autoBranch) {
for (let type of autoBranch.getChildList("")) {
let uri = autoBranch.getCharPref(type);
if (uri) {
let handler = this.getWebContentHandlerByURI(type, uri);
if (handler) {
this._setAutoHandler(type, handler);
}
}
}
}
},
_typeIsRegistered(contentType, uri) {

View File

@ -49,7 +49,11 @@ EXTRA_JS_MODULES += [
]
BROWSER_CHROME_MANIFESTS += [
'test/browser.ini'
'tests/browser/browser.ini'
]
XPCSHELL_TESTS_MANIFESTS += [
'tests/unit/xpcshell.ini'
]
if CONFIG['MOZ_SAFE_BROWSING']:

View File

@ -404,7 +404,7 @@
var textBox = this._textbox;
// Save the current value in the form history
if (aData && !PrivateBrowsingUtils.isWindowPrivate(window)) {
if (aData && !PrivateBrowsingUtils.isWindowPrivate(window) && this.FormHistory.enabled) {
this.FormHistory.update(
{ op : "bump",
fieldname : textBox.getAttribute("autocompletesearchparam"),

View File

@ -1,5 +0,0 @@
{
"extends": [
"../../../testing/mochitest/browser.eslintrc"
]
}

View File

@ -0,0 +1,5 @@
{
"extends": [
"../../../../testing/mochitest/browser.eslintrc"
]
}

View File

@ -0,0 +1,32 @@
# Distribution Configuration File
# Test of distribution preferences
[Global]
id=disttest
version=1.0
about=Test distribution file
[Preferences]
distribution.test.string="Test String"
distribution.test.string.noquotes=Test String
distribution.test.int=777
distribution.test.bool.true=true
distribution.test.bool.false=false
[LocalizablePreferences]
distribution.test.locale="%LOCALE%"
distribution.test.reset="Set"
distribution.test.locale.set="First Set"
distribution.test.language.set="First Set"
[LocalizablePreferences-en]
distribution.test.language.en="en"
distribution.test.language.set="Second Set"
[LocalizablePreferences-en-US]
distribution.test.locale.en-US="en-US"
distribution.test.reset=
distribution.test.locale.set="Second Set"
[LocalizablePreferences-de]
distribution.test.locale.de="de"

View File

@ -0,0 +1,81 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that preferences are properly set by distribution.ini
*/
var Ci = Components.interfaces;
var Cc = Components.classes;
var Cr = Components.results;
var Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/LoadContextInfo.jsm");
// Import common head.
var commonFile = do_get_file("../../../../toolkit/components/places/tests/head_common.js", false);
if (commonFile) {
let uri = Services.io.newFileURI(commonFile);
Services.scriptloader.loadSubScript(uri.spec, this);
}
const TOPICDATA_DISTRIBUTION_CUSTOMIZATION = "force-distribution-customization";
const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
function run_test() {
// Set special pref to load distribution.ini from the profile folder.
Services.prefs.setBoolPref("distribution.testing.loadFromProfile", true);
// Copy distribution.ini file to the profile dir.
let distroDir = gProfD.clone();
distroDir.leafName = "distribution";
let iniFile = distroDir.clone();
iniFile.append("distribution.ini");
if (iniFile.exists()) {
iniFile.remove(false);
print("distribution.ini already exists, did some test forget to cleanup?");
}
let testDistributionFile = gTestDir.clone();
testDistributionFile.append("distribution.ini");
testDistributionFile.copyTo(distroDir, "distribution.ini");
Assert.ok(testDistributionFile.exists());
run_next_test();
}
do_register_cleanup(function () {
// Remove the distribution file, even if the test failed, otherwise all
// next tests will import it.
let iniFile = gProfD.clone();
iniFile.leafName = "distribution";
iniFile.append("distribution.ini");
if (iniFile.exists()) {
iniFile.remove(false);
}
Assert.ok(!iniFile.exists());
});
add_task(function* () {
// Force distribution.
let glue = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver)
glue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_DISTRIBUTION_CUSTOMIZATION);
Assert.equal(Services.prefs.getCharPref("distribution.test.string"), "Test String");
Assert.throws(() => Services.prefs.getCharPref("distribution.test.string.noquotes"));
Assert.equal(Services.prefs.getIntPref("distribution.test.int"), 777);
Assert.equal(Services.prefs.getBoolPref("distribution.test.bool.true"), true);
Assert.equal(Services.prefs.getBoolPref("distribution.test.bool.false"), false);
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale", Ci.nsIPrefLocalizedString).data, "en-US");
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.en", Ci.nsIPrefLocalizedString).data, "en");
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.en-US", Ci.nsIPrefLocalizedString).data, "en-US");
Assert.throws(() => Services.prefs.getComplexValue("distribution.test.locale.de", Ci.nsIPrefLocalizedString));
// This value was never set because of the empty locale specific pref
// This testcase currently fails - the value is set to "undefined" - it should not be set at all (throw)
// Assert.throws(() => Services.prefs.getComplexValue("distribution.test.reset", Ci.nsIPrefLocalizedString));
// This value was overriden by a locale specific setting
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Second Set");
// This value was overriden by a language specific setting
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.set", Ci.nsIPrefLocalizedString).data, "Second Set");
});

View File

@ -0,0 +1,7 @@
[DEFAULT]
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
distribution.ini
[test_distribution.js]

View File

@ -613,7 +613,9 @@ var MozLoopServiceInternal = {
2 * 32, true);
}
if (payloadObj) {
// Later versions of Firefox will do utf-8 encoding of the request, but
// we need to do it ourselves for older versions.
if (!gHawkClient.willUTF8EncodeRequests && payloadObj) {
// Note: we must copy the object rather than mutate it, to avoid
// mutating the values of the object passed in.
let newPayloadObj = {};
@ -999,7 +1001,7 @@ var MozLoopServiceInternal = {
// Handle window.close correctly on the chatbox.
mm.sendAsyncMessage("Social:HookWindowCloseForPanelClose");
messageName = "DOMWindowClose";
messageName = "Social:DOMWindowClose";
mm.addMessageListener(messageName, listeners[messageName] = () => {
// Remove message listeners.
for (let name of Object.getOwnPropertyNames(listeners)) {

View File

@ -12,12 +12,13 @@
Cu.import("resource://services-common/utils.js");
add_task(function* request_with_unicode() {
const unicodeName = "yøü";
// Note unicodeName must be unicode, not utf-8
const unicodeName = "y\xf8\xfc"; // "yøü"
loopServer.registerPathHandler("/fake", (request, response) => {
let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
let jsonBody = JSON.parse(body);
Assert.equal(jsonBody.name, CommonUtils.encodeUTF8(unicodeName));
let jsonBody = JSON.parse(CommonUtils.decodeUTF8(body));
Assert.equal(jsonBody.name, unicodeName);
response.setStatusLine(null, 200, "OK");
response.processAsync();

View File

@ -6,6 +6,7 @@ from marionette import MarionetteTestCase
import os
import sys
import time
import urlparse
sys.path.insert(1, os.path.dirname(os.path.abspath(__file__)))
@ -77,6 +78,8 @@ class Test1BrowserCall(MarionetteTestCase):
self.marionette.set_context("chrome")
self.marionette.switch_to_frame()
# Added time lapse to allow for DOM to catch up
time.sleep(2)
# XXX should be using wait_for_element_displayed, but need to wait
# for Marionette bug 1094246 to be fixed.
chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox')
@ -130,7 +133,7 @@ class Test1BrowserCall(MarionetteTestCase):
# Assumes the standalone or the conversation window is selected first.
def check_video(self, selector):
video = self.wait_for_element_displayed(By.CSS_SELECTOR,
selector, 20)
selector, 30)
self.wait_for_element_attribute_to_be_false(video, "paused")
self.assertEqual(video.get_attribute("ended"), "false")

View File

@ -198,7 +198,6 @@ var Chat = {
// even on platforms where getZOrderDOMWindowEnumerator is broken
// (ie. Linux). This will handle most cases, but won't work if the
// foreground window is a popup.
let mostRecent = Services.wm.getMostRecentWindow("navigator:browser");
if (isWindowGoodForChats(mostRecent))
return mostRecent;

View File

@ -375,16 +375,18 @@ this.ContentSearch = {
return Promise.resolve();
}
let browserData = this._suggestionDataForBrowser(msg.target, true);
FormHistory.update({
op: "bump",
fieldname: browserData.controller.formHistoryParam,
value: entry,
}, {
handleCompletion: () => {},
handleError: err => {
Cu.reportError("Error adding form history entry: " + err);
},
});
if (FormHistory.enabled) {
FormHistory.update({
op: "bump",
fieldname: browserData.controller.formHistoryParam,
value: entry,
}, {
handleCompletion: () => {},
handleError: err => {
Cu.reportError("Error adding form history entry: " + err);
},
});
}
return Promise.resolve();
},

View File

@ -46,7 +46,7 @@ this.Feeds = {
case "WCCR:setAutoHandler": {
let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
getService(Ci.nsIWebContentHandlerRegistrar);
getService(Ci.nsIWebContentConverterService);
registrar.setAutoHandler(data.contentType, data.handler);
break;
}

View File

@ -23,13 +23,8 @@ var ReaderParent = {
_readerModeInfoPanelOpen: false,
MESSAGES: [
"Reader:AddToList",
"Reader:ArticleGet",
"Reader:FaviconRequest",
"Reader:ListStatusRequest",
"Reader:RemoveFromList",
"Reader:Share",
"Reader:SystemUIVisibility",
"Reader:UpdateReaderButton",
"Reader:SetIntPref",
"Reader:SetCharPref",
@ -72,13 +67,6 @@ var ReaderParent = {
}
break;
}
case "Reader:Share":
// XXX: To implement.
break;
case "Reader:SystemUIVisibility":
// XXX: To implement.
break;
case "Reader:UpdateReaderButton": {
let browser = message.target;

View File

@ -35,18 +35,18 @@
"block-scoped-var": 2,
// Enforce one true brace style (opening brace on the same line) and avoid
// start and end braces on the same line.
"brace-style": [1, "1tbs", {"allowSingleLine": false}],
"brace-style": [2, "1tbs", {"allowSingleLine": false}],
// Require camel case names
"camelcase": 1,
"camelcase": 2,
// Allow trailing commas for easy list extension. Having them does not
// impair readability, but also not required either.
"comma-dangle": 0,
// Enforce spacing before and after comma
"comma-spacing": [1, {"before": false, "after": true}],
"comma-spacing": [2, {"before": false, "after": true}],
// Enforce one true comma style.
"comma-style": [1, "last"],
"comma-style": [2, "last"],
// Warn about cyclomatic complexity in functions.
"complexity": 1,
"complexity": 2,
// Require return statements to either always or never specify values.
"consistent-return": 2,
// Don't warn for inconsistent naming when capturing this (not so important
@ -58,7 +58,7 @@
// add a bogus default when you know all possible cases are handled.
"default-case": 0,
// Enforce dots on the next line with property name.
"dot-location": [1, "property"],
"dot-location": [2, "property"],
// Encourage the use of dot notation whenever possible.
"dot-notation": 2,
// Enforce newline at the end of file, with no multiple empty lines.
@ -77,22 +77,22 @@
// Deprecated, will be removed in 1.0.
"generator-star": 0,
// Enforce the spacing around the * in generator functions.
"generator-star-spacing": [1, "after"],
"generator-star-spacing": [2, "after"],
// Deprecated, will be removed in 1.0.
"global-strict": 0,
// Only useful in a node environment.
"handle-callback-err": 0,
// Tab width.
"indent": [1, 2, {"SwitchCase": 1}],
"indent": [2, 2, {"SwitchCase": 1}],
// Enforces spacing between keys and values in object literal properties.
"key-spacing": [1, {"beforeColon": false, "afterColon": true}],
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
// Allow mixed 'LF' and 'CRLF' as linebreaks.
"linebreak-style": 0,
// Don't enforce the maximum depth that blocks can be nested. The complexity
// rule is a better rule to check this.
"max-depth": 0,
// Maximum length of a line.
"max-len": [1, 80, 2, {"ignoreUrls": true, "ignorePattern": "\\s*require\\s*\\(|^\\s*loader\\.lazy|-\\*-"}],
"max-len": [2, 80, 2, {"ignoreUrls": true, "ignorePattern": "\\s*require\\s*\\(|^\\s*loader\\.lazy|-\\*-"}],
// Maximum depth callbacks can be nested.
"max-nested-callbacks": [2, 3],
// Don't limit the number of parameters that can be used in a function.
@ -115,7 +115,7 @@
"no-caller": 2,
// Disallow the catch clause parameter name being the same as a variable in
// the outer scope, to avoid confusion.
"no-catch-shadow": 1,
"no-catch-shadow": 2,
// Deprecated, will be removed in 1.0.
"no-comma-dangle": 0,
// Disallow assignment in conditional expressions.
@ -167,7 +167,7 @@
// Allow unnecessary parentheses, as they may make the code more readable.
"no-extra-parens": 0,
// Disallow unnecessary semicolons.
"no-extra-semi": 1,
"no-extra-semi": 2,
// Deprecated, will be removed in 1.0.
"no-extra-strict": 0,
// Disallow fallthrough of case statements, except if there is a comment.
@ -175,7 +175,7 @@
// Allow the use of leading or trailing decimal points in numeric literals.
"no-floating-decimal": 0,
// Disallow comments inline after code.
"no-inline-comments": 1,
"no-inline-comments": 2,
// Disallow if as the only statement in an else block.
"no-lonely-if": 2,
// Allow mixing regular variable and require declarations (not a node env).
@ -185,11 +185,11 @@
// Disallow use of multiple spaces (sometimes used to align const values,
// array or object items, etc.). It's hard to maintain and doesn't add that
// much benefit.
"no-multi-spaces": 1,
"no-multi-spaces": 2,
// Disallow use of multiline strings (use template strings instead).
"no-multi-str": 1,
"no-multi-str": 2,
// Disallow multiple empty lines.
"no-multiple-empty-lines": [1, {"max": 1}],
"no-multiple-empty-lines": [2, {"max": 1}],
// Disallow reassignments of native objects.
"no-native-reassign": 2,
// Disallow nested ternary expressions, they make the code hard to read.
@ -197,7 +197,7 @@
// Allow use of new operator with the require function.
"no-new-require": 0,
// Disallow use of octal literals.
"no-octal": 1,
"no-octal": 2,
// Allow reassignment of function parameters.
"no-param-reassign": 0,
// Allow string concatenation with __dirname and __filename (not a node env).
@ -232,13 +232,13 @@
// in a small helper function rather than having to come up with another
// random name.
// Still, making this a warning can help people avoid being confused.
"no-shadow": 1,
"no-shadow": 2,
// Disallow shadowing of names such as arguments.
"no-shadow-restricted-names": 2,
// Deprecated, will be removed in 1.0.
"no-space-before-semi": 0,
// Disallow space between function identifier and application.
"no-spaced-func": 1,
"no-spaced-func": 2,
// Disallow sparse arrays, eg. let arr = [,,2].
// Array destructuring is fine though:
// for (let [, breakpointPromise] of aPromises)
@ -283,47 +283,47 @@
// Allow more than one variable declaration per function.
"one-var": 0,
// Disallow padding within blocks.
"padded-blocks": [1, "never"],
"padded-blocks": [2, "never"],
// Don't require quotes around object literal property names.
"quote-props": 0,
// Double quotes should be used.
"quotes": [1, "double", "avoid-escape"],
"quotes": [2, "double", "avoid-escape"],
// Require use of the second argument for parseInt().
"radix": 2,
// Always require use of semicolons wherever they are valid.
"semi": [1, "always"],
"semi": [2, "always"],
// Enforce spacing after semicolons.
"semi-spacing": [1, {"before": false, "after": true}],
"semi-spacing": [2, {"before": false, "after": true}],
// Don't require to sort variables within the same declaration block.
// Anyway, one-var is disabled.
"sort-vars": 0,
// Deprecated, will be removed in 1.0.
"space-after-function-name": 0,
// Require a space after keywords.
"space-after-keywords": [1, "always"],
"space-after-keywords": [2, "always"],
// Require a space before the start brace of a block.
"space-before-blocks": [1, "always"],
"space-before-blocks": [2, "always"],
// Deprecated, will be removed in 1.0.
"space-before-function-parentheses": 0,
// Disallow space before function opening parenthesis.
"space-before-function-paren": [1, "never"],
"space-before-function-paren": [2, "never"],
// Disable the rule that checks if spaces inside {} and [] are there or not.
// Our code is split on conventions, and it'd be nice to have 2 rules
// instead, one for [] and one for {}. So, disabling until we write them.
"space-in-brackets": 0,
// Disallow spaces inside parentheses.
"space-in-parens": [1, "never"],
"space-in-parens": [2, "never"],
// Require spaces around operators, except for a|0.
"space-infix-ops": [1, {"int32Hint": true}],
"space-infix-ops": [2, {"int32Hint": true}],
// Require a space after return, throw, and case.
"space-return-throw-case": 1,
"space-return-throw-case": 2,
// Require spaces before/after unary operators (words on by default,
// nonwords off by default).
"space-unary-ops": [1, { "words": true, "nonwords": false }],
"space-unary-ops": [2, { "words": true, "nonwords": false }],
// Deprecated, will be removed in 1.0.
"space-unary-word-ops": 0,
// Require a space immediately following the // in a line comment.
"spaced-comment": [1, "always"],
"spaced-comment": [2, "always"],
// Require "use strict" to be defined globally in the script.
"strict": [2, "global"],
// Disallow comparisons with the value NaN.

View File

@ -3,7 +3,12 @@
/* 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/. */
/* animation-panel.js is loaded in the same scope but we don't use
import-globals-from to avoid infinite loops since animation-panel.js already
imports globals from animation-controller.js */
/* globals AnimationsPanel */
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
"use strict";
@ -15,10 +20,8 @@ Cu.import("resource://gre/modules/Console.jsm");
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");
loader.lazyRequireGetter(this, "promise");
loader.lazyRequireGetter(this, "EventEmitter",
"devtools/shared/event-emitter");
loader.lazyRequireGetter(this, "AnimationsFront",
"devtools/server/actors/animation", true);
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
loader.lazyRequireGetter(this, "AnimationsFront", "devtools/server/actors/animation", true);
const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);

View File

@ -3,6 +3,7 @@
/* 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/. */
/* import-globals-from animation-controller.js */
/* globals document */
@ -140,11 +141,12 @@ var AnimationsPanel = {
gToolbox.off("picker-started", this.onPickerStarted);
gToolbox.off("picker-stopped", this.onPickerStopped);
this.toggleAllButtonEl.removeEventListener("click", this.onToggleAllClicked);
this.playTimelineButtonEl.removeEventListener(
"click", this.onTimelinePlayClicked);
this.rewindTimelineButtonEl.removeEventListener(
"click", this.onTimelineRewindClicked);
this.toggleAllButtonEl.removeEventListener("click",
this.onToggleAllClicked);
this.playTimelineButtonEl.removeEventListener("click",
this.onTimelinePlayClicked);
this.rewindTimelineButtonEl.removeEventListener("click",
this.onTimelineRewindClicked);
document.removeEventListener("keydown", this.onKeyDown, false);

View File

@ -1,12 +1,16 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript 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/. */
"use strict";
const {Cu} = require("chrome");
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
const {
createNode,
TimeScale
} = require("devtools/client/animationinspector/utils");
const {createNode, TimeScale} = require("devtools/client/animationinspector/utils");
const {Keyframes} = require("devtools/client/animationinspector/components/keyframes");
/**
* UI component responsible for displaying detailed information for a given
* animation.

View File

@ -1,10 +1,15 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript 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/. */
"use strict";
const {Cu} = require("chrome");
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
const {DomNodePreview} = require(
"devtools/client/inspector/shared/dom-node-preview");
const {DomNodePreview} = require("devtools/client/inspector/shared/dom-node-preview");
// Map dom node fronts by animation fronts so we don't have to get them from the
// walker every time the timeline is refreshed.

View File

@ -1,11 +1,14 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript 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/. */
"use strict";
const {Cu} = require("chrome");
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");
const {
createNode,
TimeScale
} = require("devtools/client/animationinspector/utils");
const {createNode, TimeScale} = require("devtools/client/animationinspector/utils");
const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
@ -52,7 +55,7 @@ AnimationTimeBlock.prototype = {
let {x, iterationW, delayX, delayW, negativeDelayW} =
TimeScale.getAnimationDimensions(animation);
let iterations = createNode({
createNode({
parent: this.containerEl,
attributes: {
"class": "iterations" + (state.iterationCount ? "" : " infinite"),

View File

@ -1,3 +1,9 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript 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/. */
"use strict";
const {
@ -81,7 +87,8 @@ AnimationsTimeline.prototype = {
"class": "scrubber-handle"
}
});
this.scrubberHandleEl.addEventListener("mousedown", this.onScrubberMouseDown);
this.scrubberHandleEl.addEventListener("mousedown",
this.onScrubberMouseDown);
this.timeHeaderEl = createNode({
parent: this.rootWrapperEl,
@ -89,7 +96,8 @@ AnimationsTimeline.prototype = {
"class": "time-header track-container"
}
});
this.timeHeaderEl.addEventListener("mousedown", this.onScrubberMouseDown);
this.timeHeaderEl.addEventListener("mousedown",
this.onScrubberMouseDown);
this.animationsEl = createNode({
parent: this.rootWrapperEl,
@ -99,14 +107,16 @@ AnimationsTimeline.prototype = {
}
});
this.win.addEventListener("resize", this.onWindowResize);
this.win.addEventListener("resize",
this.onWindowResize);
},
destroy: function() {
this.stopAnimatingScrubber();
this.unrender();
this.win.removeEventListener("resize", this.onWindowResize);
this.win.removeEventListener("resize",
this.onWindowResize);
this.timeHeaderEl.removeEventListener("mousedown",
this.onScrubberMouseDown);
this.scrubberHandleEl.removeEventListener("mousedown",
@ -414,7 +424,8 @@ AnimationsTimeline.prototype = {
drawHeaderAndBackground: function() {
let width = this.timeHeaderEl.offsetWidth;
let animationDuration = TimeScale.maxEndTime - TimeScale.minStartTime;
let minTimeInterval = TIME_GRADUATION_MIN_SPACING * animationDuration / width;
let minTimeInterval = TIME_GRADUATION_MIN_SPACING *
animationDuration / width;
let intervalLength = findOptimalTimeInterval(minTimeInterval);
let intervalWidth = intervalLength * width / animationDuration;

View File

@ -1,3 +1,9 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript 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/. */
"use strict";
const {Cu} = require("chrome");

View File

@ -1,3 +1,9 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript 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/. */
"use strict";
const {Cu} = require("chrome");

View File

@ -10,10 +10,14 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8,welcome to the animation panel");
let {panel, controller} = yield openAnimationInspector();
ok(controller, "The animation controller exists");
ok(controller.animationsFront, "The animation controller has been initialized");
ok(panel, "The animation panel exists");
ok(panel.playersEl, "The animation panel has been initialized");
ok(panel.animationsTimelineComponent, "The animation panel has been initialized");
ok(controller,
"The animation controller exists");
ok(controller.animationsFront,
"The animation controller has been initialized");
ok(panel,
"The animation panel exists");
ok(panel.playersEl,
"The animation panel has been initialized");
ok(panel.animationsTimelineComponent,
"The animation panel has been initialized");
});

View File

@ -14,7 +14,8 @@ add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector();
info("Listen for the players-updated, ui-updated and inspector-updated events");
info("Listen for the players-updated, ui-updated and " +
"inspector-updated events");
let receivedEvents = [];
controller.once(controller.PLAYERS_UPDATED_EVENT, () => {
receivedEvents.push(controller.PLAYERS_UPDATED_EVENT);

View File

@ -8,11 +8,10 @@ requestLongerTimeout(2);
// Check that the timeline shows correct time graduations in the header.
const {
findOptimalTimeInterval,
TimeScale
} = require("devtools/client/animationinspector/utils");
// Should be kept in sync with TIME_GRADUATION_MIN_SPACING in animation-timeline.js
const {findOptimalTimeInterval, TimeScale} = require("devtools/client/animationinspector/utils");
// Should be kept in sync with TIME_GRADUATION_MIN_SPACING in
// animation-timeline.js
const TIME_GRADUATION_MIN_SPACING = 40;
add_task(function*() {

View File

@ -99,11 +99,12 @@ function waitForOutOfBoundScrubber({win, scrubberEl}) {
function waitForScrubberStopped(timeline) {
return new Promise(resolve => {
timeline.on("timeline-data-changed", function onTimelineData(e, {isMoving}) {
if (!isMoving) {
timeline.off("timeline-data-changed", onTimelineData);
resolve();
}
});
timeline.on("timeline-data-changed",
function onTimelineData(e, {isMoving}) {
if (!isMoving) {
timeline.off("timeline-data-changed", onTimelineData);
resolve();
}
});
});
}

View File

@ -16,6 +16,7 @@ add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel, controller} = yield openAnimationInspector();
let players = controller.animationPlayers;
let btn = panel.rewindTimelineButtonEl;
ok(btn, "The rewind button exists");
@ -26,9 +27,9 @@ add_task(function*() {
info("Check that the scrubber has stopped moving");
yield assertScrubberMoving(panel, false);
ok(controller.animationPlayers.every(({state}) => state.currentTime === 0),
ok(players.every(({state}) => state.currentTime === 0),
"All animations' currentTimes have been set to 0");
ok(controller.animationPlayers.every(({state}) => state.playState === "paused"),
ok(players.every(({state}) => state.playState === "paused"),
"All animations have been paused");
info("Play the animations again");
@ -43,8 +44,8 @@ add_task(function*() {
info("Check that the scrubber has stopped moving");
yield assertScrubberMoving(panel, false);
ok(controller.animationPlayers.every(({state}) => state.currentTime === 0),
ok(players.every(({state}) => state.currentTime === 0),
"All animations' currentTimes have been set to 0");
ok(controller.animationPlayers.every(({state}) => state.playState === "paused"),
ok(players.every(({state}) => state.playState === "paused"),
"All animations have been paused");
});

View File

@ -1,6 +1,7 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* globals addMessageListener, sendAsyncMessage */
"use strict";
@ -11,7 +12,8 @@
* @param {Object} data
* - {String} selector The CSS selector to get the node (can be a "super"
* selector).
* - {Number} animationIndex The index of the node's animationPlayers to play or pause
* - {Number} animationIndex The index of the node's animationPlayers to play
* or pause
* - {Boolean} pause True to pause the animation, false to play.
*/
addMessageListener("Test:ToggleAnimationPlayer", function(msg) {
@ -103,18 +105,18 @@ addMessageListener("Test:GetAnimationPlayerState", function(msg) {
* @param {String} superSelector.
* @return {DOMNode} The node, or null if not found.
*/
function superQuerySelector(superSelector, root=content.document) {
function superQuerySelector(superSelector, root = content.document) {
let frameIndex = superSelector.indexOf("||");
if (frameIndex === -1) {
return root.querySelector(superSelector);
} else {
let rootSelector = superSelector.substring(0, frameIndex).trim();
let childSelector = superSelector.substring(frameIndex+2).trim();
root = root.querySelector(rootSelector);
if (!root || !root.contentWindow) {
return null;
}
return superQuerySelector(childSelector, root.contentWindow.document);
}
let rootSelector = superSelector.substring(0, frameIndex).trim();
let childSelector = superSelector.substring(frameIndex + 2).trim();
root = root.querySelector(rootSelector);
if (!root || !root.contentWindow) {
return null;
}
return superQuerySelector(childSelector, root.contentWindow.document);
}

View File

@ -22,6 +22,8 @@
<div></div>
<div class="rate"></div>
<script>
"use strict";
var el = document.querySelector(".rate");
var ani = el.getAnimations()[0];
ani.playbackRate = 2;

View File

@ -42,13 +42,15 @@
<div class="ball css-transition"></div>
<script>
setTimeout(function(){
"use strict";
setTimeout(function() {
document.querySelector(".css-transition").style.backgroundColor = "yellow";
}, 0);
document.querySelector(".script-animation").animate([
{ opacity: 1, offset: 0 },
{ opacity: .1, offset: 1 }
{opacity: 1, offset: 0},
{opacity: .1, offset: 1}
], {
duration: 10000,
fill: "forwards"

View File

@ -45,6 +45,8 @@
<div class="zero"></div>
<div class="positive"></div>
<script>
"use strict";
var negative = document.querySelector(".negative");
var zero = document.querySelector(".zero");
var positive = document.querySelector(".positive");

View File

@ -1,6 +1,7 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
"use strict";
@ -114,7 +115,7 @@ function getNodeFront(selector, {walker}) {
* to highlight the node upon selection
* @return {Promise} Resolves when the inspector is updated with the new node
*/
var selectNode = Task.async(function*(data, inspector, reason="test") {
var selectNode = Task.async(function*(data, inspector, reason = "test") {
info("Selecting the node for '" + data + "'");
let nodeFront = data;
if (!data._form) {
@ -258,7 +259,7 @@ function hasSideBarTab(inspector, id) {
* @param {Boolean} useCapture Optional, for add/removeEventListener
* @return A promise that resolves when the event has been handled
*/
function once(target, eventName, useCapture=false) {
function once(target, eventName, useCapture = false) {
info("Waiting for event: '" + eventName + "' on " + target + ".");
let deferred = promise.defer();
@ -312,7 +313,8 @@ function waitForContentMessage(name) {
* @return {Promise} Resolves to the response data if a response is expected,
* immediately resolves otherwise
*/
function executeInContent(name, data={}, objects={}, expectResponse=true) {
function executeInContent(name, data = {}, objects = {},
expectResponse = true) {
info("Sending message " + name + " to content");
let mm = gBrowser.selectedBrowser.messageManager;
@ -327,7 +329,8 @@ function executeInContent(name, data={}, objects={}, expectResponse=true) {
/**
* Get the current playState of an animation player on a given node.
*/
var getAnimationPlayerState = Task.async(function*(selector, animationIndex=0) {
var getAnimationPlayerState = Task.async(function*(selector,
animationIndex = 0) {
let playState = yield executeInContent("Test:GetAnimationPlayerState",
{selector, animationIndex});
return playState;
@ -366,7 +369,6 @@ var waitForAllAnimationTargets = Task.async(function*(panel) {
*/
function* assertScrubberMoving(panel, isMoving) {
let timeline = panel.animationsTimelineComponent;
let scrubberEl = timeline.scrubberEl;
if (isMoving) {
// If we expect the scrubber to move, just wait for a couple of
@ -446,8 +448,8 @@ function* changeTimelinePlaybackRate(panel, rate) {
// Simulate a mousemove outside of the rate selector area to avoid subsequent
// tests from failing because of unwanted mouseover events.
EventUtils.synthesizeMouseAtCenter(win.document.querySelector("#timeline-toolbar"),
{type: "mousemove"}, win);
EventUtils.synthesizeMouseAtCenter(
win.document.querySelector("#timeline-toolbar"), {type: "mousemove"}, win);
}
/**
@ -519,6 +521,8 @@ function getKeyframeComponent(panel, animationIndex, propertyName) {
* @return {DOMNode} The keyframe element.
*/
function getKeyframeEl(panel, animationIndex, propertyName, keyframeIndex) {
let keyframeComponent = getKeyframeComponent(panel, animationIndex, propertyName);
return keyframeComponent.keyframesEl.querySelectorAll(".frame")[keyframeIndex];
let keyframeComponent = getKeyframeComponent(panel, animationIndex,
propertyName);
return keyframeComponent.keyframesEl
.querySelectorAll(".frame")[keyframeIndex];
}

View File

@ -9,7 +9,6 @@ var Cu = Components.utils;
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const {formatStopwatchTime} = require("devtools/client/animationinspector/utils");
const TEST_DATA = [{
desc: "Formatting 0",
time: 0,

View File

@ -8,10 +8,8 @@
const {Cu} = require("chrome");
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
var {loader} = Cu.import("resource://devtools/shared/Loader.jsm");
loader.lazyRequireGetter(this, "EventEmitter",
"devtools/shared/event-emitter");
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
@ -67,7 +65,8 @@ exports.createNode = createNode;
* Given a data-scale, draw the background for a graph (vertical lines) into a
* canvas and set that canvas as an image-element with an ID that can be used
* from CSS.
* @param {Document} document The document where the image-element should be set.
* @param {Document} document The document where the image-element should be
* set.
* @param {String} id The ID for the image-element.
* @param {Number} graphWidth The width of the graph.
* @param {Number} intervalWidth The width of one interval
@ -162,10 +161,10 @@ function formatStopwatchTime(time) {
let pad = (nb, max) => {
if (nb < max) {
return new Array((max+"").length - (nb+"").length + 1).join("0") + nb;
return new Array((max + "").length - (nb + "").length + 1).join("0") + nb;
}
return nb;
}
};
minutes = pad(minutes, 10);
seconds = pad(seconds, 10);

View File

@ -297,7 +297,9 @@ var DebuggerController = {
}
});
this.Workers.connect();
if (this._target.isTabActor) {
this.Workers.connect();
}
this.ThreadState.connect();
this.StackFrames.connect();

View File

@ -125,6 +125,8 @@ skip-if = e10s && debug
tags = addons
[browser_dbg_addon-sources.js]
tags = addons
[browser_dbg_addon-workers-dbg-enabled.js]
tags = addons
[browser_dbg_addon-modules.js]
skip-if = e10s # TODO
tags = addons

View File

@ -0,0 +1,39 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the Addon Debugger works when devtools.debugger.workers is enabled.
// Workers controller cannot be used when debugging an Addon actor.
const ADDON_URL = EXAMPLE_URL + "addon3.xpi";
function test() {
Task.spawn(function*() {
info("Enable worker debugging.");
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({
"set": [["devtools.debugger.workers", true]]
}, resolve);
});
let addon = yield addAddon(ADDON_URL);
let addonDebugger = yield initAddonDebugger(ADDON_URL);
is(addonDebugger.title, "Debugger - browser_dbg_addon3",
"Saw the right toolbox title.");
info("Check that groups and sources are displayed.");
let groups = yield addonDebugger.getSourceGroups();
is(groups.length, 2, "Should be only two groups.");
let sources = groups[0].sources;
is(sources.length, 2, "Should be two sources");
yield addonDebugger.destroy();
yield removeAddon(addon);
finish();
});
}

View File

@ -957,7 +957,7 @@ CssRuleView.prototype = {
let elementStyle = this._elementStyle;
return this._elementStyle.populate().then(() => {
if (this._elementStyle !== elementStyle || this.isDestroyed) {
return;
return null;
}
this._clearRules();
@ -1693,8 +1693,8 @@ RuleViewTool.prototype = {
let target = this.inspector.target;
if (Tools.styleEditor.isTargetSupported(target)) {
gDevTools.showToolbox(target, "styleeditor").then(function(toolbox) {
let sheet = source || href;
toolbox.getCurrentPanel().selectStyleSheet(sheet, line, column);
let url = source || href;
toolbox.getCurrentPanel().selectStyleSheet(url, line, column);
});
}
return;

View File

@ -22,12 +22,9 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testCancelNew(view);
});
function* testCancelNew(view) {
let elementRuleEditor = getRuleViewRuleEditor(view, 0);
let editor = yield focusEditableField(view, elementRuleEditor.closeBrace);
let editor = yield focusNewRuleViewProperty(elementRuleEditor);
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
"The new property editor got focused");
@ -37,12 +34,10 @@ function* testCancelNew(view) {
yield onBlur;
info("Checking the state of cancelling a new property name editor");
ok(!elementRuleEditor.rule._applyingModifications,
"Shouldn't have an outstanding request after a cancel.");
is(elementRuleEditor.rule.textProps.length, 0,
"Should have cancelled creating a new text property.");
ok(!elementRuleEditor.propertyList.hasChildNodes(),
"Should not have any properties.");
is(view.styleDocument.activeElement, view.styleDocument.documentElement,
"Correct element has focus");
}
});

View File

@ -21,59 +21,12 @@ add_task(function*() {
yield selectNode("#testid", inspector);
info("Test creating a new property and escaping");
let elementRuleEditor = getRuleViewRuleEditor(view, 1);
info("Focusing a new property name in the rule-view");
let editor = yield focusEditableField(view, elementRuleEditor.closeBrace);
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
"The new property editor got focused.");
info("Entering a value in the property name editor");
editor.input.value = "color";
info("Pressing return to commit and focus the new value field");
let onValueFocus = once(elementRuleEditor.element, "focus", true);
let onRuleViewChanged = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onValueFocus;
yield onRuleViewChanged;
// Getting the new value editor after focus
editor = inplaceEditor(view.styleDocument.activeElement);
let textProp = elementRuleEditor.rule.textProps[1];
is(elementRuleEditor.rule.textProps.length, 2,
"Created a new text property.");
is(elementRuleEditor.propertyList.children.length, 2,
"Created a property editor.");
is(editor, inplaceEditor(textProp.editor.valueSpan),
"Editing the value span now.");
info("Entering a property value");
editor.input.value = "red";
// Setting the input value above schedules a preview to be shown in 10ms
// which triggers a ruleview-changed event. If the event arrives at just the
// right moment after pressing escape but before the new property is removed
// from the rule view (it's done after a tick), the test continues too soon
// and the assertions below fail as the new property is still there (bug
// 1209295).
//
// Thus, wait for the ruleview-changed event triggered by the preview before
// continuing to discard the new property.
info("Waiting for preview to be applied.");
yield view.once("ruleview-changed");
info("Escaping out of the field");
onRuleViewChanged = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
yield onRuleViewChanged;
yield addProperty(view, 1, "color", "red", "VK_ESCAPE", false);
is(view.styleDocument.documentElement, view.styleDocument.activeElement,
"Correct element has focus");
let elementRuleEditor = getRuleViewRuleEditor(view, 1);
is(elementRuleEditor.rule.textProps.length, 1,
"Removed the new text property.");
is(elementRuleEditor.propertyList.children.length, 1,

View File

@ -9,29 +9,23 @@
const TEST_URI = `
<style type='text/css'>
#testid {
div {
background-color: blue;
}
.testclass {
background-color: green;
}
</style>
<div id='testid' class='testclass'>Styled Node</div>
<div>Test node</div>
`;
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testCancelNewOnEscape(inspector, view);
});
yield selectNode("div", inspector);
function* testCancelNewOnEscape(inspector, view) {
// Start at the beginning: start to add a rule to the element's style
// declaration, add some text, then press escape.
// Add a property to the element's style declaration, add some text,
// then press escape.
let elementRuleEditor = getRuleViewRuleEditor(view, 0);
let editor = yield focusEditableField(view, elementRuleEditor.closeBrace);
let elementRuleEditor = getRuleViewRuleEditor(view, 1);
let editor = yield focusNewRuleViewProperty(elementRuleEditor);
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
"Next focused editor should be the new property editor.");
@ -42,12 +36,8 @@ function* testCancelNewOnEscape(inspector, view) {
EventUtils.synthesizeKey("VK_ESCAPE", {});
yield onBlur;
ok(!elementRuleEditor.rule._applyingModifications,
"Shouldn't have an outstanding modification request after a cancel.");
is(elementRuleEditor.rule.textProps.length, 0,
is(elementRuleEditor.rule.textProps.length, 1,
"Should have canceled creating a new text property.");
ok(!elementRuleEditor.propertyList.hasChildNodes(),
"Should not have any properties.");
is(view.styleDocument.documentElement, view.styleDocument.activeElement,
"Correct element has focus");
}
});

View File

@ -13,49 +13,10 @@ add_task(function*() {
yield addTab(TEST_URL);
let {inspector, view} = yield openRuleView();
yield selectNode(TEST_SELECTOR, inspector);
yield testCreateNew(view);
});
function* testCreateNew(ruleView) {
info("Test creating a new property");
let elementRuleEditor = getRuleViewRuleEditor(ruleView, 0);
info("Focusing a new property name in the rule-view");
let editor = yield focusEditableField(ruleView, elementRuleEditor.closeBrace);
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
"Next focused editor should be the new property editor.");
let input = editor.input;
info("Entering the property name");
input.value = "fill";
info("Pressing RETURN and waiting for the value field focus");
let onFocus = once(elementRuleEditor.element, "focus", true);
EventUtils.sendKey("return", ruleView.styleWindow);
yield onFocus;
yield elementRuleEditor.rule._applyingModifications;
editor = inplaceEditor(ruleView.styleDocument.activeElement);
is(elementRuleEditor.rule.textProps.length, 1,
"Should have created a new text property.");
is(elementRuleEditor.propertyList.children.length, 1,
"Should have created a property editor.");
let textProp = elementRuleEditor.rule.textProps[0];
is(editor, inplaceEditor(textProp.editor.valueSpan),
"Should be editing the value span now.");
editor.input.value = "red";
let onBlur = once(editor.input, "blur");
EventUtils.sendKey("return", ruleView.styleWindow);
yield onBlur;
yield elementRuleEditor.rule._applyingModifications;
is(textProp.value, "red", "Text prop should have been changed.");
yield addProperty(view, 0, "fill", "red");
is((yield getComputedStyleProperty(TEST_SELECTOR, null, "fill")),
"rgb(255, 0, 0)", "The fill was changed to red");
}
"rgb(255, 0, 0)", "The fill was changed to red");
});

View File

@ -4,9 +4,7 @@
"use strict";
// Testing various inplace-editor behaviors in the rule-view
// FIXME: To be split in several test files, and some of the inplace-editor
// focus/blur/commit/revert stuff should be factored out in head.js
// Test adding an invalid property.
const TEST_URI = `
<style type='text/css'>
@ -24,51 +22,11 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testCreateNew(view);
});
function* testCreateNew(view) {
info("Test creating a new property");
let elementRuleEditor = getRuleViewRuleEditor(view, 0);
info("Focusing a new property name in the rule-view");
let editor = yield focusEditableField(view, elementRuleEditor.closeBrace);
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
"The new property editor got focused");
let input = editor.input;
info("Entering background-color in the property name editor");
input.value = "background-color";
info("Pressing return to commit and focus the new value field");
let onModifications = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onModifications;
// Getting the new value editor after focus
editor = inplaceEditor(view.styleDocument.activeElement);
let textProp = elementRuleEditor.rule.textProps[0];
is(elementRuleEditor.rule.textProps.length, 1,
"Created a new text property.");
is(elementRuleEditor.propertyList.children.length, 1,
"Created a property editor.");
is(editor, inplaceEditor(textProp.editor.valueSpan),
"Editing the value span now.");
ok(!textProp.editor.element.classList.contains("ruleview-overridden"),
"property should not be overridden.");
info("Entering a value and bluring the field to expect a rule change");
editor.input.value = "#XYZ";
onModifications = view.once("ruleview-changed");
editor.input.blur();
yield onModifications;
let textProp = yield addProperty(view, 0, "background-color", "#XYZ");
is(textProp.value, "#XYZ", "Text prop should have been changed.");
is(textProp.overridden, true, "Property should be overridden");
is(textProp.editor.isValid(), false, "#XYZ should not be a valid entry");
}
});

View File

@ -4,8 +4,7 @@
"use strict";
// Tests all sorts of additions and updates of properties in the rule-view.
// FIXME: TO BE SPLIT IN *MANY* SMALLER TESTS
//
const TEST_URI = `
<style type="text/css">
@ -23,37 +22,31 @@ const TEST_URI = `
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield testCreateNew(inspector, view);
});
function* testCreateNew(inspector, ruleView) {
// Create a new property.
let elementRuleEditor = getRuleViewRuleEditor(ruleView, 0);
let editor = yield focusEditableField(ruleView, elementRuleEditor.closeBrace);
info("Focus the new property name field");
let elementRuleEditor = getRuleViewRuleEditor(view, 0);
let editor = yield focusNewRuleViewProperty(elementRuleEditor);
let input = editor.input;
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
"Next focused editor should be the new property editor.");
let input = editor.input;
ok(input.selectionStart === 0 && input.selectionEnd === input.value.length,
"Editor contents are selected.");
// Try clicking on the editor's input again, shouldn't cause trouble
// (see bug 761665).
EventUtils.synthesizeMouse(input, 1, 1, {}, ruleView.styleWindow);
EventUtils.synthesizeMouse(input, 1, 1, {}, view.styleWindow);
input.select();
info("Entering the property name");
input.value = "background-color";
editor.input.value = "background-color";
info("Pressing RETURN and waiting for the value field focus");
let onFocus = once(elementRuleEditor.element, "focus", true);
EventUtils.sendKey("return", ruleView.styleWindow);
yield onFocus;
yield elementRuleEditor.rule._applyingModifications;
let onNameAdded = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onNameAdded;
editor = inplaceEditor(ruleView.styleDocument.activeElement);
editor = inplaceEditor(view.styleDocument.activeElement);
is(elementRuleEditor.rule.textProps.length, 1,
"Should have created a new text property.");
@ -63,12 +56,14 @@ function* testCreateNew(inspector, ruleView) {
is(editor, inplaceEditor(textProp.editor.valueSpan),
"Should be editing the value span now.");
info("Entering the property value");
// We're editing inline style, so expect a style attribute mutation.
let onMutated = inspector.once("markupmutation");
let onValueAdded = view.once("ruleview-changed");
editor.input.value = "purple";
let onBlur = once(editor.input, "blur");
EventUtils.sendKey("return", ruleView.styleWindow);
yield onBlur;
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onValueAdded;
yield onMutated;
is(textProp.value, "purple", "Text prop should have been changed.");
}
});

View File

@ -34,7 +34,7 @@ const TEST_DATA = [
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
let {inspector, view, testActor} = yield openRuleView();
for (let data of TEST_DATA) {
let {node, expected} = data;
@ -43,7 +43,8 @@ add_task(function*() {
yield testNewRule(view, expected, 1);
info("Resetting page content");
content.document.body.innerHTML = TEST_URI;
yield testActor.eval(
"content.document.body.innerHTML = `" + TEST_URI + "`;");
}
});

View File

@ -34,7 +34,7 @@ const TEST_DATA = [
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
let {inspector, view, testActor} = yield openRuleView();
for (let data of TEST_DATA) {
let {node, expected} = data;
@ -43,7 +43,8 @@ add_task(function*() {
yield testNewRule(view, expected, 1);
info("Resetting page content");
content.document.body.innerHTML = TEST_URI;
yield testActor.eval(
"content.document.body.innerHTML = `" + TEST_URI + "`;");
}
});

View File

@ -7,11 +7,11 @@
// Test for as-authored styles.
function* createTestContent(style) {
let content = `<style type="text/css">
let html = `<style type="text/css">
${style}
</style>
<div id="testid" class="testclass">Styled Node</div>`;
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(content));
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(html));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);

View File

@ -7,12 +7,12 @@
// Test for as-authored styles.
function* createTestContent(style) {
let content = `<style type="text/css">
let html = `<style type="text/css">
${style}
</style>
<div id="testid" class="testclass">Styled Node</div>`;
let tab = yield addTab("data:text/html;charset=utf-8," +
encodeURIComponent(content));
encodeURIComponent(html));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
@ -41,10 +41,8 @@ add_task(function* () {
swatch.click();
yield onShown;
let testNode = getNode("#testid");
yield simulateColorPickerChange(view, cPicker, [0, 255, 0, 1], {
element: testNode,
selector: "#testid",
name: "color",
value: "rgb(0, 255, 0)"
});

View File

@ -7,11 +7,11 @@
// Test for as-authored styles.
function* createTestContent(style) {
let content = `<style type="text/css">
let html = `<style type="text/css">
${style}
</style>
<div id="testid" class="testclass">Styled Node</div>`;
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(content));
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(html));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
@ -42,8 +42,7 @@ add_task(function* () {
is(prop.overridden, i !== 2, "check overridden for " + i);
}
rule.textProps[2].setEnabled(false);
yield rule._applyingModifications;
yield togglePropStatus(view, rule.textProps[2]);
// Now the first property should be active.
for (let i = 0; i < 3; ++i) {

View File

@ -46,10 +46,8 @@ function* basicTest(view, name, result) {
swatch.click();
yield onShown;
let testNode = getNode("#testid");
yield simulateColorPickerChange(view, cPicker, [0, 255, 0, 1], {
element: testNode,
selector: "#testid",
name: "color",
value: "rgb(0, 255, 0)"
});

View File

@ -39,8 +39,8 @@ function* testImageTooltipAfterColorChange(swatch, url, ruleView) {
swatch.click();
yield onShown;
yield simulateColorPickerChange(ruleView, picker, [0, 0, 0, 1], {
element: content.document.body,
name: "backgroundImage",
selector: "body",
name: "background-image",
value: 'url("chrome://global/skin/icons/warning-64.png"), linear-gradient(rgb(0, 0, 0), rgb(255, 0, 102) 400px)'
});

View File

@ -20,10 +20,6 @@ const TEST_URI = `
Testing the color picker tooltip!
`;
const PAGE_CONTENT = [
].join("\n");
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {view} = yield openRuleView();
@ -41,8 +37,8 @@ function* testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView) {
yield onShown;
yield simulateColorPickerChange(ruleView, picker, [0, 0, 0, 1], {
element: content.document.body,
name: "backgroundColor",
selector: "body",
name: "background-color",
value: "rgb(0, 0, 0)"
});

View File

@ -33,8 +33,8 @@ function* testPressingEnterCommitsChanges(swatch, ruleView) {
yield onShown;
yield simulateColorPickerChange(ruleView, cPicker, [0, 255, 0, .5], {
element: content.document.body,
name: "borderLeftColor",
selector: "body",
name: "border-left-color",
value: "rgba(0, 255, 0, 0.5)"
});
@ -51,7 +51,7 @@ function* testPressingEnterCommitsChanges(swatch, ruleView) {
yield onHidden;
yield onModified;
is(content.getComputedStyle(content.document.body).borderLeftColor,
is((yield getComputedStyleProperty("body", null, "border-left-color")),
"rgba(0, 255, 0, 0.5)", "The element's border was kept after RETURN");
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
"The color swatch's background was kept after RETURN");

View File

@ -51,23 +51,24 @@ function* testPickingNewColor(view) {
let swatchEl = ruleEl.valueSpan.querySelector(".ruleview-colorswatch");
let colorEl = ruleEl.valueSpan.querySelector(".ruleview-color");
info("Getting the color picker tooltip and clicking on the swatch to show it");
info("Get the color picker tooltip and clicking on the swatch to show it");
let cPicker = view.tooltips.colorPicker;
let onShown = cPicker.tooltip.once("shown");
swatchEl.click();
yield onShown;
let change = {
element: content.document.body,
name: "backgroundImage",
value: "linear-gradient(to left, rgb(1, 1, 1) 25%, rgb(51, 51, 51) 95%, rgb(0, 0, 0) 100%)"
selector: "body",
name: "background-image",
value: "linear-gradient(to left, rgb(1, 1, 1) 25%, " +
"rgb(51, 51, 51) 95%, rgb(0, 0, 0) 100%)"
};
yield simulateColorPickerChange(view, cPicker, [1, 1, 1, 1], change);
is(swatchEl.style.backgroundColor, "rgb(1, 1, 1)",
"The color swatch's background was updated");
is(colorEl.textContent, "#010101", "The color text was updated");
is(content.getComputedStyle(content.document.body).backgroundImage,
is((yield getComputedStyleProperty("body", null, "background-image")),
"linear-gradient(to left, rgb(1, 1, 1) 25%, rgb(51, 51, 51) 95%, " +
"rgb(0, 0, 0) 100%)",
"The gradient has been updated correctly");

View File

@ -55,7 +55,7 @@ function* testSimpleMultipleColorChanges(inspector, ruleView) {
];
for (let {rgba, computed} of colors) {
yield simulateColorPickerChange(ruleView, picker, rgba, {
element: content.document.querySelector("p"),
selector: "p",
name: "color",
value: computed
});
@ -83,8 +83,8 @@ function* testComplexMultipleColorChanges(inspector, ruleView) {
];
for (let {rgba, computed} of colors) {
yield simulateColorPickerChange(ruleView, picker, rgba, {
element: content.document.body,
name: "backgroundColor",
selector: "body",
name: "background-color",
value: computed
});
}
@ -114,11 +114,11 @@ function* testOverriddenMultipleColorChanges(inspector, ruleView) {
];
for (let {rgba, computed} of colors) {
yield simulateColorPickerChange(ruleView, picker, rgba, {
element: content.document.body,
selector: "body",
name: "color",
value: computed
});
is(content.getComputedStyle(content.document.querySelector("p")).color,
is((yield getComputedStyleProperty("p", null, "color")),
"rgb(200, 200, 200)", "The color of the P tag is still correct");
}
}

View File

@ -44,7 +44,8 @@ add_task(function*() {
info("Moving mouse over color picker without any buttons pressed.");
EventUtils.synthesizeMouse(spectrum.dragger, 10, 10, {
button: -1, // -1 = no buttons are pressed down
// -1 = no buttons are pressed down
button: -1,
type: "mousemove",
}, spectrum.dragger.ownerDocument.defaultView);
});

View File

@ -23,20 +23,12 @@ add_task(function*() {
});
function* testPressingEscapeRevertsChanges(view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let swatch = propEditor.valueSpan.querySelector(".ruleview-colorswatch");
let cPicker = view.tooltips.colorPicker;
let onShown = cPicker.tooltip.once("shown");
swatch.click();
yield onShown;
yield simulateColorPickerChange(view, cPicker, [0, 0, 0, 1], {
element: content.document.body,
name: "backgroundColor",
value: "rgb(0, 0, 0)"
});
let {swatch, propEditor, cPicker} = yield openColorPickerAndSelectColor(view,
1, 0, [0, 0, 0, 1], {
selector: "body",
name: "background-color",
value: "rgb(0, 0, 0)"
});
is(swatch.style.backgroundColor, "rgb(0, 0, 0)",
"The color swatch's background was updated");
@ -60,56 +52,50 @@ function* testPressingEscapeRevertsChanges(view) {
function* testPressingEscapeRevertsChangesAndDisables(view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let swatch = propEditor.valueSpan.querySelector(".ruleview-colorswatch");
let cPicker = view.tooltips.colorPicker;
info("Disabling background-color property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
let textProp = ruleEditor.rule.textProps[0];
yield togglePropStatus(view, textProp);
ok(propEditor.element.classList.contains("ruleview-overridden"),
ok(textProp.editor.element.classList.contains("ruleview-overridden"),
"property is overridden.");
is(propEditor.enable.style.visibility, "visible",
is(textProp.editor.enable.style.visibility, "visible",
"property enable checkbox is visible.");
ok(!propEditor.enable.getAttribute("checked"),
ok(!textProp.editor.enable.getAttribute("checked"),
"property enable checkbox is not checked.");
ok(!propEditor.prop.enabled,
ok(!textProp.editor.prop.enabled,
"background-color property is disabled.");
let newValue = yield getRulePropertyValue("background-color");
is(newValue, "", "background-color should have been unset.");
let onShown = cPicker.tooltip.once("shown");
swatch.click();
yield onShown;
let {cPicker} = yield openColorPickerAndSelectColor(view,
1, 0, [0, 0, 0, 1]);
ok(!propEditor.element.classList.contains("ruleview-overridden"),
ok(!textProp.editor.element.classList.contains("ruleview-overridden"),
"property overridden is not displayed.");
is(propEditor.enable.style.visibility, "hidden",
is(textProp.editor.enable.style.visibility, "hidden",
"property enable checkbox is hidden.");
let spectrum = yield cPicker.spectrum;
info("Simulating a color picker change in the widget");
spectrum.rgb = [0, 0, 0, 1];
yield ruleEditor.rule._applyingModifications;
info("Pressing ESCAPE to close the tooltip");
let onHidden = cPicker.tooltip.once("hidden");
let onModifications = view.once("ruleview-changed");
EventUtils.sendKey("ESCAPE", spectrum.element.ownerDocument.defaultView);
yield onHidden;
yield ruleEditor.rule._applyingModifications;
yield onModifications;
ok(propEditor.element.classList.contains("ruleview-overridden"),
ok(textProp.editor.element.classList.contains("ruleview-overridden"),
"property is overridden.");
is(propEditor.enable.style.visibility, "visible",
is(textProp.editor.enable.style.visibility, "visible",
"property enable checkbox is visible.");
ok(!propEditor.enable.getAttribute("checked"),
ok(!textProp.editor.enable.getAttribute("checked"),
"property enable checkbox is not checked.");
ok(!propEditor.prop.enabled,
ok(!textProp.editor.prop.enabled,
"background-color property is disabled.");
newValue = yield getRulePropertyValue("background-color");
is(newValue, "", "background-color should have been unset.");
is(propEditor.valueSpan.textContent, "#EDEDED",
is(textProp.editor.valueSpan.textContent, "#EDEDED",
"Got expected property value.");
}

View File

@ -58,13 +58,13 @@ const TEST_URI = "<h1 style='font: 24px serif'>Header</h1>";
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {toolbox, inspector, view} = yield openRuleView();
let {toolbox, inspector, view, testActor} = yield openRuleView();
info("Test autocompletion after 1st page load");
yield runAutocompletionTest(toolbox, inspector, view);
info("Test autocompletion after page navigation");
yield reloadPage(inspector);
yield reloadPage(inspector, testActor);
yield runAutocompletionTest(toolbox, inspector, view);
});
@ -78,17 +78,22 @@ function* runAutocompletionTest(toolbox, inspector, view) {
let editor = yield focusEditableField(view, propertyName);
info("Starting to test for css property completion");
let previousPopupSize = 0;
for (let i = 0; i < testData.length; i++) {
yield testCompletion(testData[i], editor, view);
let expectPopupHiddenEvent = previousPopupSize > 0 && testData[3] === 0;
yield testCompletion(testData[i], expectPopupHiddenEvent, editor, view);
previousPopupSize = testData[3];
}
}
function* testCompletion([key, completion, index, total], editor, view) {
function* testCompletion([key, completion, index, total],
expectPopupHiddenEvent, editor, view) {
info("Pressing key " + key);
info("Expecting " + completion + ", " + index + ", " + total);
// Listening for the right event that will tell us when the key has been
// entered and processed.
let onSuggest;
if (/(left|right|back_space|escape|home|end|page_up|page_down)/ig.test(key)) {
info("Adding event listener for " +
"left|right|back_space|escape|home|end|page_up|page_down keys");
@ -98,11 +103,16 @@ function* testCompletion([key, completion, index, total], editor, view) {
onSuggest = editor.once("after-suggest");
}
// Also listening for popup hiding if needed.
let onMaybePopupHidden = expectPopupHiddenEvent
? once(editor.popup._panel, "hidden")
: null;
info("Synthesizing key " + key);
EventUtils.synthesizeKey(key, {}, view.styleWindow);
yield onSuggest;
yield wait(1); // Equivalent of executeSoon
yield onMaybePopupHidden;
info("Checking the state");
if (completion != null) {

View File

@ -40,13 +40,13 @@ const TEST_URI = "<h1 style='color: red'>Header</h1>";
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {toolbox, inspector, view} = yield openRuleView();
let {toolbox, inspector, view, testActor} = yield openRuleView();
info("Test autocompletion after 1st page load");
yield runAutocompletionTest(toolbox, inspector, view);
info("Test autocompletion after page navigation");
yield reloadPage(inspector);
yield reloadPage(inspector, testActor);
yield runAutocompletionTest(toolbox, inspector, view);
});
@ -90,7 +90,7 @@ function* testCompletion([key, modifiers, completion, index, total], editor,
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
yield onKeyPress;
yield wait(1); // Equivalent of executeSoon
yield waitForTick();
// The key might have been a TAB or shift-TAB, in which case the editor will
// be a new one

View File

@ -41,13 +41,13 @@ const TEST_URI = "<h1 style='border: 1px solid red'>Header</h1>";
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {toolbox, inspector, view} = yield openRuleView();
let {toolbox, inspector, view, testActor} = yield openRuleView();
info("Test autocompletion after 1st page load");
yield runAutocompletionTest(toolbox, inspector, view);
info("Test autocompletion after page navigation");
yield reloadPage(inspector);
yield reloadPage(inspector, testActor);
yield runAutocompletionTest(toolbox, inspector, view);
});
@ -83,7 +83,7 @@ function* testCompletion([key, completion, index, total], editor, view) {
EventUtils.synthesizeKey(key, {}, view.styleWindow);
yield onSuggest;
yield wait(1); // Equivalent of executeSoon
yield waitForTick();
info("Checking the state");
if (completion != null) {

View File

@ -50,13 +50,13 @@ const TEST_URI = `
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {toolbox, inspector, view} = yield openRuleView();
let {toolbox, inspector, view, testActor} = yield openRuleView();
info("Test autocompletion after 1st page load");
yield runAutocompletionTest(toolbox, inspector, view);
info("Test autocompletion after page navigation");
yield reloadPage(inspector);
yield reloadPage(inspector, testActor);
yield runAutocompletionTest(toolbox, inspector, view);
});
@ -101,7 +101,7 @@ function* testCompletion([key, modifiers, completion, index, total], editor,
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
yield onKeyPress;
yield wait(1); // Equivalent of executeSoon
yield waitForTick();
info("Checking the state");
if (completion != null) {

View File

@ -10,7 +10,7 @@ const TEST_URI = "<h1 style='font: 24px serif'></h1>";
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
let {inspector, view, testActor} = yield openRuleView();
info("Test autocompletion popup is hidden after page navigation");
@ -28,12 +28,12 @@ add_task(function*() {
info("Waiting for autocomplete popup to be displayed");
yield onSuggest;
yield wait(1);
yield waitForTick();
ok(view.popup && view.popup.isOpen, "Popup should be opened");
info("Reloading the page");
yield reloadPage(inspector);
yield reloadPage(inspector, testActor);
ok(!(view.popup && view.popup.isOpen), "Popup should be closed");
});

View File

@ -31,7 +31,7 @@ function* testComputedList(inspector, view) {
ok(!expander.hasAttribute("open"), "margin computed list is closed");
info("Opening the computed list of margin property")
info("Opening the computed list of margin property");
expander.click();
ok(expander.hasAttribute("open"), "margin computed list is open");
@ -45,22 +45,28 @@ function* testComputedList(inspector, view) {
];
is(computed.length, propNames.length, "There should be 4 computed values");
is(computedDom.children.length, propNames.length, "There should be 4 nodes in the DOM");
is(computedDom.children.length, propNames.length,
"There should be 4 nodes in the DOM");
propNames.forEach((propName, i) => {
let propValue = i + "px";
is(computed[i].name, propName, "Computed property #" + i + " has name " + propName);
is(computed[i].value, propValue, "Computed property #" + i + " has value " + propValue);
is(computedDom.getElementsByClassName("ruleview-propertyname")[i].textContent, propName,
"Computed property #" + i + " in DOM has correct name");
is(computedDom.getElementsByClassName("ruleview-propertyvalue")[i].textContent, propValue,
"Computed property #" + i + " in DOM has correct value");
is(computed[i].name, propName,
"Computed property #" + i + " has name " + propName);
is(computed[i].value, propValue,
"Computed property #" + i + " has value " + propValue);
is(computedDom.querySelectorAll(".ruleview-propertyname")[i].textContent,
propName,
"Computed property #" + i + " in DOM has correct name");
is(computedDom.querySelectorAll(".ruleview-propertyvalue")[i].textContent,
propValue,
"Computed property #" + i + " in DOM has correct value");
});
info("Closing the computed list of margin property")
info("Closing the computed list of margin property");
expander.click();
ok(!expander.hasAttribute("open"), "margin computed list is closed");
info("Opening the computed list of margin property")
info("Opening the computed list of margin property");
expander.click();
ok(expander.hasAttribute("open"), "margin computed list is open");
is(computed.length, propNames.length, "Still 4 computed values");

View File

@ -6,49 +6,46 @@
// Test that the rule-view content is correct
const TEST_URI = `
<style type="text/css">
@media screen and (min-width: 10px) {
#testid {
background-color: blue;
}
}
.testclass, .unmatched {
background-color: green;
}
</style>
<div id="testid" class="testclass">Styled Node</div>
<div id="testid2">Styled Node</div>
`;
add_task(function*() {
yield addTab("data:text/html;charset=utf-8,browser_ruleview_content.js");
let {toolbox, inspector, view} = yield openRuleView();
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
info("Creating the test document");
let style = "" +
"@media screen and (min-width: 10px) {" +
" #testid {" +
" background-color: blue;" +
" }" +
"}" +
".testclass, .unmatched {" +
" background-color: green;" +
"}";
let styleNode = addStyle(content.document, style);
content.document.body.innerHTML = "<div id='testid' class='testclass'>Styled Node</div>" +
"<div id='testid2'>Styled Node</div>";
yield testContentAfterNodeSelection(inspector, view);
});
function* testContentAfterNodeSelection(inspector, ruleView) {
yield selectNode("#testid", inspector);
is(ruleView.element.querySelectorAll("#noResults").length, 0,
is(view.element.querySelectorAll("#noResults").length, 0,
"After a highlight, no longer has a no-results element.");
yield clearCurrentNodeSelection(inspector)
is(ruleView.element.querySelectorAll("#noResults").length, 1,
yield clearCurrentNodeSelection(inspector);
is(view.element.querySelectorAll("#noResults").length, 1,
"After highlighting null, has a no-results element again.");
yield selectNode("#testid", inspector);
let linkText = getRuleViewLinkTextByIndex(ruleView, 1);
is(linkText, "inline:1 @screen and (min-width: 10px)",
let linkText = getRuleViewLinkTextByIndex(view, 1);
is(linkText, "inline:3 @screen and (min-width: 10px)",
"link text at index 1 contains media query text.");
linkText = getRuleViewLinkTextByIndex(ruleView, 2);
is(linkText, "inline:1",
linkText = getRuleViewLinkTextByIndex(view, 2);
is(linkText, "inline:7",
"link text at index 2 contains no media query text.");
let classEditor = getRuleViewRuleEditor(ruleView, 2);
is(classEditor.selectorText.querySelector(".ruleview-selector-matched").textContent,
let selector = getRuleViewRuleEditor(view, 2).selectorText;
is(selector.querySelector(".ruleview-selector-matched").textContent,
".testclass", ".textclass should be matched.");
is(classEditor.selectorText.querySelector(".ruleview-selector-unmatched").textContent,
is(selector.querySelector(".ruleview-selector-unmatched").textContent,
".unmatched", ".unmatched should not be matched.");
}
});

View File

@ -1,19 +1,21 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* globals getTestActorWithoutToolbox */
"use strict";
// Test the rule-view content when the inspector gets opened via the page
// ctx-menu "inspect element"
const CONTENT = '<body style="color:red;">\
<div style="color:blue;">\
<p style="color:green;">\
<span style="color:yellow;">test element</span>\
</p>\
</div>\
</body>';
const CONTENT = `
<body style="color:red;">
<div style="color:blue;">
<p style="color:green;">
<span style="color:yellow;">test element</span>
</p>
</div>
</body>
`;
const STRINGS = Services.strings
.createBundle("chrome://devtools-shared/locale/styleinspector.properties");
@ -53,10 +55,12 @@ function checkRuleViewContent({styleDocument}) {
"The rule's selector is correct");
let propertyNames = [...rule.querySelectorAll(".ruleview-propertyname")];
is(propertyNames.length, 1, "There's only one property name, as expected");
is(propertyNames.length, 1,
"There's only one property name, as expected");
let propertyValues = [...rule.querySelectorAll(".ruleview-propertyvalue")];
is(propertyValues.length, 1, "There's only one property value, as expected");
is(propertyValues.length, 1,
"There's only one property value, as expected");
}
}

View File

@ -16,8 +16,6 @@
"use strict";
const {setBaseCssDocsUrl} = require("devtools/client/shared/widgets/MdnDocsWidget");
/**
* The test document tries to confuse the context menu
* code by having a tag called "padding" and a property

View File

@ -17,7 +17,8 @@
"use strict";
const {setBaseCssDocsUrl} = require("devtools/client/shared/widgets/MdnDocsWidget");
const {setBaseCssDocsUrl} =
require("devtools/client/shared/widgets/MdnDocsWidget");
const PROPERTYNAME = "color";
@ -70,6 +71,8 @@ function* testShowAndHideMdnTooltip(view) {
info("Quick check that the tooltip contents are set");
let cssDocs = view.tooltips.cssDocs;
// FIXME: Remove the comment below when bug 1246896 is fixed.
/* eslint-disable mozilla/no-cpows-in-tests */
let tooltipDocument = cssDocs.tooltip.content.contentDocument;
let h1 = tooltipDocument.getElementById("property-name");
is(h1.textContent, PROPERTYNAME, "The MDN docs tooltip h1 is correct");
@ -80,8 +83,3 @@ function* testShowAndHideMdnTooltip(view) {
yield onHidden;
ok(true, "The MDN docs tooltip was hidden on pressing 'escape'");
}
/**
* Returns the root element for the rule view.
*/
var rootElement = view => (view.element) ? view.element : view.styleDocument;

View File

@ -259,7 +259,7 @@ function* checkCopyStyle(view, node, menuItem, expectedPattern, hidden) {
try {
yield waitForClipboard(() => menuItem.click(),
() => checkClipboardData(expectedPattern));
} catch(e) {
} catch (e) {
failedClipboard(expectedPattern);
}
@ -268,11 +268,8 @@ function* checkCopyStyle(view, node, menuItem, expectedPattern, hidden) {
function* disableProperty(view, index) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[index].editor;
info("Disabling a property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
let textProp = ruleEditor.rule.textProps[index];
yield togglePropStatus(view, textProp);
}
function checkClipboardData(expectedPattern) {

View File

@ -39,9 +39,10 @@ function* testPressingEnterCommitsChanges(swatch, ruleView) {
widget.coordinates = [0.1, 2, 0.9, -1];
let expected = "cubic-bezier(0.1, 2, 0.9, -1)";
yield waitForSuccess(() => {
return content.getComputedStyle(content.document.body)
.transitionTimingFunction === expected;
yield waitForSuccess(function*() {
let func = yield getComputedStyleProperty("body", null,
"transition-timing-function");
return func === expected;
}, "Waiting for the change to be previewed on the element");
ok(getRuleViewProperty(ruleView, "body", "transition").valueSpan.textContent
@ -55,9 +56,11 @@ function* testPressingEnterCommitsChanges(swatch, ruleView) {
EventUtils.sendKey("RETURN", widget.parent.ownerDocument.defaultView);
yield onRuleViewChanged;
is(content.getComputedStyle(content.document.body).transitionTimingFunction,
expected, "The element's timing-function was kept after RETURN");
ok(getRuleViewProperty(ruleView, "body", "transition").valueSpan.textContent
.indexOf("cubic-bezier(") !== -1,
"The text of the timing-function was kept after RETURN");
let style = yield getComputedStyleProperty("body", null,
"transition-timing-function");
is(style, expected, "The element's timing-function was kept after RETURN");
let ruleViewStyle = getRuleViewProperty(ruleView, "body", "transition")
.valueSpan.textContent.indexOf("cubic-bezier(") !== -1;
ok(ruleViewStyle, "The text of the timing-function was kept after RETURN");
}

View File

@ -23,30 +23,17 @@ add_task(function*() {
});
function* testPressingEscapeRevertsChanges(view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let swatch = propEditor.valueSpan.querySelector(".ruleview-bezierswatch");
let bezierTooltip = view.tooltips.cubicBezier;
let {propEditor} = yield openCubicBezierAndChangeCoords(view, 1, 0,
[0.1, 2, 0.9, -1], {
selector: "body",
name: "animation-timing-function",
value: "cubic-bezier(0.1, 2, 0.9, -1)"
});
let onShown = bezierTooltip.tooltip.once("shown");
swatch.click();
yield onShown;
let widget = yield bezierTooltip.widget;
info("Simulating a change of curve in the widget");
widget.coordinates = [0.1, 2, 0.9, -1];
yield ruleEditor.rule._applyingModifications;
yield waitForComputedStyleProperty("body", null, "animation-timing-function",
"cubic-bezier(0.1, 2, 0.9, -1)");
is(propEditor.valueSpan.textContent, "cubic-bezier(.1,2,.9,-1)",
"Got expected property value.");
info("Pressing ESCAPE to close the tooltip");
let onHidden = bezierTooltip.tooltip.once("hidden");
EventUtils.sendKey("ESCAPE", widget.parent.ownerDocument.defaultView);
yield onHidden;
yield ruleEditor.rule._applyingModifications;
yield escapeTooltip(view);
yield waitForComputedStyleProperty("body", null, "animation-timing-function",
"linear");
@ -56,13 +43,11 @@ function* testPressingEscapeRevertsChanges(view) {
function* testPressingEscapeRevertsChangesAndDisables(view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let swatch = propEditor.valueSpan.querySelector(".ruleview-bezierswatch");
let bezierTooltip = view.tooltips.cubicBezier;
let textProp = ruleEditor.rule.textProps[0];
let propEditor = textProp.editor;
info("Disabling animation-timing-function property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
yield togglePropStatus(view, textProp);
ok(propEditor.element.classList.contains("ruleview-overridden"),
"property is overridden.");
@ -75,25 +60,9 @@ function* testPressingEscapeRevertsChangesAndDisables(view) {
let newValue = yield getRulePropertyValue("animation-timing-function");
is(newValue, "", "animation-timing-function should have been unset.");
let onShown = bezierTooltip.tooltip.once("shown");
swatch.click();
yield onShown;
yield openCubicBezierAndChangeCoords(view, 1, 0, [0.1, 2, 0.9, -1]);
ok(!propEditor.element.classList.contains("ruleview-overridden"),
"property overridden is not displayed.");
is(propEditor.enable.style.visibility, "hidden",
"property enable checkbox is hidden.");
let widget = yield bezierTooltip.widget;
info("Simulating a change of curve in the widget");
widget.coordinates = [0.1, 2, 0.9, -1];
yield ruleEditor.rule._applyingModifications;
info("Pressing ESCAPE to close the tooltip");
let onHidden = bezierTooltip.tooltip.once("hidden");
EventUtils.sendKey("ESCAPE", widget.parent.ownerDocument.defaultView);
yield onHidden;
yield ruleEditor.rule._applyingModifications;
yield escapeTooltip(view);
ok(propEditor.element.classList.contains("ruleview-overridden"),
"property is overridden.");
@ -117,3 +86,15 @@ function* getRulePropertyValue(name) {
});
return propValue;
}
function* escapeTooltip(view) {
info("Pressing ESCAPE to close the tooltip");
let bezierTooltip = view.tooltips.cubicBezier;
let widget = yield bezierTooltip.widget;
let onHidden = bezierTooltip.tooltip.once("hidden");
let onModifications = view.once("ruleview-changed");
EventUtils.sendKey("ESCAPE", widget.parent.ownerDocument.defaultView);
yield onHidden;
yield onModifications;
}

View File

@ -20,61 +20,53 @@ add_task(function*() {
function* simpleCustomOverride(inspector, view) {
yield selectNode("#testidSimple", inspector);
let elementStyle = view._elementStyle;
let idRule = getRuleViewRuleEditor(view, 1).rule;
let idRuleProp = idRule.textProps[0];
let idRule = elementStyle.rules[1];
let idProp = idRule.textProps[0];
is(idProp.name, "--background-color",
is(idRuleProp.name, "--background-color",
"First ID prop should be --background-color");
ok(!idProp.overridden, "ID prop should not be overridden.");
ok(!idRuleProp.overridden, "ID prop should not be overridden.");
let classRule = elementStyle.rules[2];
let classProp = classRule.textProps[0];
is(classProp.name, "--background-color",
let classRule = getRuleViewRuleEditor(view, 2).rule;
let classRuleProp = classRule.textProps[0];
is(classRuleProp.name, "--background-color",
"First class prop should be --background-color");
ok(classProp.overridden, "Class property should be overridden.");
ok(classRuleProp.overridden, "Class property should be overridden.");
// Override --background-color by changing the element style.
let elementRule = elementStyle.rules[0];
elementRule.createProperty("--background-color", "purple", "");
yield elementRule._applyingModifications;
let elementProp = yield addProperty(view, 0, "--background-color", "purple");
let elementProp = elementRule.textProps[0];
is(classProp.name, "--background-color",
is(classRuleProp.name, "--background-color",
"First element prop should now be --background-color");
ok(!elementProp.overridden,
"Element style property should not be overridden");
ok(idProp.overridden, "ID property should be overridden");
ok(classProp.overridden, "Class property should be overridden");
ok(idRuleProp.overridden, "ID property should be overridden");
ok(classRuleProp.overridden, "Class property should be overridden");
}
function* importantCustomOverride(inspector, view) {
yield selectNode("#testidImportant", inspector);
let elementStyle = view._elementStyle;
let idRule = getRuleViewRuleEditor(view, 1).rule;
let idRuleProp = idRule.textProps[0];
ok(idRuleProp.overridden, "Not-important rule should be overridden.");
let idRule = elementStyle.rules[1];
let idProp = idRule.textProps[0];
ok(idProp.overridden, "Not-important rule should be overridden.");
let classRule = elementStyle.rules[2];
let classProp = classRule.textProps[0];
ok(!classProp.overridden, "Important rule should not be overridden.");
let classRule = getRuleViewRuleEditor(view, 2).rule;
let classRuleProp = classRule.textProps[0];
ok(!classRuleProp.overridden, "Important rule should not be overridden.");
}
function* disableCustomOverride(inspector, view) {
yield selectNode("#testidDisable", inspector);
let elementStyle = view._elementStyle;
let idRule = getRuleViewRuleEditor(view, 1).rule;
let idRuleProp = idRule.textProps[0];
let idRule = elementStyle.rules[1];
let idProp = idRule.textProps[0];
yield togglePropStatus(view, idRuleProp);
idProp.setEnabled(false);
yield idRule._applyingModifications;
let classRule = elementStyle.rules[2];
let classProp = classRule.textProps[0];
ok(!classProp.overridden,
let classRule = getRuleViewRuleEditor(view, 2).rule;
let classRuleProp = classRule.textProps[0];
ok(!classRuleProp.overridden,
"Class prop should not be overridden after id prop was disabled.");
}

View File

@ -20,17 +20,13 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testEditPropertyAndCancel(inspector, view);
});
function* testEditPropertyAndCancel(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
yield focusEditableField(view, propEditor.nameSpan);
yield sendCharsAndWaitForFocus(view, ruleEditor.element,
["VK_DELETE", "VK_ESCAPE"]);
yield ruleEditor.rule._applyingModifications;
is(propEditor.nameSpan.textContent, "background-color",
"'background-color' property name is correctly set.");
@ -38,15 +34,16 @@ function* testEditPropertyAndCancel(inspector, view) {
"rgb(0, 0, 255)", "#00F background color is set.");
yield focusEditableField(view, propEditor.valueSpan);
let onValueDeleted = view.once("ruleview-changed");
yield sendCharsAndWaitForFocus(view, ruleEditor.element,
["VK_DELETE", "VK_ESCAPE"]);
yield ruleEditor.rule._applyingModifications;
yield onValueDeleted;
is(propEditor.valueSpan.textContent, "#00F",
"'#00F' property value is correctly set.");
is((yield getComputedStyleProperty("#testid", null, "background-color")),
"rgb(0, 0, 255)", "#00F background color is set.");
}
});
function* sendCharsAndWaitForFocus(view, element, chars) {
let onFocus = once(element, "focus", true);

View File

@ -7,9 +7,23 @@
// Test that increasing/decreasing values in rule view using
// arrow keys works correctly.
const TEST_URI = `
<style>
#test {
margin-top: 0px;
padding-top: 0px;
color: #000000;
background-color: #000000;
background: none;
transition: initial;
z-index: 0;
}
</style>
<div id="test"></div>
`;
add_task(function*() {
yield addTab("data:text/html;charset=utf-8,sample document for bug 722691");
createDocument();
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#test", inspector);
@ -23,22 +37,6 @@ add_task(function*() {
yield testZeroValueIncrements(view);
});
function createDocument() {
content.document.body.innerHTML = "" +
"<style>" +
" #test {" +
" margin-top:0px;" +
" padding-top: 0px;" +
" color:#000000;" +
" background-color: #000000;" +
" background: none;" +
" transition: initial;" +
" z-index: 0;" +
" }" +
"</style>" +
"<div id=\"test\"></div>";
}
function* testMarginIncrements(view) {
info("Testing keyboard increments on the margin property");
@ -53,7 +51,8 @@ function* testMarginIncrements(view) {
5: {down: true, start: "0px", end: "-1px", selectAll: true},
6: {down: true, shift: true, start: "0px", end: "-10px", selectAll: true},
7: {pageUp: true, shift: true, start: "0px", end: "100px", selectAll: true},
8: {pageDown: true, shift: true, start: "0px", end: "-100px", selectAll: true},
8: {pageDown: true, shift: true, start: "0px", end: "-100px",
selectAll: true},
9: {start: "0", end: "1px", selectAll: true},
10: {down: true, start: "0", end: "-1px", selectAll: true},
});
@ -92,7 +91,8 @@ function* testHexIncrements(view) {
3: {start: "#CCCCCC", end: "#CDCCCC", selection: [1, 3]},
4: {shift: true, start: "#CCCCCC", end: "#DCCCCC", selection: [1, 3]},
5: {start: "#FFFFFF", end: "#FFFFFF", selectAll: true},
6: {down: true, shift: true, start: "#000000", end: "#000000", selectAll: true}
6: {down: true, shift: true, start: "#000000", end: "#000000",
selectAll: true}
});
}
@ -104,11 +104,14 @@ function* testRgbIncrements(view) {
yield runIncrementTest(rgbColorPropEditor, view, {
1: {start: "rgb(0,0,0)", end: "rgb(0,1,0)", selection: [6, 7]},
2: {shift: true, start: "rgb(0,0,0)", end: "rgb(0,10,0)", selection: [6, 7]},
2: {shift: true, start: "rgb(0,0,0)", end: "rgb(0,10,0)",
selection: [6, 7]},
3: {start: "rgb(0,255,0)", end: "rgb(0,255,0)", selection: [6, 9]},
4: {shift: true, start: "rgb(0,250,0)", end: "rgb(0,255,0)", selection: [6, 9]},
4: {shift: true, start: "rgb(0,250,0)", end: "rgb(0,255,0)",
selection: [6, 9]},
5: {down: true, start: "rgb(0,0,0)", end: "rgb(0,0,0)", selection: [6, 7]},
6: {down: true, shift: true, start: "rgb(0,5,0)", end: "rgb(0,0,0)", selection: [6, 7]}
6: {down: true, shift: true, start: "rgb(0,5,0)", end: "rgb(0,0,0)",
selection: [6, 7]}
});
}
@ -120,14 +123,21 @@ function* testShorthandIncrements(view) {
yield runIncrementTest(paddingPropEditor, view, {
1: {start: "0px 0px 0px 0px", end: "0px 1px 0px 0px", selection: [4, 7]},
2: {shift: true, start: "0px 0px 0px 0px", end: "0px 10px 0px 0px", selection: [4, 7]},
2: {shift: true, start: "0px 0px 0px 0px", end: "0px 10px 0px 0px",
selection: [4, 7]},
3: {start: "0px 0px 0px 0px", end: "1px 0px 0px 0px", selectAll: true},
4: {shift: true, start: "0px 0px 0px 0px", end: "10px 0px 0px 0px", selectAll: true},
5: {down: true, start: "0px 0px 0px 0px", end: "0px 0px -1px 0px", selection: [8, 11]},
6: {down: true, shift: true, start: "0px 0px 0px 0px", end: "-10px 0px 0px 0px", selectAll: true},
7: {up: true, start: "0.1em .1em 0em 0em", end: "0.1em 1.1em 0em 0em", selection: [6, 9]},
8: {up: true, alt: true, start: "0.1em .9em 0em 0em", end: "0.1em 1em 0em 0em", selection: [6, 9]},
9: {up: true, shift: true, start: "0.2em .2em 0em 0em", end: "0.2em 10.2em 0em 0em", selection: [6, 9]}
4: {shift: true, start: "0px 0px 0px 0px", end: "10px 0px 0px 0px",
selectAll: true},
5: {down: true, start: "0px 0px 0px 0px", end: "0px 0px -1px 0px",
selection: [8, 11]},
6: {down: true, shift: true, start: "0px 0px 0px 0px",
end: "-10px 0px 0px 0px", selectAll: true},
7: {up: true, start: "0.1em .1em 0em 0em", end: "0.1em 1.1em 0em 0em",
selection: [6, 9]},
8: {up: true, alt: true, start: "0.1em .9em 0em 0em",
end: "0.1em 1em 0em 0em", selection: [6, 9]},
9: {up: true, shift: true, start: "0.2em .2em 0em 0em",
end: "0.2em 10.2em 0em 0em", selection: [6, 9]}
});
}
@ -145,13 +155,19 @@ function* testOddCases(view) {
5: {start: "'a=-1'", end: "'a=0'", selection: [4, 4]},
6: {start: "0 -1px", end: "0 0px", selection: [2, 2]},
7: {start: "url(-1)", end: "url(-1)", selection: [4, 4]},
8: {start: "url('test1.1.png')", end: "url('test1.2.png')", selection: [11, 11]},
8: {start: "url('test1.1.png')", end: "url('test1.2.png')",
selection: [11, 11]},
9: {start: "url('test1.png')", end: "url('test2.png')", selection: [9, 9]},
10: {shift: true, start: "url('test1.1.png')", end: "url('test11.1.png')", selection: [9, 9]},
11: {down: true, start: "url('test-1.png')", end: "url('test-2.png')", selection: [9, 11]},
12: {start: "url('test1.1.png')", end: "url('test1.2.png')", selection: [11, 12]},
13: {down: true, alt: true, start: "url('test-0.png')", end: "url('test--0.1.png')", selection: [10, 11]},
14: {alt: true, start: "url('test--0.1.png')", end: "url('test-0.png')", selection: [10, 14]},
10: {shift: true, start: "url('test1.1.png')", end: "url('test11.1.png')",
selection: [9, 9]},
11: {down: true, start: "url('test-1.png')", end: "url('test-2.png')",
selection: [9, 11]},
12: {start: "url('test1.1.png')", end: "url('test1.2.png')",
selection: [11, 12]},
13: {down: true, alt: true, start: "url('test-0.png')",
end: "url('test--0.1.png')", selection: [10, 11]},
14: {alt: true, start: "url('test--0.1.png')", end: "url('test-0.png')",
selection: [10, 14]}
});
}
@ -218,9 +234,15 @@ function* testIncrement(editor, options, view) {
let onRuleViewChanged = view.once("ruleview-changed");
let onKeyUp = once(input, "keyup");
let key;
key = options.down ? "VK_DOWN" : "VK_UP";
key = options.pageDown ? "VK_PAGE_DOWN" : options.pageUp ? "VK_PAGE_UP" : key;
if (options.pageDown) {
key = "VK_PAGE_DOWN";
} else if (options.pageUp) {
key = "VK_PAGE_UP";
}
EventUtils.synthesizeKey(key, {altKey: options.alt, shiftKey: options.shift},
view.styleWindow);
yield onKeyUp;

View File

@ -6,77 +6,84 @@
// Checking properties orders and overrides in the rule-view.
const TEST_URI = "<div id='testid'>Styled Node</div>";
const TEST_URI = "<style>#testid {}</style><div id='testid'>Styled Node</div>";
add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
let element = getNode("#testid");
let elementStyle = view._elementStyle;
let elementRule = elementStyle.rules[0];
let elementRule = elementStyle.rules[1];
info("Checking rules insertion order and checking the applied style");
let firstProp = elementRule.createProperty("background-color", "green", "");
let secondProp = elementRule.createProperty("background-color", "blue", "");
is(elementRule.textProps[0], firstProp, "Rules should be in addition order.");
let firstProp = yield addProperty(view, 1, "background-color", "green");
let secondProp = yield addProperty(view, 1, "background-color", "blue");
is(elementRule.textProps[0], firstProp,
"Rules should be in addition order.");
is(elementRule.textProps[1], secondProp,
"Rules should be in addition order.");
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "blue",
"Second property should have been used.");
"Rules should be in addition order.");
// rgb(0, 0, 255) = blue
is((yield getValue("#testid", "background-color")), "rgb(0, 0, 255)",
"Second property should have been used.");
info("Removing the second property and checking the applied style again");
secondProp.remove();
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "green",
"After deleting second property, first should be used.");
yield removeProperty(view, secondProp);
// rgb(0, 128, 0) = green
is((yield getValue("#testid", "background-color")), "rgb(0, 128, 0)",
"After deleting second property, first should be used.");
info("Creating a new second property and checking that the insertion order " +
"is still the same");
secondProp = elementRule.createProperty("background-color", "blue", "");
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "blue",
"New property should be used.");
"is still the same");
secondProp = yield addProperty(view, 1, "background-color", "blue");
is((yield getValue("#testid", "background-color")), "rgb(0, 0, 255)",
"New property should be used.");
is(elementRule.textProps[0], firstProp,
"Rules shouldn't have switched places.");
"Rules shouldn't have switched places.");
is(elementRule.textProps[1], secondProp,
"Rules shouldn't have switched places.");
"Rules shouldn't have switched places.");
info("Disabling the second property and checking the applied style");
secondProp.setEnabled(false);
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "green",
"After disabling second property, first value should be used");
yield togglePropStatus(view, secondProp);
is((yield getValue("#testid", "background-color")), "rgb(0, 128, 0)",
"After disabling second property, first value should be used");
info("Disabling the first property too and checking the applied style");
firstProp.setEnabled(false);
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "",
"After disabling both properties, value should be empty.");
yield togglePropStatus(view, firstProp);
is((yield getValue("#testid", "background-color")), "transparent",
"After disabling both properties, value should be empty.");
info("Re-enabling the second propertyt and checking the applied style");
secondProp.setEnabled(true);
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "blue",
"Value should be set correctly after re-enabling");
yield togglePropStatus(view, secondProp);
is((yield getValue("#testid", "background-color")), "rgb(0, 0, 255)",
"Value should be set correctly after re-enabling");
info("Re-enabling the first property and checking the insertion order " +
"is still respected");
firstProp.setEnabled(true);
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "blue",
"Re-enabling an earlier property shouldn't make it override " +
"a later property.");
is(elementRule.textProps[0], firstProp,
"Rules shouldn't have switched places.");
is(elementRule.textProps[1], secondProp,
"Rules shouldn't have switched places.");
"is still respected");
yield togglePropStatus(view, firstProp);
is((yield getValue("#testid", "background-color")), "rgb(0, 0, 255)",
"Re-enabling an earlier property shouldn't make it override " +
"a later property.");
is(elementRule.textProps[0], firstProp,
"Rules shouldn't have switched places.");
is(elementRule.textProps[1], secondProp,
"Rules shouldn't have switched places.");
info("Modifying the first property and checking the applied style");
firstProp.setValue("purple", "");
yield elementRule._applyingModifications;
is(element.style.getPropertyValue("background-color"), "blue",
"Modifying an earlier property shouldn't override a later property.");
yield setProperty(view, firstProp, "purple");
is((yield getValue("#testid", "background-color")), "rgb(0, 0, 255)",
"Modifying an earlier property shouldn't override a later property.");
});
function* getValue(selector, propName) {
let value = yield getComputedStyleProperty(selector, null, propName);
return value;
}

View File

@ -22,17 +22,13 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testEditPropertyAndRemove(inspector, view);
});
function* testEditPropertyAndRemove(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
info("Getting the first property in the #testid rule");
let rule = getRuleViewRuleEditor(view, 1).rule;
let prop = rule.textProps[0];
yield focusEditableField(view, propEditor.nameSpan);
yield sendKeysAndWaitForFocus(view, ruleEditor.element,
["VK_DELETE", "VK_RETURN"]);
yield ruleEditor.rule._applyingModifications;
info("Deleting the name of that property to remove the property");
yield removeProperty(view, prop, false);
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -41,15 +37,16 @@ function* testEditPropertyAndRemove(inspector, view) {
});
is(newValue, "", "background-color should have been unset.");
propEditor = ruleEditor.rule.textProps[0].editor;
info("Getting the new first property in the rule");
prop = rule.textProps[0];
let editor = inplaceEditor(view.styleDocument.activeElement);
is(inplaceEditor(propEditor.nameSpan), editor,
is(inplaceEditor(prop.editor.nameSpan), editor,
"Focus should have moved to the next property name");
yield sendKeysAndWaitForFocus(view, ruleEditor.element,
["VK_DELETE", "VK_RETURN"]);
yield ruleEditor.rule._applyingModifications;
info("Deleting the name of that property to remove the property");
view.styleDocument.activeElement.blur();
yield removeProperty(view, prop, false);
newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -59,18 +56,12 @@ function* testEditPropertyAndRemove(inspector, view) {
is(newValue, "", "color should have been unset.");
editor = inplaceEditor(view.styleDocument.activeElement);
is(inplaceEditor(ruleEditor.newPropSpan), editor,
is(inplaceEditor(rule.editor.newPropSpan), editor,
"Focus should have moved to the new property span");
is(ruleEditor.rule.textProps.length, 0,
is(rule.textProps.length, 0,
"All properties should have been removed.");
is(ruleEditor.propertyList.children.length, 1,
is(rule.editor.propertyList.children.length, 1,
"Should have the new property span.");
}
function* sendKeysAndWaitForFocus(view, element, keys) {
let onFocus = once(element, "focus", true);
for (let key of keys) {
EventUtils.synthesizeKey(key, {}, view.styleWindow);
}
yield onFocus;
}
view.styleDocument.activeElement.blur();
});

View File

@ -22,17 +22,13 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testEditPropertyAndRemove(inspector, view);
});
function* testEditPropertyAndRemove(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
info("Getting the first property in the rule");
let rule = getRuleViewRuleEditor(view, 1).rule;
let prop = rule.textProps[0];
yield focusEditableField(view, propEditor.valueSpan);
yield sendKeysAndWaitForFocus(view, ruleEditor.element,
["VK_DELETE", "VK_RETURN"]);
yield ruleEditor.rule._applyingModifications;
info("Clearing the property value");
yield setProperty(view, prop, null, false);
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -41,17 +37,16 @@ function* testEditPropertyAndRemove(inspector, view) {
});
is(newValue, "", "background-color should have been unset.");
propEditor = ruleEditor.rule.textProps[0].editor;
info("Getting the new first property in the rule");
prop = rule.textProps[0];
let editor = inplaceEditor(view.styleDocument.activeElement);
is(inplaceEditor(propEditor.nameSpan), editor,
is(inplaceEditor(prop.editor.nameSpan), editor,
"Focus should have moved to the next property name");
view.styleDocument.activeElement.blur();
info("Focus the property value and remove the property");
let onChanged = view.once("ruleview-changed");
yield sendKeysAndWaitForFocus(view, ruleEditor.element,
["VK_TAB", "VK_DELETE", "VK_RETURN"]);
yield onChanged;
info("Clearing the property value");
yield setProperty(view, prop, null, false);
newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -61,18 +56,12 @@ function* testEditPropertyAndRemove(inspector, view) {
is(newValue, "", "color should have been unset.");
editor = inplaceEditor(view.styleDocument.activeElement);
is(inplaceEditor(ruleEditor.newPropSpan), editor,
is(inplaceEditor(rule.editor.newPropSpan), editor,
"Focus should have moved to the new property span");
is(ruleEditor.rule.textProps.length, 0,
is(rule.textProps.length, 0,
"All properties should have been removed.");
is(ruleEditor.propertyList.children.length, 1,
is(rule.editor.propertyList.children.length, 1,
"Should have the new property span.");
}
function* sendKeysAndWaitForFocus(view, element, keys) {
let onFocus = once(element, "focus", true);
for (let key of keys) {
EventUtils.synthesizeKey(key, {}, view.styleWindow);
}
yield onFocus;
}
view.styleDocument.activeElement.blur();
});

View File

@ -22,19 +22,17 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testEditPropertyAndRemove(inspector, view);
});
function* testEditPropertyAndRemove(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[1].editor;
info("Getting the second property in the rule");
let rule = getRuleViewRuleEditor(view, 1).rule;
let prop = rule.textProps[1];
yield focusEditableField(view, propEditor.valueSpan);
yield sendKeysAndWaitForFocus(view, ruleEditor.element, [
{ key: "VK_DELETE", modifiers: {} },
{ key: "VK_TAB", modifiers: { shiftKey: true } }
]);
yield ruleEditor.rule._applyingModifications;
info("Clearing the property value and pressing shift-tab");
let editor = yield focusEditableField(view, prop.editor.valueSpan);
let onValueDone = view.once("ruleview-changed");
editor.input.value = "";
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true}, view.styleWindow);
yield onValueDone;
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -42,28 +40,31 @@ function* testEditPropertyAndRemove(inspector, view) {
name: "color"
});
is(newValue, "", "color should have been unset.");
is(propEditor.valueSpan.textContent, "",
is(prop.editor.valueSpan.textContent, "",
"'' property value is correctly set.");
yield sendKeysAndWaitForFocus(view, ruleEditor.element, [
{ key: "VK_TAB", modifiers: { shiftKey: true } }
]);
yield ruleEditor.rule._applyingModifications;
info("Pressing shift-tab again to focus the previous property value");
let onValueFocused = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true}, view.styleWindow);
yield onValueFocused;
propEditor = ruleEditor.rule.textProps[0].editor;
info("Getting the first property in the rule");
prop = rule.textProps[0];
let editor = inplaceEditor(view.styleDocument.activeElement);
is(inplaceEditor(propEditor.valueSpan), editor,
editor = inplaceEditor(view.styleDocument.activeElement);
is(inplaceEditor(prop.editor.valueSpan), editor,
"Focus should have moved to the previous property value");
info("Focus the property name and remove the property");
yield sendKeysAndWaitForFocus(view, ruleEditor.element, [
{ key: "VK_TAB", modifiers: { shiftKey: true } },
{ key: "VK_DELETE", modifiers: {} },
{ key: "VK_TAB", modifiers: { shiftKey: true } }
]);
info("Pressing shift-tab again to focus the property name");
let onNameFocused = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true}, view.styleWindow);
yield onNameFocused;
yield ruleEditor.rule._applyingModifications;
info("Removing the name and pressing shift-tab to focus the selector");
let onNameDeleted = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_DELETE", {}, view.styleWindow);
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true}, view.styleWindow);
yield onNameDeleted;
newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -73,18 +74,10 @@ function* testEditPropertyAndRemove(inspector, view) {
is(newValue, "", "background-color should have been unset.");
editor = inplaceEditor(view.styleDocument.activeElement);
is(inplaceEditor(ruleEditor.selectorText), editor,
is(inplaceEditor(rule.editor.selectorText), editor,
"Focus should have moved to the selector text.");
is(ruleEditor.rule.textProps.length, 0,
is(rule.textProps.length, 0,
"All properties should have been removed.");
ok(!ruleEditor.propertyList.hasChildNodes(),
ok(!rule.editor.propertyList.hasChildNodes(),
"Should not have any properties.");
}
function* sendKeysAndWaitForFocus(view, element, keys) {
let onFocus = once(element, "focus", true);
for (let {key, modifiers} of keys) {
EventUtils.synthesizeKey(key, modifiers, view.styleWindow);
}
yield onFocus;
}
});

View File

@ -36,46 +36,46 @@ add_task(function*() {
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 1);
let rule = getRuleViewRuleEditor(view, 1).rule;
for (let {name, value, isValid} of TEST_DATA) {
yield testEditProperty(ruleEditor, name, value, isValid);
yield testEditProperty(view, rule, name, value, isValid);
}
});
function* testEditProperty(ruleEditor, name, value, isValid) {
function* testEditProperty(view, rule, name, value, isValid) {
info("Test editing existing property name/value fields");
let doc = ruleEditor.doc;
let propEditor = ruleEditor.rule.textProps[0].editor;
let doc = rule.editor.doc;
let prop = rule.textProps[0];
info("Focusing an existing property name in the rule-view");
let editor = yield focusEditableField(ruleEditor.ruleView,
propEditor.nameSpan, 32, 1);
let editor = yield focusEditableField(view, prop.editor.nameSpan, 32, 1);
is(inplaceEditor(propEditor.nameSpan), editor,
is(inplaceEditor(prop.editor.nameSpan), editor,
"The property name editor got focused");
let input = editor.input;
info("Entering a new property name, including : to commit and " +
"focus the value");
let onValueFocus = once(ruleEditor.element, "focus", true);
let onModifications = ruleEditor.ruleView.once("ruleview-changed");
let onValueFocus = once(rule.editor.element, "focus", true);
let onNameDone = view.once("ruleview-changed");
EventUtils.sendString(name + ":", doc.defaultView);
yield onValueFocus;
yield onModifications;
yield onNameDone;
// Getting the value editor after focus
editor = inplaceEditor(doc.activeElement);
input = editor.input;
is(inplaceEditor(propEditor.valueSpan), editor, "Focus moved to the value.");
is(inplaceEditor(prop.editor.valueSpan), editor, "Focus moved to the value.");
info("Entering a new value, including ; to commit and blur the value");
let onValueDone = view.once("ruleview-changed");
let onBlur = once(input, "blur");
EventUtils.sendString(value + ";", doc.defaultView);
yield onBlur;
yield ruleEditor.rule._applyingModifications;
yield onValueDone;
is(propEditor.isValid(), isValid,
is(prop.editor.isValid(), isValid,
value + " is " + isValid ? "valid" : "invalid");
info("Checking that the style property was changed on the content page");
@ -90,10 +90,4 @@ function* testEditProperty(ruleEditor, name, value, isValid) {
} else {
isnot(propValue, value, name + " shouldn't have been set.");
}
info("Wait for remaining modifications to be applied");
yield ruleEditor.rule._applyingModifications;
is(ruleEditor.rule._applyingModifications, null,
"Reference to rule modification promise was removed after completion");
}

View File

@ -30,12 +30,12 @@ add_task(function*() {
});
function* testEditProperty(inspector, ruleView) {
let idRuleEditor = getRuleViewRuleEditor(ruleView, 1);
let propEditor = idRuleEditor.rule.textProps[0].editor;
let idRule = getRuleViewRuleEditor(ruleView, 1).rule;
let prop = idRule.textProps[0];
let editor = yield focusEditableField(ruleView, propEditor.nameSpan);
let editor = yield focusEditableField(ruleView, prop.editor.nameSpan);
let input = editor.input;
is(inplaceEditor(propEditor.nameSpan), editor,
is(inplaceEditor(prop.editor.nameSpan), editor,
"Next focused editor should be the name editor.");
ok(input.selectionStart === 0 && input.selectionEnd === input.value.length,
@ -48,15 +48,16 @@ function* testEditProperty(inspector, ruleView) {
info("Entering property name \"border-color\" followed by a colon to " +
"focus the value");
let onFocus = once(idRuleEditor.element, "focus", true);
let onNameDone = ruleView.once("ruleview-changed");
let onFocus = once(idRule.editor.element, "focus", true);
EventUtils.sendString("border-color:", ruleView.styleWindow);
yield onFocus;
yield idRuleEditor.rule._applyingModifications;
yield onNameDone;
info("Verifying that the focused field is the valueSpan");
editor = inplaceEditor(ruleView.styleDocument.activeElement);
input = editor.input;
is(inplaceEditor(propEditor.valueSpan), editor,
is(inplaceEditor(prop.editor.valueSpan), editor,
"Focus should have moved to the value.");
ok(input.selectionStart === 0 && input.selectionEnd === input.value.length,
"Editor contents are selected.");
@ -64,14 +65,15 @@ function* testEditProperty(inspector, ruleView) {
info("Entering a value following by a semi-colon to commit it");
let onBlur = once(editor.input, "blur");
// Use sendChar() to pass each character as a string so that we can test
// propEditor.warning.hidden after each character.
// prop.editor.warning.hidden after each character.
for (let ch of "red;") {
let onPreviewDone = ruleView.once("ruleview-changed");
EventUtils.sendChar(ch, ruleView.styleWindow);
is(propEditor.warning.hidden, true,
yield onPreviewDone;
is(prop.editor.warning.hidden, true,
"warning triangle is hidden or shown as appropriate");
}
yield onBlur;
yield idRuleEditor.rule._applyingModifications;
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -80,20 +82,8 @@ function* testEditProperty(inspector, ruleView) {
});
is(newValue, "red", "border-color should have been set.");
info("Entering property name \"color\" followed by a colon to " +
"focus the value");
onFocus = once(idRuleEditor.element, "focus", true);
EventUtils.sendString("color:", ruleView.styleWindow);
yield onFocus;
info("Verifying that the focused field is the valueSpan");
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.styleWindow);
yield onBlur;
yield idRuleEditor.rule._applyingModifications;
ruleView.styleDocument.activeElement.blur();
yield addProperty(ruleView, 1, "color", "red", ";");
let props = ruleView.element.querySelectorAll(".ruleview-property");
for (let i = 0; i < props.length; i++) {
@ -103,12 +93,11 @@ function* testEditProperty(inspector, ruleView) {
}
function* testDisableProperty(inspector, ruleView) {
let idRuleEditor = getRuleViewRuleEditor(ruleView, 1);
let propEditor = idRuleEditor.rule.textProps[0].editor;
let idRule = getRuleViewRuleEditor(ruleView, 1).rule;
let prop = idRule.textProps[0];
info("Disabling a property");
propEditor.enable.click();
yield idRuleEditor.rule._applyingModifications;
yield togglePropStatus(ruleView, prop);
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -118,8 +107,7 @@ function* testDisableProperty(inspector, ruleView) {
is(newValue, "", "Border-color should have been unset.");
info("Enabling the property again");
propEditor.enable.click();
yield idRuleEditor.rule._applyingModifications;
yield togglePropStatus(ruleView, prop);
newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,

View File

@ -20,16 +20,12 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testDisableProperty(inspector, view);
});
function* testDisableProperty(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let rule = getRuleViewRuleEditor(view, 1).rule;
let prop = rule.textProps[0];
info("Disabling a property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
yield togglePropStatus(view, prop);
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
@ -38,23 +34,21 @@ function* testDisableProperty(inspector, view) {
});
is(newValue, "", "background-color should have been unset.");
yield testEditDisableProperty(view, ruleEditor, propEditor,
propEditor.nameSpan, "VK_ESCAPE");
yield testEditDisableProperty(view, ruleEditor, propEditor,
propEditor.valueSpan, "VK_ESCAPE");
yield testEditDisableProperty(view, ruleEditor, propEditor,
propEditor.valueSpan, "VK_TAB");
yield testEditDisableProperty(view, ruleEditor, propEditor,
propEditor.valueSpan, "VK_RETURN");
}
yield testEditDisableProperty(view, rule, prop, "name", "VK_ESCAPE");
yield testEditDisableProperty(view, rule, prop, "value", "VK_ESCAPE");
yield testEditDisableProperty(view, rule, prop, "value", "VK_TAB");
yield testEditDisableProperty(view, rule, prop, "value", "VK_RETURN");
});
function* testEditDisableProperty(view, ruleEditor, propEditor,
editableField, commitKey) {
let editor = yield focusEditableField(view, editableField);
function* testEditDisableProperty(view, rule, prop, fieldType, commitKey) {
let field = fieldType === "name" ? prop.editor.nameSpan
: prop.editor.valueSpan;
ok(!propEditor.element.classList.contains("ruleview-overridden"),
let editor = yield focusEditableField(view, field);
ok(!prop.editor.element.classList.contains("ruleview-overridden"),
"property is not overridden.");
is(propEditor.enable.style.visibility, "hidden",
is(prop.editor.enable.style.visibility, "hidden",
"property enable checkbox is hidden.");
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
@ -64,17 +58,22 @@ function* testEditDisableProperty(view, ruleEditor, propEditor,
});
is(newValue, "", "background-color should remain unset.");
let onChangeDone;
if (fieldType === "value") {
onChangeDone = view.once("ruleview-changed");
}
let onBlur = once(editor.input, "blur");
EventUtils.synthesizeKey(commitKey, {}, view.styleWindow);
yield onBlur;
yield ruleEditor.rule._applyingModifications;
yield onChangeDone;
ok(!propEditor.prop.enabled, "property is disabled.");
ok(propEditor.element.classList.contains("ruleview-overridden"),
ok(!prop.enabled, "property is disabled.");
ok(prop.editor.element.classList.contains("ruleview-overridden"),
"property is overridden.");
is(propEditor.enable.style.visibility, "visible",
is(prop.editor.enable.style.visibility, "visible",
"property enable checkbox is visible.");
ok(!propEditor.enable.getAttribute("checked"),
ok(!prop.editor.enable.getAttribute("checked"),
"property enable checkbox is not checked.");
newValue = yield executeInContent("Test:GetRulePropertyValue", {

View File

@ -20,61 +20,52 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testEditingDisableProperty(inspector, view);
});
function* testEditingDisableProperty(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let rule = getRuleViewRuleEditor(view, 1).rule;
let prop = rule.textProps[0];
info("Disabling background-color property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
yield togglePropStatus(view, prop);
let newValue = yield getRulePropertyValue("background-color");
is(newValue, "", "background-color should have been unset.");
yield focusEditableField(view, propEditor.nameSpan);
info("Entering a new property name, including : to commit and " +
"focus the value");
let onValueFocus = once(ruleEditor.element, "focus", true);
yield focusEditableField(view, prop.editor.nameSpan);
let onNameDone = view.once("ruleview-changed");
EventUtils.sendString("border-color:", view.styleWindow);
yield onValueFocus;
yield ruleEditor.rule._applyingModifications;
yield onNameDone;
info("Escape editing the property value");
let onValueDone = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.styleWindow);
yield ruleEditor.rule._applyingModifications;
yield onValueDone;
newValue = yield getRulePropertyValue("border-color");
is(newValue, "blue", "border-color should have been set.");
ok(propEditor.prop.enabled, "border-color property is enabled.");
ok(!propEditor.element.classList.contains("ruleview-overridden"),
ok(prop.enabled, "border-color property is enabled.");
ok(!prop.editor.element.classList.contains("ruleview-overridden"),
"border-color is not overridden");
info("Disabling border-color property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
yield togglePropStatus(view, prop);
newValue = yield getRulePropertyValue("border-color");
is(newValue, "", "border-color should have been unset.");
info("Enter a new property value for the border-color property");
let editor = yield focusEditableField(view, propEditor.valueSpan);
let onBlur = once(editor.input, "blur");
EventUtils.sendString("red;", view.styleWindow);
yield onBlur;
yield ruleEditor.rule._applyingModifications;
yield setProperty(view, prop, "red");
newValue = yield getRulePropertyValue("border-color");
is(newValue, "red", "new border-color should have been set.");
ok(propEditor.prop.enabled, "border-color property is enabled.");
ok(!propEditor.element.classList.contains("ruleview-overridden"),
ok(prop.enabled, "border-color property is enabled.");
ok(!prop.editor.element.classList.contains("ruleview-overridden"),
"border-color is not overridden");
}
});
function* getRulePropertyValue(name) {
let propValue = yield executeInContent("Test:GetRulePropertyValue", {

View File

@ -22,43 +22,31 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("body", inspector);
yield testEditPropertyPriorityAndDisable(inspector, view);
});
function* testEditPropertyPriorityAndDisable(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let rule = getRuleViewRuleEditor(view, 1).rule;
let prop = rule.textProps[0];
is((yield getComputedStyleProperty("body", null, "background-color")),
"rgb(0, 128, 0)", "green background color is set.");
let editor = yield focusEditableField(view, propEditor.valueSpan);
let onBlur = once(editor.input, "blur");
EventUtils.sendString("red !important;", view.styleWindow);
yield onBlur;
yield ruleEditor.rule._applyingModifications;
yield setProperty(view, prop, "red !important");
is(propEditor.valueSpan.textContent, "red !important",
is(prop.editor.valueSpan.textContent, "red !important",
"'red !important' property value is correctly set.");
is((yield getComputedStyleProperty("body", null, "background-color")),
"rgb(255, 0, 0)", "red background color is set.");
info("Disabling red background color property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
yield togglePropStatus(view, prop);
is((yield getComputedStyleProperty("body", null, "background-color")),
"rgb(0, 128, 0)", "green background color is set.");
editor = yield focusEditableField(view, propEditor.valueSpan);
onBlur = once(editor.input, "blur");
EventUtils.sendString("red;", view.styleWindow);
yield onBlur;
yield ruleEditor.rule._applyingModifications;
yield setProperty(view, prop, "red");
is(propEditor.valueSpan.textContent, "red",
is(prop.editor.valueSpan.textContent, "red",
"'red' property value is correctly set.");
ok(propEditor.prop.enabled, "red background-color property is enabled.");
ok(prop.enabled, "red background-color property is enabled.");
is((yield getComputedStyleProperty("body", null, "background-color")),
"rgb(0, 128, 0)", "green background color is set.");
}
});

View File

@ -20,36 +20,31 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testEditDisableProperty(inspector, view);
});
function* testEditDisableProperty(inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 1);
let propEditor = ruleEditor.rule.textProps[0].editor;
let rule = getRuleViewRuleEditor(view, 1).rule;
let prop = rule.textProps[0];
info("Disabling red background color property");
propEditor.enable.click();
yield ruleEditor.rule._applyingModifications;
yield togglePropStatus(view, prop);
ok(!prop.enabled, "red background-color property is disabled.");
ok(!propEditor.prop.enabled, "red background-color property is disabled.");
let editor = yield focusEditableField(view, prop.editor.valueSpan);
let onDone = view.once("ruleview-changed");
editor.input.value = "red; color: red;";
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onDone;
let editor = yield focusEditableField(view, propEditor.valueSpan);
let onBlur = once(editor.input, "blur");
EventUtils.sendString("red; color: red;", view.styleWindow);
yield onBlur;
yield ruleEditor.rule._applyingModifications;
is(propEditor.valueSpan.textContent, "red",
is(prop.editor.valueSpan.textContent, "red",
"'red' property value is correctly set.");
ok(propEditor.prop.enabled, "red background-color property is enabled.");
ok(prop.enabled, "red background-color property is enabled.");
is((yield getComputedStyleProperty("#testid", null, "background-color")),
"rgb(255, 0, 0)", "red background color is set.");
propEditor = ruleEditor.rule.textProps[1].editor;
let propEditor = rule.textProps[1].editor;
is(propEditor.nameSpan.textContent, "color",
"new 'color' property name is correctly set.");
is(propEditor.valueSpan.textContent, "red",
"new 'red' property value is correctly set.");
is((yield getComputedStyleProperty("#testid", null, "color")),
"rgb(255, 0, 0)", "red color is set.");
}
});

View File

@ -71,42 +71,7 @@ function* checkModifiedElement(view, name) {
function* testAddProperty(view) {
info("Test creating a new property");
let ruleEditor = getRuleViewRuleEditor(view, 1);
info("Focusing a new property name in the rule-view");
let editor = yield focusEditableField(view, ruleEditor.closeBrace);
is(inplaceEditor(ruleEditor.newPropSpan), editor,
"The new property editor got focused");
let input = editor.input;
info("Entering text-align in the property name editor");
input.value = "text-align";
info("Pressing return to commit and focus the new value field");
let onValueFocus = once(ruleEditor.element, "focus", true);
let onRuleViewChanged = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onValueFocus;
yield onRuleViewChanged;
// Getting the new value editor after focus
editor = inplaceEditor(view.styleDocument.activeElement);
let textProp = ruleEditor.rule.textProps[0];
is(ruleEditor.rule.textProps.length, 1, "Created a new text property.");
is(ruleEditor.propertyList.children.length, 1, "Created a property editor.");
is(editor, inplaceEditor(textProp.editor.valueSpan),
"Editing the value span now.");
info("Entering a value and bluring the field to expect a rule change");
editor.input.value = "center";
let onBlur = once(editor.input, "blur");
onRuleViewChanged = waitForNEvents(view, "ruleview-changed", 2);
editor.input.blur();
yield onBlur;
yield onRuleViewChanged;
let textProp = yield addProperty(view, 1, "text-align", "center");
is(textProp.value, "center", "Text prop should have been changed.");
is(textProp.overridden, false, "Property should not be overridden");

View File

@ -29,7 +29,7 @@ add_task(function*() {
yield testEditableFieldFocus(inspector, view, "VK_TAB", { shiftKey: true });
});
function* testEditableFieldFocus(inspector, view, commitKey, options={}) {
function* testEditableFieldFocus(inspector, view, commitKey, options = {}) {
let ruleEditor = getRuleViewRuleEditor(view, 2);
let editor = yield focusEditableField(view, ruleEditor.selectorText);
is(inplaceEditor(ruleEditor.selectorText), editor,

View File

@ -10,8 +10,6 @@ Services.telemetry.canRecordExtended = true;
registerCleanupFunction(function() {
Services.telemetry.canRecordExtended = oldCanRecord;
});
const HISTOGRAM_ID = "DEVTOOLS_PICKER_EYEDROPPER_OPENED_COUNT";
const FLAG_HISTOGRAM_ID = "DEVTOOLS_PICKER_EYEDROPPER_OPENED_PER_USER_FLAG";
const EXPECTED_TELEMETRY = {
"DEVTOOLS_PICKER_EYEDROPPER_OPENED_COUNT": 2,
"DEVTOOLS_PICKER_EYEDROPPER_OPENED_PER_USER_FLAG": 1
@ -40,8 +38,10 @@ const TEST_URI = `
<body><div id="div1"></div><div id="div2"></div></body>
`;
const ORIGINAL_COLOR = "rgb(255, 0, 153)"; // #f09
const EXPECTED_COLOR = "rgb(255, 255, 85)"; // #ff5
// #f09
const ORIGINAL_COLOR = "rgb(255, 0, 153)";
// #ff5
const EXPECTED_COLOR = "rgb(255, 255, 85)";
// Test opening the eyedropper from the color picker. Pressing escape
// to close it, and clicking the page to select a color.
@ -103,8 +103,7 @@ function* testSelect(view, swatch, dropper) {
let color = swatch.style.backgroundColor;
is(color, EXPECTED_COLOR, "swatch changed colors");
let element = content.document.querySelector("div");
is(content.window.getComputedStyle(element).backgroundColor,
is((yield getComputedStyleProperty("div", null, "background-color")),
EXPECTED_COLOR,
"div's color set to body color after dropper");
}
@ -148,7 +147,7 @@ function openEyedropper(view, swatch) {
return deferred.promise;
}
function inspectPage(dropper, click=true) {
function inspectPage(dropper, click = true) {
let target = document.documentElement;
let win = window;

View File

@ -40,7 +40,6 @@ add_task(function*() {
EventUtils.sendKey("RETURN", widget.styleWindow);
yield onRuleViewChanged;
const computed = content.getComputedStyle(content.document.body);
is(computed.filter, "blur(2px)",
is((yield getComputedStyleProperty("body", null, "filter")), "blur(2px)",
"The elemenet's filter was kept after RETURN");
});

View File

@ -34,40 +34,14 @@ add_task(function*() {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode("#testid", inspector);
yield testIndentation(toolbox, inspector, view);
});
function* testIndentation(toolbox, inspector, view) {
let ruleEditor = getRuleViewRuleEditor(view, 2);
info("Focusing a new property name in the rule-view");
let editor = yield focusEditableField(view, ruleEditor.closeBrace);
let input = editor.input;
info("Entering color in the property name editor");
input.value = "color";
info("Pressing return to commit and focus the new value field");
let onValueFocus = once(ruleEditor.element, "focus", true);
let onModifications = ruleEditor.rule._applyingModifications;
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onValueFocus;
yield onModifications;
// Getting the new value editor after focus
editor = inplaceEditor(view.styleDocument.activeElement);
info("Entering a value and bluring the field to expect a rule change");
editor.input.value = "chartreuse";
let onBlur = once(editor.input, "blur");
onModifications = ruleEditor.rule._applyingModifications;
editor.input.blur();
yield onBlur;
yield onModifications;
info("Add a new property in the rule-view");
yield addProperty(view, 2, "color", "chartreuse");
info("Switch to the style-editor");
let { UI } = yield toolbox.selectTool("styleeditor");
let styleEditor = yield UI.editors[0].getSourceEditor();
let text = styleEditor.sourceEditor.getText();
is(text, expectedText, "style inspector changes are synced");
}
});

View File

@ -7,8 +7,6 @@
// Check that inherited properties appear for a nested element in the
// rule view.
var {ELEMENT_STYLE} = require("devtools/server/actors/styles");
const TEST_URI = `
<style type="text/css">
#test2 {

View File

@ -7,8 +7,6 @@
// Check that no inherited properties appear when the property does not apply
// to the nested element.
var {ELEMENT_STYLE} = require("devtools/server/actors/styles");
const TEST_URI = `
<style type="text/css">
#test2 {

View File

@ -14,11 +14,8 @@ add_task(function*() {
let { inspector, view } = yield openRuleView();
yield selectNode("#outer", inspector);
// Insert a new property, which will affect the line numbers.
let elementRuleEditor = getRuleViewRuleEditor(view, 1);
let onRuleViewChanged = view.once("ruleview-changed");
yield createNewRuleViewProperty(elementRuleEditor, "font-size: 72px");
yield onRuleViewChanged;
info("Insert a new property, which will affect the line numbers");
yield addProperty(view, 1, "font-size", "72px");
yield selectNode("#inner", inspector);

Some files were not shown because too many files have changed in this diff Show More