Bug 1287042 - Always before/after CSS rules in rule-view; r=bgrins
authorPatrick Brosset <pbrosset@mozilla.com>
Mon, 18 Jul 2016 17:15:05 +0200
changeset 345879 ec882720349ca69e63f2c1ca7b5bff6c30ff18e2
parent 345878 abe9d470586496065a53b2f9c3cb60b1ec8f3ed5
child 345880 9c84392108d91ea0a598b13e0acfd6b086e2952a
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1287042
milestone50.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
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;