Bug 1287042 - Always before/after CSS rules in rule-view; r=bgrins draft
authorPatrick Brosset <pbrosset@mozilla.com>
Mon, 18 Jul 2016 17:15:05 +0200
changeset 389878 19979672561e55fc5713900b83dd6d40ac33d2a3
parent 389877 0687d5c6b97b23c247016b4214a431e38d751152
child 525890 5aef895e17b664487d93a9761fd5300d77a86464
push id23554
push userpbrosset@mozilla.com
push dateWed, 20 Jul 2016 09:13:33 +0000
reviewersbgrins
bugs1287042
milestone50.0a1
Bug 1287042 - Always before/after CSS rules in rule-view; r=bgrins ::before and ::after pseudo-elements are visible in the markup-view today but if, for some reason, they aren't generated, we still want to know that the CSS rule exists. This may happen if you use display:none on the pseudo-element CSS rule itself. When that happens, the pseudo-element won't be generated and therefore there will be no possibility to see the rule in the rule-view (you'd have to go to the style-editor for that). This change keeps the pseudo-elements in the markup-view, but also adds the corresponding CSS rules in the rule-view. MozReview-Commit-ID: tx5IpmtE7b
devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js
devtools/client/inspector/rules/test/browser_rules_pseudo-element_02.js
devtools/server/actors/styles.js
--- a/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js
+++ b/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js
@@ -5,39 +5,39 @@
 "use strict";
 
 // Test that pseudoelements are displayed correctly in the rule view
 
 const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
 const PSEUDO_PREF = "devtools.inspector.show_pseudo_elements";
 
 add_task(function* () {
-  Services.prefs.setBoolPref(PSEUDO_PREF, true);
+  yield pushPref(PSEUDO_PREF, true);
 
   yield addTab(TEST_URI);
   let {inspector, view} = yield openRuleView();
 
   yield testTopLeft(inspector, view);
   yield testTopRight(inspector, view);
   yield testBottomRight(inspector, view);
   yield testBottomLeft(inspector, view);
   yield testParagraph(inspector, view);
   yield testBody(inspector, view);
-
-  Services.prefs.clearUserPref(PSEUDO_PREF);
 });
 
 function* testTopLeft(inspector, view) {
   let id = "#topleft";
   let rules = yield assertPseudoElementRulesNumbers(id,
     inspector, view, {
       elementRulesNb: 4,
       firstLineRulesNb: 2,
       firstLetterRulesNb: 1,
-      selectionRulesNb: 0
+      selectionRulesNb: 0,
+      afterRulesNb: 1,
+      beforeRulesNb: 2
     }
   );
 
   let gutters = assertGutters(view);
 
   info("Make sure that clicking on the twisty hides pseudo elements");
   let expander = gutters[0].querySelector(".ruleview-expander");
   ok(!view.element.children[1].hidden, "Pseudo Elements are expanded");
@@ -117,17 +117,19 @@ function* testTopLeft(inspector, view) {
      "rgb(0, 255, 0)", "Added prop does not apply to pseudo");
 }
 
 function* testTopRight(inspector, view) {
   yield assertPseudoElementRulesNumbers("#topright", inspector, view, {
     elementRulesNb: 4,
     firstLineRulesNb: 1,
     firstLetterRulesNb: 1,
-    selectionRulesNb: 0
+    selectionRulesNb: 0,
+    beforeRulesNb: 2,
+    afterRulesNb: 1
   });
 
   let gutters = assertGutters(view);
 
   let expander = gutters[0].querySelector(".ruleview-expander");
   ok(!view.element.firstChild.classList.contains("show-expandable-container"),
      "Pseudo Elements remain collapsed after switching element");
 
@@ -137,36 +139,42 @@ function* testTopRight(inspector, view) 
     "Pseudo Elements are shown again after clicking twisty");
 }
 
 function* testBottomRight(inspector, view) {
   yield assertPseudoElementRulesNumbers("#bottomright", inspector, view, {
     elementRulesNb: 4,
     firstLineRulesNb: 1,
     firstLetterRulesNb: 1,
-    selectionRulesNb: 0
+    selectionRulesNb: 0,
+    beforeRulesNb: 3,
+    afterRulesNb: 1
   });
 }
 
 function* testBottomLeft(inspector, view) {
   yield assertPseudoElementRulesNumbers("#bottomleft", inspector, view, {
     elementRulesNb: 4,
     firstLineRulesNb: 1,
     firstLetterRulesNb: 1,
-    selectionRulesNb: 0
+    selectionRulesNb: 0,
+    beforeRulesNb: 2,
+    afterRulesNb: 1
   });
 }
 
 function* testParagraph(inspector, view) {
   let rules =
     yield assertPseudoElementRulesNumbers("#bottomleft p", inspector, view, {
       elementRulesNb: 3,
       firstLineRulesNb: 1,
       firstLetterRulesNb: 1,
-      selectionRulesNb: 1
+      selectionRulesNb: 1,
+      beforeRulesNb: 0,
+      afterRulesNb: 0
     });
 
   assertGutters(view);
 
   let elementFirstLineRule = rules.firstLineRules[0];
   is(convertTextPropsToString(elementFirstLineRule.textProps),
      "background: blue",
      "Paragraph first-line properties are correct");
@@ -204,27 +212,35 @@ function* assertPseudoElementRulesNumber
 
   let rules = {
     elementRules: elementStyle.rules.filter(rule => !rule.pseudoElement),
     firstLineRules: elementStyle.rules.filter(rule =>
       rule.pseudoElement === ":first-line"),
     firstLetterRules: elementStyle.rules.filter(rule =>
       rule.pseudoElement === ":first-letter"),
     selectionRules: elementStyle.rules.filter(rule =>
-      rule.pseudoElement === ":-moz-selection")
+      rule.pseudoElement === ":-moz-selection"),
+    beforeRules: elementStyle.rules.filter(rule =>
+      rule.pseudoElement === ":before"),
+    afterRules: elementStyle.rules.filter(rule =>
+      rule.pseudoElement === ":after"),
   };
 
   is(rules.elementRules.length, ruleNbs.elementRulesNb,
      selector + " has the correct number of non pseudo element rules");
   is(rules.firstLineRules.length, ruleNbs.firstLineRulesNb,
      selector + " has the correct number of :first-line rules");
   is(rules.firstLetterRules.length, ruleNbs.firstLetterRulesNb,
      selector + " has the correct number of :first-letter rules");
   is(rules.selectionRules.length, ruleNbs.selectionRulesNb,
      selector + " has the correct number of :selection rules");
