author | Tim Nguyen <ntim.bugs@gmail.com> |
Mon, 08 Jun 2015 12:25:00 -0400 | |
changeset 248135 | 4bd79939fea127dab2f1fbc64236d2a0dd8592fd |
parent 248134 | b4f355ca322fb6ca04d795720209dd59addc8a14 |
child 248136 | fdaad6bb56fdf82a5cbc1c4053c3e84df3ef31f0 |
push id | 60888 |
push user | kwierso@gmail.com |
push date | Thu, 11 Jun 2015 01:38:38 +0000 |
treeherder | mozilla-inbound@39e638ed06bf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bgrins |
bugs | 1165032 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/devtools/styleinspector/rule-view.js +++ b/browser/devtools/styleinspector/rule-view.js @@ -1623,22 +1623,23 @@ CssRuleView.prototype = { /** * Add a new rule to the current element. */ _onAddRule: function() { let elementStyle = this._elementStyle; let element = elementStyle.element; let rules = elementStyle.rules; let client = this.inspector.toolbox._target.client; + let pseudoClasses = element.pseudoClassLocks; if (!client.traits.addNewRule) { return; } - this.pageStyle.addNewRule(element).then(options => { + this.pageStyle.addNewRule(element, pseudoClasses).then(options => { let newRule = new Rule(elementStyle, options); rules.push(newRule); let editor = new RuleEditor(this, newRule); // Insert the new rule editor after the inline element rule if (rules.length <= 1) { this.element.appendChild(editor.element); } else {
--- a/browser/devtools/styleinspector/test/browser.ini +++ b/browser/devtools/styleinspector/test/browser.ini @@ -50,16 +50,17 @@ support-files = [browser_ruleview_add-property-cancel_02.js] [browser_ruleview_add-property-cancel_03.js] [browser_ruleview_add-property_01.js] [browser_ruleview_add-property_02.js] [browser_ruleview_add-property-svg.js] [browser_ruleview_add-rule_01.js] [browser_ruleview_add-rule_02.js] [browser_ruleview_add-rule_03.js] +[browser_ruleview_add-rule_pseudo_class.js] [browser_ruleview_colorpicker-and-image-tooltip_01.js] [browser_ruleview_colorpicker-and-image-tooltip_02.js] [browser_ruleview_colorpicker-appears-on-swatch-click.js] [browser_ruleview_colorpicker-commit-on-ENTER.js] [browser_ruleview_colorpicker-edit-gradient.js] [browser_ruleview_colorpicker-hides-on-tooltip.js] [browser_ruleview_colorpicker-multiple-changes.js] [browser_ruleview_colorpicker-release-outside-frame.js]
new file mode 100644 --- /dev/null +++ b/browser/devtools/styleinspector/test/browser_ruleview_add-rule_pseudo_class.js @@ -0,0 +1,107 @@ +/* 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"; + +// Tests adding a rule with pseudo class locks on + +let PAGE_CONTENT = "<p id='element'>Test element</p>"; + +const EXPECTED_SELECTOR = "#element"; +const TEST_DATA = [ + [], + [":hover"], + [":hover", ":active"], + [":hover", ":active", ":focus"], + [":active"], + [":active", ":focus"], + [":focus"] +]; + +add_task(function*() { + yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(PAGE_CONTENT)); + + info("Opening the rule-view"); + let {toolbox, inspector, view} = yield openRuleView(); + + info("Selecting the test element"); + yield selectNode("#element", inspector); + + info("Iterating over the test data"); + for (let data of TEST_DATA) { + yield runTestData(inspector, view, data); + } +}); + +function* runTestData(inspector, view, pseudoClasses) { + yield setPseudoLocks(inspector, view, pseudoClasses); + yield addNewRule(inspector, view); + yield testNewRule(view, pseudoClasses, 1); + yield resetPseudoLocks(inspector, view); +} + +function* addNewRule(inspector, view) { + info("Adding the new rule using the button"); + view.addRuleButton.click(); + info("Waiting for rule view to change"); + let onRuleViewChanged = once(view, "ruleview-changed"); + yield onRuleViewChanged; +} + +function* testNewRule(view, pseudoClasses, index) { + let idRuleEditor = getRuleViewRuleEditor(view, index); + let editor = idRuleEditor.selectorText.ownerDocument.activeElement; + let expected = EXPECTED_SELECTOR + pseudoClasses.join(""); + + is(editor.value, expected, + "Selector editor value is as expected: " + expected); + + info("Entering the escape key"); + EventUtils.synthesizeKey("VK_ESCAPE", {}); + + is(idRuleEditor.selectorText.textContent, expected, + "Selector text value is as expected: " + expected); +} + +function* setPseudoLocks(inspector, view, pseudoClasses) { + if (pseudoClasses.length == 0) { + return; + } + for (var pseudoClass of pseudoClasses) { + switch (pseudoClass) { + case ":hover": + view.hoverCheckbox.click(); + yield inspector.once("rule-view-refreshed"); + break; + case ":active": + view.activeCheckbox.click(); + yield inspector.once("rule-view-refreshed"); + break; + case ":focus": + view.focusCheckbox.click(); + yield inspector.once("rule-view-refreshed"); + break; + } + } +} + +function* resetPseudoLocks(inspector, view) { + if (!view.hoverCheckbox.checked && + !view.activeCheckbox.checked && + !view.focusCheckbox.checked) { + return; + } + if (view.hoverCheckbox.checked) { + view.hoverCheckbox.click(); + yield inspector.once("rule-view-refreshed"); + } + if (view.activeCheckbox.checked) { + view.activeCheckbox.click(); + yield inspector.once("rule-view-refreshed"); + } + if (view.focusCheckbox.checked) { + view.focusCheckbox.click(); + yield inspector.once("rule-view-refreshed"); + } +}
--- a/toolkit/devtools/server/actors/styles.js +++ b/toolkit/devtools/server/actors/styles.js @@ -871,40 +871,47 @@ var PageStyleActor = protocol.ActorClass getNewAppliedProps: function(node, rule) { let ruleActor = this._styleRef(rule); return this.getAppliedProps(node, [{ rule: ruleActor }], { matchedSelectors: true }); }, /** * Adds a new rule, and returns the new StyleRuleActor. - * @param NodeActor node + * @param NodeActor node + * @param [string] pseudoClasses The list of pseudo classes to append to the + * new selector. * @returns StyleRuleActor of the new rule */ - addNewRule: method(function(node) { + addNewRule: method(function(node, pseudoClasses) { let style = this.styleElement; let sheet = style.sheet; let cssRules = sheet.cssRules; let rawNode = node.rawNode; let selector; if (rawNode.id) { selector = "#" + CSS.escape(rawNode.id); } else if (rawNode.className) { selector = "." + rawNode.className.split(" ").map(c => CSS.escape(c)).join("."); } else { selector = rawNode.tagName.toLowerCase(); } + if (pseudoClasses && pseudoClasses.length > 0) { + selector += pseudoClasses.join(""); + } + let index = sheet.insertRule(selector + " {}", cssRules.length); return this.getNewAppliedProps(node, cssRules.item(index)); }, { request: { - node: Arg(0, "domnode") + node: Arg(0, "domnode"), + pseudoClasses: Arg(1, "nullable:array:string") }, response: RetVal("appliedStylesReturn") }), }); exports.PageStyleActor = PageStyleActor; /** * Front object for the PageStyleActor @@ -948,18 +955,18 @@ var PageStyleFront = protocol.FrontClass yield this.getLayout(node); } let ret = yield this._getApplied(node, options); return ret.entries; }), { impl: "_getApplied" }), - addNewRule: protocol.custom(function(node) { - return this._addNewRule(node).then(ret => { + addNewRule: protocol.custom(function(node, pseudoClasses) { + return this._addNewRule(node, pseudoClasses).then(ret => { return ret.entries[0]; }); }, { impl: "_addNewRule" }) }); /**