diff --git a/browser/devtools/styleinspector/test/browser_ruleview_user-agent-styles.js b/browser/devtools/styleinspector/test/browser_ruleview_user-agent-styles.js index e4142569caa1..8cd5501c208d 100644 --- a/browser/devtools/styleinspector/test/browser_ruleview_user-agent-styles.js +++ b/browser/devtools/styleinspector/test/browser_ruleview_user-agent-styles.js @@ -9,12 +9,73 @@ let PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles"; const { PrefObserver } = devtools.require("devtools/styleeditor/utils"); -const TEST_URI = "data:text/html;charset=utf-8," + - "
" + - "
" +
-  "   inspect user agent styles" +
-  " 
" + - "
"; + +const TEST_DOC = ' \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
\ +
                         \
+                          inspect user agent styles \
+                        
\ +
\ + \ + '; + +const TEST_URI = "data:text/html;charset=utf-8," + encodeURIComponent(TEST_DOC); + +const TEST_DATA = [ + { + selector: "blockquote", + numUserRules: 1, + numUARules: 0 + }, + { + selector: "pre", + numUserRules: 1, + numUARules: 0 + }, + { + selector: "input[type=range]", + numUserRules: 1, + numUARules: 0 + }, + { + selector: "input[type=number]", + numUserRules: 1, + numUARules: 0 + }, + { + selector: "input[type=color]", + numUserRules: 1, + numUARules: 0 + }, + { + selector: "input[type=text]", + numUserRules: 1, + numUARules: 0 + }, + { + selector: "progress", + numUserRules: 1, + numUARules: 0 + }, + { + selector: "a", + numUserRules: 2, + numUARules: 0 + } +]; add_task(function*() { info ("Starting the test with the pref set to true before toolbox is opened"); @@ -55,66 +116,45 @@ function* setUserAgentStylesPref(val) { function* userAgentStylesVisible(inspector, view) { info ("Making sure that user agent styles are currently visible"); - yield selectNode("blockquote", inspector); - yield compareAppliedStylesWithUI(inspector, view, "ua"); + let userRules; + let uaRules; - let userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); - let uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); - is (userRules.length, 1, "Correct number of user rules"); - ok (uaRules.length > 0, "Has UA rules"); + for (let data of TEST_DATA) { + yield selectNode(data.selector, inspector); + yield compareAppliedStylesWithUI(inspector, view, "ua"); - yield selectNode("pre", inspector); - yield compareAppliedStylesWithUI(inspector, view, "ua"); + userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); + uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); + is (userRules.length, data.numUserRules, "Correct number of user rules"); + ok (uaRules.length > data.numUARules, "Has UA rules"); + } - userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); - uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); - is (userRules.length, 1, "Correct number of user rules"); - ok (uaRules.length > 0, "Has UA rules"); - - yield selectNode("a", inspector); - yield compareAppliedStylesWithUI(inspector, view, "ua"); - - userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); - uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); - is (userRules.length, 1, "Correct number of user rules"); - - ok (userRules.some(rule=> rule.matchedSelectors.length === 0), + ok (userRules.some(rule=> rule.matchedSelectors.length === 1), "There is an inline style for element in user styles"); ok (uaRules.some(rule=> rule.matchedSelectors.indexOf(":-moz-any-link")), "There is a rule for :-moz-any-link"); ok (uaRules.some(rule=> rule.matchedSelectors.indexOf("*|*:link")), "There is a rule for *|*:link"); - ok (!uaRules.some(rule=> rule.matchedSelectors.length === 0), - "No inline styles for ua styles"); + ok (uaRules.some(rule=> rule.matchedSelectors.length === 1), + "Inline styles for ua styles"); } function* userAgentStylesNotVisible(inspector, view) { info ("Making sure that user agent styles are not currently visible"); - yield selectNode("blockquote", inspector); - yield compareAppliedStylesWithUI(inspector, view); + let userRules; + let uaRules; - let userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); - let uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); - is (userRules.length, 1, "Correct number of user rules"); - is (uaRules.length, 0, "No UA rules"); + for (let data of TEST_DATA) { + yield selectNode(data.selector, inspector); + yield compareAppliedStylesWithUI(inspector, view); - yield selectNode("pre", inspector); - yield compareAppliedStylesWithUI(inspector, view); - - userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); - uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); - is (userRules.length, 1, "Correct number of user rules"); - is (uaRules.length, 0, "No UA rules"); - - yield selectNode("a", inspector); - yield compareAppliedStylesWithUI(inspector, view); - - userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); - uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); - is (userRules.length, 1, "Correct number of user rules"); - is (uaRules.length, 0, "No UA rules"); + userRules = view._elementStyle.rules.filter(rule=>rule.editor.isEditable); + uaRules = view._elementStyle.rules.filter(rule=>!rule.editor.isEditable); + is (userRules.length, data.numUserRules, "Correct number of user rules"); + is (uaRules.length, data.numUARules, "No UA rules"); + } } function* compareAppliedStylesWithUI(inspector, view, filter) { @@ -129,6 +169,10 @@ function* compareAppliedStylesWithUI(inspector, view, filter) { let elementStyle = view._elementStyle; is(elementStyle.rules.length, entries.length, "Should have correct number of rules (" + entries.length + ")"); + entries = entries.sort((a, b) => { + return (a.pseudoElement || "z") > (b.pseudoElement || "z"); + }); + entries.forEach((entry, i) => { let elementStyleRule = elementStyle.rules[i]; is (elementStyleRule.inherited, entry.inherited, "Same inherited (" +entry.inherited+ ")" ); diff --git a/toolkit/devtools/server/actors/styles.js b/toolkit/devtools/server/actors/styles.js index 49a024b64c1f..25086aa64ac5 100644 --- a/toolkit/devtools/server/actors/styles.js +++ b/toolkit/devtools/server/actors/styles.js @@ -13,7 +13,7 @@ const events = require("sdk/event/core"); const object = require("sdk/util/object"); const {Class} = require("sdk/core/heritage"); const {LongStringActor} = require("devtools/server/actors/string"); - +const {PSEUDO_ELEMENT_SET} = require("devtools/styleinspector/css-logic"); // This will add the "stylesheet" actor type for protocol.js to recognize require("devtools/server/actors/stylesheets"); @@ -27,7 +27,18 @@ loader.lazyGetter(this, "DOMUtils", () => Cc["@mozilla.org/inspector/dom-utils;1 const ELEMENT_STYLE = 100; exports.ELEMENT_STYLE = ELEMENT_STYLE; -const PSEUDO_ELEMENTS = [":first-line", ":first-letter", ":before", ":after", ":-moz-selection"]; +// Not included since these are uneditable by the user. +// See https://hg.mozilla.org/mozilla-central/file/696a4ad5d011/layout/style/nsCSSPseudoElementList.h#l74 +PSEUDO_ELEMENT_SET.delete(":-moz-meter-bar"); +PSEUDO_ELEMENT_SET.delete(":-moz-list-bullet"); +PSEUDO_ELEMENT_SET.delete(":-moz-list-number"); +PSEUDO_ELEMENT_SET.delete(":-moz-focus-inner"); +PSEUDO_ELEMENT_SET.delete(":-moz-focus-outer"); +PSEUDO_ELEMENT_SET.delete(":-moz-math-anonymous"); +PSEUDO_ELEMENT_SET.delete(":-moz-math-stretchy"); + +const PSEUDO_ELEMENTS = Array.from(PSEUDO_ELEMENT_SET); + exports.PSEUDO_ELEMENTS = PSEUDO_ELEMENTS; // When gathering rules to read for pseudo elements, we will skip @@ -494,7 +505,7 @@ var PageStyleActor = protocol.ActorClass({ * 'ua': Include properties from user and user-agent sheets. * Default value is 'ua' * `inherited`: Include styles inherited from parent nodes. - * `matchedSeletors`: Include an array of specific selectors that + * `matchedSelectors`: Include an array of specific selectors that * caused this rule to match its node. */ getApplied: method(function(node, options) { @@ -548,19 +559,22 @@ var PageStyleActor = protocol.ActorClass({ let showElementStyles = !inherited && !pseudo; let showInheritedStyles = inherited && this._hasInheritedProps(bindingElement.style); + let rule = { + rule: elementStyle, + pseudoElement: null, + isSystem: false, + inherited: false + }; + // First any inline styles if (showElementStyles) { - rules.push({ - rule: elementStyle, - }); + rules.push(rule); } // Now any inherited styles if (showInheritedStyles) { - rules.push({ - rule: elementStyle, - inherited: inherited - }); + rule.inherited = inherited; + rules.push(rule); } // Add normal rules. Typically this is passing in the node passed into the diff --git a/toolkit/devtools/server/tests/mochitest/test_styles-applied.html b/toolkit/devtools/server/tests/mochitest/test_styles-applied.html index 45b2ac0cbd38..c5f25d838303 100644 --- a/toolkit/devtools/server/tests/mochitest/test_styles-applied.html +++ b/toolkit/devtools/server/tests/mochitest/test_styles-applied.html @@ -88,7 +88,7 @@ addTest(function inheritedSystemStyles() { ok(!applied[1].rule.parentStyleSheet.system, "Entry 1 should be a system style"); is(applied[1].rule.type, 1, "Entry 1 should be a rule style"); - is(applied.length, 7, "Should have 7 rules."); + is(applied.length, 8, "Should have 8 rules."); }).then(runNextTest)); }); diff --git a/toolkit/devtools/styleinspector/css-logic.js b/toolkit/devtools/styleinspector/css-logic.js index 001ae8c25835..16df7fabb667 100644 --- a/toolkit/devtools/styleinspector/css-logic.js +++ b/toolkit/devtools/styleinspector/css-logic.js @@ -42,6 +42,36 @@ const { Cc, Ci, Cu } = require("chrome"); const Services = require("Services"); const DevToolsUtils = require("devtools/toolkit/DevToolsUtils"); +let pseudos = new Set([ + ":after", + ":before", + ":first-letter", + ":first-line", + ":selection", + ":-moz-color-swatch", + ":-moz-focus-inner", + ":-moz-focus-outer", + ":-moz-list-bullet", + ":-moz-list-number", + ":-moz-math-anonymous", + ":-moz-math-stretchy", + ":-moz-meter-bar", + ":-moz-number-spin-box", + ":-moz-number-spin-down", + ":-moz-number-spin-up", + ":-moz-number-text", + ":-moz-number-wrapper", + ":-moz-placeholder", + ":-moz-progress-bar", + ":-moz-range-progress", + ":-moz-range-thumb", + ":-moz-range-track", + ":-moz-selection" +]); + +const PSEUDO_ELEMENT_SET = pseudos; +exports.PSEUDO_ELEMENT_SET = PSEUDO_ELEMENT_SET; + // This should be ok because none of the functions that use this should be used // on the worker thread, where Cu is not available. if (Cu) { @@ -1655,21 +1685,7 @@ CssSelector.prototype = { get pseudoElements() { if (!CssSelector._pseudoElements) { - let pseudos = CssSelector._pseudoElements = new Set(); - pseudos.add("after"); - pseudos.add("before"); - pseudos.add("first-letter"); - pseudos.add("first-line"); - pseudos.add("selection"); - pseudos.add("-moz-color-swatch"); - pseudos.add("-moz-focus-inner"); - pseudos.add("-moz-focus-outer"); - pseudos.add("-moz-list-bullet"); - pseudos.add("-moz-list-number"); - pseudos.add("-moz-math-anonymous"); - pseudos.add("-moz-math-stretchy"); - pseudos.add("-moz-progress-bar"); - pseudos.add("-moz-selection"); + CssSelector._pseudoElements = PSEUDO_ELEMENT_SET; } return CssSelector._pseudoElements; },