+  is(rules.beforeRules.length, ruleNbs.beforeRulesNb,
+     selector + " has the correct number of :before rules");
+  is(rules.afterRules.length, ruleNbs.afterRulesNb,
+     selector + " has the correct number of :after rules");
 
   return rules;
 }
 
 function getGutters(view) {
   return view.element.querySelectorAll(".theme-gutter");
 }
 
--- a/devtools/client/inspector/rules/test/browser_rules_pseudo-element_02.js
+++ b/devtools/client/inspector/rules/test/browser_rules_pseudo-element_02.js
@@ -1,15 +1,15 @@
 /* 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 pseudoelements are displayed correctly in the rule view
+// Test that pseudoelements are displayed correctly in the markup view.
 
 const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
 
 add_task(function* () {
   yield addTab(TEST_URI);
   let {inspector} = yield openRuleView();
 
   let node = yield getNodeFront("#topleft", inspector);
--- a/devtools/server/actors/styles.js
+++ b/devtools/server/actors/styles.js
@@ -18,22 +18,18 @@ const events = require("sdk/event/core")
 const {UPDATE_PRESERVING_RULES, UPDATE_GENERAL} = require("devtools/server/actors/stylesheets");
 const {pageStyleSpec, styleRuleSpec, ELEMENT_STYLE} = require("devtools/shared/specs/styles");
 
 loader.lazyRequireGetter(this, "CSS", "CSS");
 loader.lazyGetter(this, "CssLogic", () => require("devtools/server/css-logic").CssLogic);
 loader.lazyGetter(this, "SharedCssLogic", () => require("devtools/shared/inspector/css-logic"));
 loader.lazyGetter(this, "DOMUtils", () => Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils));
 
-// When gathering rules to read for pseudo elements, we will skip
-// :before and :after, which are handled as a special case.
-loader.lazyGetter(this, "PSEUDO_ELEMENTS_TO_READ", () => {
-  return DOMUtils.getCSSPseudoElementNames().filter(pseudo => {
-    return pseudo !== ":before" && pseudo !== ":after";
-  });
+loader.lazyGetter(this, "PSEUDO_ELEMENTS", () => {
+  return DOMUtils.getCSSPseudoElementNames();
 });
 
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
 const FONT_PREVIEW_TEXT = "Abc";
 const FONT_PREVIEW_FONT_SIZE = 40;
 const FONT_PREVIEW_FILLSTYLE = "black";
 const NORMAL_FONT_WEIGHT = 400;
 const BOLD_FONT_WEIGHT = 700;
@@ -536,20 +532,19 @@ var PageStyleActor = protocol.ActorClass
           // The only case when there would be a pseudo here is
           // ::before/::after, and in this case we want to tell the
           // view that it belongs to the element (which is a
           // _moz_generated_content native anonymous element).
           oneRule.pseudoElement = null;
           rules.push(oneRule);
         });
 
-    // Now any pseudos (except for ::before / ::after, which was handled as
-    // a 'normal rule' above.
+    // Now any pseudos.
     if (showElementStyles) {
-      for (let readPseudo of PSEUDO_ELEMENTS_TO_READ) {
+      for (let readPseudo of PSEUDO_ELEMENTS) {
         this._getElementRules(bindingElement, readPseudo, inherited, options)
             .forEach(oneRule => {
               rules.push(oneRule);
             });
       }
     }
 
     return rules;