Bug 672743 - Remove category view from style inspector; r=msucan
authorMike Ratcliffe <mratcliffe@mozilla.com>
Tue, 30 Aug 2011 13:40:29 -0300
changeset 76261 c6309c9aa79a70c0b92ca335cd8d4340c796d4e9
parent 76260 54685bf66136dc5e346e1e0873d2fc9afb4f85c0
child 76262 8d3407891a21e389c14cb16a7e7a5ef7666bf2dc
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersmsucan
bugs672743
milestone9.0a1
Bug 672743 - Remove category view from style inspector; r=msucan
browser/base/content/inspector.js
browser/devtools/styleinspector/CssHtmlTree.jsm
browser/devtools/styleinspector/csshtmltree.xhtml
browser/devtools/styleinspector/test/browser/browser_styleinspector.js
browser/devtools/styleinspector/test/browser/browser_styleinspector_webconsole.htm
browser/devtools/styleinspector/test/browser/browser_styleinspector_webconsole.js
browser/themes/gnomestripe/browser/devtools/csshtmltree.css
browser/themes/pinstripe/browser/devtools/csshtmltree.css
browser/themes/winstripe/browser/devtools/csshtmltree.css
--- a/browser/base/content/inspector.js
+++ b/browser/base/content/inspector.js
@@ -1122,17 +1122,16 @@ var InspectorUI = {
   onTreeDblClick: function IUI_onTreeDblClick(aEvent)
   {
     // if already editing an attribute value, double-clicking elsewhere
     // in the tree is the same as a click, which dismisses the editor
     if (this.editingContext)
       this.closeEditor();
 
     let target = aEvent.target;
-
     if (this.hasClass(target, "nodeValue")) {
       let repObj = this.getRepObject(target);
       let attrName = target.getAttribute("data-attributeName");
       let attrVal = target.innerHTML;
 
       this.editAttributeValue(target, repObj, attrName, attrVal);
     }
   },
--- a/browser/devtools/styleinspector/CssHtmlTree.jsm
+++ b/browser/devtools/styleinspector/CssHtmlTree.jsm
@@ -67,23 +67,25 @@ function CssHtmlTree(aStyleWin, aCssLogi
   this.getRTLAttr = CssHtmlTree.getRTLAttr;
 
   // The document in which we display the results (csshtmltree.xhtml).
   this.styleDocument = this.styleWin.contentWindow.document;
 
   // Nodes used in templating
   this.root = this.styleDocument.getElementById("root");
   this.templateRoot = this.styleDocument.getElementById("templateRoot");
+  this.propertyContainer = this.styleDocument.getElementById("propertyContainer");
+  this.templateProperty = this.styleDocument.getElementById("templateProperty");
   this.panel = aPanel;
 
   // The element that we're inspecting, and the document that it comes from.
   this.viewedElement = null;
   this.viewedDocument = null;
 
-  this.createStyleGroupViews();
+  this.createStyleViews();
 }
 
 /**
  * Memonized lookup of a l10n string from a string bundle.
  * @param {string} aName The key to lookup.
  * @returns A localized version of the given key.
  */
 CssHtmlTree.l10n = function CssHtmlTree_l10n(aName)
@@ -99,20 +101,26 @@ CssHtmlTree.l10n = function CssHtmlTree_
 /**
  * Clone the given template node, and process it by resolving ${} references
  * in the template.
  *
  * @param {nsIDOMElement} aTemplate the template note to use.
  * @param {nsIDOMElement} aDestination the destination node where the
  * processed nodes will be displayed.
  * @param {object} aData the data to pass to the template.
+ * @param {Boolean} aPreserveDestination If true then the template will be
+ * appended to aDestination's content else aDestination.innerHTML will be
+ * cleared before the template is appended.
  */
-CssHtmlTree.processTemplate = function CssHtmlTree_processTemplate(aTemplate, aDestination, aData)
+CssHtmlTree.processTemplate = function CssHtmlTree_processTemplate(aTemplate,
+                                  aDestination, aData, aPreserveDestination)
 {
-  aDestination.innerHTML = "";
+  if (!aPreserveDestination) {
+    aDestination.innerHTML = "";
+  }
 
   // All the templater does is to populate a given DOM tree with the given
   // values, so we need to clone the template first.
   let duplicated = aTemplate.cloneNode(true);
   new Templater().processNode(duplicated, aData);
   while (duplicated.firstChild) {
     aDestination.appendChild(duplicated.firstChild);
   }
@@ -141,45 +149,72 @@ XPCOMUtils.defineLazyGetter(CssHtmlTree,
 
 CssHtmlTree.prototype = {
   /**
    * Focus the output display on a specific element.
    * @param {nsIDOMElement} aElement The highlighted node to get styles for.
    */
   highlight: function CssHtmlTree_highlight(aElement)
   {
-    this.viewedElement = aElement;
+    if (this.viewedElement == aElement) {
+      return;
+    }
 
-    // Reset the style groups. Without this previously expanded groups
-    // will fail to expand when inspecting subsequent nodes
-    let close = !aElement;
-    this.styleGroups.forEach(function(group) group.reset(close));
+    this.viewedElement = aElement;
 
     if (this.viewedElement) {
       this.viewedDocument = this.viewedElement.ownerDocument;
       CssHtmlTree.processTemplate(this.templateRoot, this.root, this);
     } else {
       this.viewedDocument = null;
       this.root.innerHTML = "";
     }
+
+    this.propertyContainer.innerHTML = "";
+
+    // We use a setTimeout loop to display the properties in batches of 25 at a
+    // time. This gives a perceptibly more responsive UI and allows us to cancel
+    // the displaying of properties in the case that a new element is selected.
+    let i = 0;
+    let batchSize = 25;
+    let max = CssHtmlTree.propertyNames.length - 1;
+    function displayProperties() {
+      if (this.viewedElement == aElement && this.panel.isOpen()) {
+        // Display the next 25 properties
+        for (let step = i + batchSize; i < step && i <= max; i++) {
+          let propView = new PropertyView(this, CssHtmlTree.propertyNames[i]);
+          CssHtmlTree.processTemplate(
+              this.templateProperty, this.propertyContainer, propView, true);
+        }
+        if (i < max) {
+          // There are still some properties to display. We loop here to display
+          // the next batch of 25.
+          this.win.setTimeout(displayProperties.bind(this), 0);
+        }
+      }
+    }
+    this.win.setTimeout(displayProperties.bind(this), 0);
   },
 
   /**
    * Called when the user clicks on a parent element in the "current element"
    * path.
    *
    * @param {Event} aEvent the DOM Event object.
    */
   pathClick: function CssHtmlTree_pathClick(aEvent)
   {
     aEvent.preventDefault();
-    if (aEvent.target && aEvent.target.pathElement) {
+    if (aEvent.target && this.viewedElement != aEvent.target.pathElement) {
+      this.propertyContainer.innerHTML = "";
       if (this.win.InspectorUI.selection) {
         if (aEvent.target.pathElement != this.win.InspectorUI.selection) {
-          this.win.InspectorUI.inspectNode(aEvent.target.pathElement);
+          let elt = aEvent.target.pathElement;
+          this.win.InspectorUI.inspectNode(elt);
+          this.panel.selectNode(elt);
         }
       } else {
         this.panel.selectNode(aEvent.target.pathElement);
       }
     }
   },
 
   /**
@@ -190,405 +225,65 @@ CssHtmlTree.prototype = {
    * selected element.
    */
   get pathElements()
   {
     return CssLogic.getShortNamePath(this.viewedElement);
   },
 
   /**
-   * Returns arrays of categorized properties.
+   * The CSS as displayed by the UI.
    */
-  _getPropertiesByGroup: function CssHtmlTree_getPropertiesByGroup()
+  createStyleViews: function CssHtmlTree_createStyleViews()
   {
-    return {
-      text: [
-        "color",                    // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "color-interpolation",      //
-        "color-interpolation-filters", //
-        "direction",                // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "fill",                     //
-        "fill-opacity",             //
-        "fill-rule",                //
-        "filter",                   //
-        "flood-color",              //
-        "flood-opacity",            //
-        "font-family",              // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "font-size",                // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "font-size-adjust",         // inherit http://www.w3.org/TR/WD-font/#font-size-props
-        "font-stretch",             // inherit http://www.w3.org/TR/WD-font/#font-stretch
-        "font-style",               // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "font-variant",             // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "font-weight",              // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "ime-mode",                 //
-        "letter-spacing",           // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "lighting-color",           //
-        "line-height",              // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "opacity",                  // no      http://www.w3.org/TR/css3-color/#transparency
-        "quotes",                   // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "stop-color",               //
-        "stop-opacity",             //
-        "stroke-opacity",           //
-        "text-align",               // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "text-anchor",              //
-        "text-decoration",          // no      http://www.w3.org/TR/CSS21/propidx.html
-        "text-indent",              // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "text-overflow",            //
-        "text-rendering",           // inherit http://www.w3.org/TR/SVG/painting.html#TextRenderingProperty !
-        "text-shadow",              // inherit http://www.w3.org/TR/css3-text/#text-shadow
-        "text-transform",           // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "vertical-align",           // no      http://www.w3.org/TR/CSS21/propidx.html
-        "white-space",              // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "word-spacing",             // inherit http://www.w3.org/TR/css3-text/#word-spacing
-        "word-wrap",                // inherit http://www.w3.org/TR/css3-text/#word-wrap
-        "-moz-column-count",        // no      http://www.w3.org/TR/css3-multicol/#column-count
-        "-moz-column-gap",          // no      http://www.w3.org/TR/css3-multicol/#column-gap
-        "-moz-column-rule-color",   // no      http://www.w3.org/TR/css3-multicol/#crc
-        "-moz-column-rule-style",   // no      http://www.w3.org/TR/css3-multicol/#column-rule-style
-        "-moz-column-rule-width",   // no      http://www.w3.org/TR/css3-multicol/#column-rule-width
-        "-moz-column-width",        // no      http://www.w3.org/TR/css3-multicol/#column-width
-        "-moz-font-feature-settings",  //
-        "-moz-font-language-override", //
-        "-moz-hyphens",                //
-        "-moz-text-decoration-color",  //
-        "-moz-text-decoration-style",  //
-        "-moz-text-decoration-line",   //
-        "-moz-text-blink",          //
-        "-moz-tab-size",            //
-      ],
-      list: [
-        "list-style-image",         // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "list-style-position",      // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "list-style-type",          // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "marker-end",               //
-        "marker-mid",               //
-        "marker-offset",            //
-        "marker-start",             //
-      ],
-      background: [
-        "background-attachment",    // no      http://www.w3.org/TR/css3-background/#background-attachment
-        "background-clip",          // no      http://www.w3.org/TR/css3-background/#background-clip
-        "background-color",         // no      http://www.w3.org/TR/css3-background/#background-color
-        "background-image",         // no      http://www.w3.org/TR/css3-background/#background-image
-        "background-origin",        // no      http://www.w3.org/TR/css3-background/#background-origin
-        "background-position",      // no      http://www.w3.org/TR/css3-background/#background-position
-        "background-repeat",        // no      http://www.w3.org/TR/css3-background/#background-repeat
-        "background-size",          // no      http://www.w3.org/TR/css3-background/#background-size
-        "-moz-appearance",          //
-        "-moz-background-inline-policy", //
-      ],
-      dims: [
-        "width",                    // no      http://www.w3.org/TR/CSS21/propidx.html
-        "height",                   // no      http://www.w3.org/TR/CSS21/propidx.html
-        "max-width",                // no      http://www.w3.org/TR/CSS21/propidx.html
-        "max-height",               // no      http://www.w3.org/TR/CSS21/propidx.html
-        "min-width",                // no      http://www.w3.org/TR/CSS21/propidx.html
-        "min-height",               // no      http://www.w3.org/TR/CSS21/propidx.html
-        "margin-top",               // no      http://www.w3.org/TR/CSS21/propidx.html
-        "margin-right",             // no      http://www.w3.org/TR/CSS21/propidx.html
-        "margin-bottom",            // no      http://www.w3.org/TR/CSS21/propidx.html
-        "margin-left",              // no      http://www.w3.org/TR/CSS21/propidx.html
-        "padding-top",              // no      http://www.w3.org/TR/CSS21/propidx.html
-        "padding-right",            // no      http://www.w3.org/TR/CSS21/propidx.html
-        "padding-bottom",           // no      http://www.w3.org/TR/CSS21/propidx.html
-        "padding-left",             // no      http://www.w3.org/TR/CSS21/propidx.html
-        "clip",                     // no      http://www.w3.org/TR/CSS21/propidx.html
-        "clip-path",                //
-        "clip-rule",                //
-        "resize",                   // no      http://www.w3.org/TR/css3-ui/#resize
-        "stroke-width",             //
-        "-moz-box-flex",            //
-        "-moz-box-sizing",          // no      http://www.w3.org/TR/css3-ui/#box-sizing
-      ],
-      pos: [
-        "top",                      // no      http://www.w3.org/TR/CSS21/propidx.html
-        "right",                    // no      http://www.w3.org/TR/CSS21/propidx.html
-        "bottom",                   // no      http://www.w3.org/TR/CSS21/propidx.html
-        "left",                     // no      http://www.w3.org/TR/CSS21/propidx.html
-        "display",                  // no      http://www.w3.org/TR/CSS21/propidx.html
-        "float",                    // no      http://www.w3.org/TR/CSS21/propidx.html
-        "clear",                    // no      http://www.w3.org/TR/CSS21/propidx.html
-        "position",                 // no      http://www.w3.org/TR/CSS21/propidx.html
-        "visibility",               // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "overflow",                 //
-        "overflow-x",               // no      http://www.w3.org/TR/CSS21/propidx.html
-        "overflow-y",               // no      http://www.w3.org/TR/CSS21/propidx.html
-        "z-index",                  // no      http://www.w3.org/TR/CSS21/propidx.html
-        "dominant-baseline",        //
-        "page-break-after",         //
-        "page-break-before",        //
-        "stroke-dashoffset",        //
-        "unicode-bidi",             //
-        "-moz-box-align",           //
-        "-moz-box-direction",       //
-        "-moz-box-ordinal-group",   //
-        "-moz-box-orient",          //
-        "-moz-box-pack",            //
-        "-moz-float-edge",          //
-        "-moz-orient",              //
-        "-moz-stack-sizing",        //
-      ],
-      border: [
-        "border-top-width",         // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-right-width",       // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-bottom-width",      // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-left-width",        // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-top-color",         // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-right-color",       // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-bottom-color",      // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-left-color",        // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-top-style",         // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-right-style",       // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-bottom-style",      // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-left-style",        // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-collapse",          // no      http://www.w3.org/TR/CSS21/propidx.html
-        "border-spacing",           // no      http://www.w3.org/TR/CSS21/propidx.html
-        "outline-offset",           // no      http://www.w3.org/TR/CSS21/propidx.html
-        "outline-style",            //
-        "outline-color",            //
-        "outline-width",            //
-        "border-top-left-radius",       // no http://www.w3.org/TR/css3-background/#border-radius
-        "border-top-right-radius",      // no http://www.w3.org/TR/css3-background/#border-radius
-        "border-bottom-right-radius",   // no http://www.w3.org/TR/css3-background/#border-radius
-        "border-bottom-left-radius",    // no http://www.w3.org/TR/css3-background/#border-radius
-        "-moz-border-bottom-colors",    //
-        "-moz-border-image",            //
-        "-moz-border-left-colors",      //
-        "-moz-border-right-colors",     //
-        "-moz-border-top-colors",       //
-        "-moz-outline-radius-topleft",      // no http://www.w3.org/TR/CSS2/ui.html#dynamic-outlines ?
-        "-moz-outline-radius-topright",     // no http://www.w3.org/TR/CSS2/ui.html#dynamic-outlines ?
-        "-moz-outline-radius-bottomright",  // no http://www.w3.org/TR/CSS2/ui.html#dynamic-outlines ?
-        "-moz-outline-radius-bottomleft",   // no http://www.w3.org/TR/CSS2/ui.html#dynamic-outlines ?
-      ],
-      other: [
-        "box-shadow",               // no      http://www.w3.org/TR/css3-background/#box-shadow
-        "caption-side",             // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "content",                  // no      http://www.w3.org/TR/CSS21/propidx.html
-        "counter-increment",        // no      http://www.w3.org/TR/CSS21/propidx.html
-        "counter-reset",            // no      http://www.w3.org/TR/CSS21/propidx.html
-        "cursor",                   // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "empty-cells",              // inherit http://www.w3.org/TR/CSS21/propidx.html
-        "image-rendering",          // inherit http://www.w3.org/TR/SVG/painting.html#ImageRenderingProperty
-        "mask",                     //
-        "pointer-events",           // inherit http://www.w3.org/TR/SVG11/interact.html#PointerEventsProperty
-        "shape-rendering",          //
-        "stroke",                   //
-        "stroke-dasharray",         //
-        "stroke-linecap",           //
-        "stroke-linejoin",          //
-        "stroke-miterlimit",        //
-        "table-layout",             // no      http://www.w3.org/TR/CSS21/propidx.html
-        "-moz-animation-delay",     //
-        "-moz-animation-direction", //
-        "-moz-animation-duration",  //
-        "-moz-animation-fill-mode", //
-        "-moz-animation-iteration-count", //
-        "-moz-animation-name",            //
-        "-moz-animation-play-state",      //
-        "-moz-animation-timing-function", //
-        "-moz-backface-visibility",       //
-        "-moz-binding",                   //
-        "-moz-force-broken-image-icon",   //
-        "-moz-image-region",        //
-        "-moz-perspective",         //
-        "-moz-perspective-origin",  //
-        "-moz-transform",           // no      http://www.w3.org/TR/css3-2d-transforms/#transform-property
-        "-moz-transform-origin",    //
-        "-moz-transition-delay",    //
-        "-moz-transition-duration", //
-        "-moz-transition-property", //
-        "-moz-transition-timing-function", //
-        "-moz-user-focus",          // inherit http://www.w3.org/TR/2000/WD-css3-userint-20000216#user-focus
-        "-moz-user-input",          // inherit http://www.w3.org/TR/2000/WD-css3-userint-20000216#user-input
-        "-moz-user-modify",         // inherit http://www.w3.org/TR/2000/WD-css3-userint-20000216#user-modify
-        "-moz-user-select",         // no      http://www.w3.org/TR/2000/WD-css3-userint-20000216#user-select
-        "-moz-window-shadow",       //
-      ],
-    };
-  },
-
-  /**
-   * The CSS groups as displayed by the UI.
-   */
-  createStyleGroupViews: function CssHtmlTree_createStyleGroupViews()
-  {
-    if (!CssHtmlTree.propertiesByGroup) {
-      let pbg = CssHtmlTree.propertiesByGroup = this._getPropertiesByGroup();
-
-      // Add any supported properties that are not categorized to the "other" group
-      let mergedArray = Array.concat(
-          pbg.text,
-          pbg.list,
-          pbg.background,
-          pbg.dims,
-          pbg.pos,
-          pbg.border,
-          pbg.other
-      );
-
-      // Here we build and cache a list of css properties supported by the browser
-      // and store a list to check against. We could use any element but let's
-      // use the inspector style panel
-      let styles = this.styleWin.contentWindow.getComputedStyle(this.styleDocument.body);
-      CssHtmlTree.supportedPropertyLookup = {};
-      for (let i = 0, numStyles = styles.length; i < numStyles; i++) {
-        let prop = styles.item(i);
-        CssHtmlTree.supportedPropertyLookup[prop] = true;
-
-        if (mergedArray.indexOf(prop) == -1) {
-          pbg.other.push(prop);
-        }
-      }
-
-      this.propertiesByGroup = CssHtmlTree.propertiesByGroup;
-    }
-
-    let pbg = CssHtmlTree.propertiesByGroup;
-
-    // These group titles are localized by their ID. See the styleinspector.properties file.
-    this.styleGroups = [
-      new StyleGroupView(this, "Text_Fonts_and_Color", pbg.text),
-      new StyleGroupView(this, "Lists", pbg.list),
-      new StyleGroupView(this, "Background", pbg.background),
-      new StyleGroupView(this, "Dimensions", pbg.dims),
-      new StyleGroupView(this, "Positioning_and_Page_Flow", pbg.pos),
-      new StyleGroupView(this, "Borders", pbg.border),
-      new StyleGroupView(this, "Effects_and_Other", pbg.other),
-    ];
-  },
-};
-
-/**
- * A container to give easy access to style group data from the template engine.
- *
- * @constructor
- * @param {CssHtmlTree} aTree the instance of the CssHtmlTree object that we are
- * working with.
- * @param {string} aId the style group ID.
- * @param {array} aPropertyNames the list of property names associated to this
- * style group view.
- */
-function StyleGroupView(aTree, aId, aPropertyNames)
-{
-  this.tree = aTree;
-  this.id = aId;
-  this.getRTLAttr = CssHtmlTree.getRTLAttr;
-  this.localName = CssHtmlTree.l10n("group." + this.id);
-
-  this.propertyViews = [];
-  aPropertyNames.forEach(function(aPropertyName) {
-    if (this.isPropertySupported(aPropertyName)) {
-      this.propertyViews.push(new PropertyView(this.tree, this, aPropertyName));
-    }
-  }, this);
-
-  this.populated = false;
-
-  this.templateProperties = this.tree.styleDocument.getElementById("templateProperties");
-
-  // Populated by templater: parent element containing the open attribute
-  this.element = null;
-  // Destination for templateProperties.
-  this.properties = null;
-}
-
-StyleGroupView.prototype = {
-  /**
-   * The click event handler for the title of the style group view.
-   */
-  click: function StyleGroupView_click()
-  {
-    // TODO: Animate opening/closing. See bug 587752.
-    if (this.element.hasAttribute("open")) {
-      this.element.removeAttribute("open");
+    if (CssHtmlTree.propertyNames) {
       return;
     }
 
-    if (!this.populated) {
-      CssHtmlTree.processTemplate(this.templateProperties, this.properties, this);
-      this.populated = true;
+    CssHtmlTree.propertyNames = [];
+
+    // Here we build and cache a list of css properties supported by the browser
+    // We could use any element but let's use the main document's body
+    let styles = this.styleWin.contentWindow.getComputedStyle(this.styleDocument.body);
+    let mozProps = [];
+    for (let i = 0, numStyles = styles.length; i < numStyles; i++) {
+      let prop = styles.item(i);
+      if (prop.charAt(0) == "-") {
+        mozProps.push(prop);
+      } else {
+        CssHtmlTree.propertyNames.push(prop);
+      }
     }
 
-    this.element.setAttribute("open", "");
-  },
-
-  /**
-   * Close the style group view.
-   */
-  close: function StyleGroupView_close()
-  {
-    if (this.element) {
-      this.element.removeAttribute("open");
-    }
-  },
-
-  /**
-   * Reset the style group view and its property views.
-   *
-   * @param {boolean} aClosePanel tells if the style panel is closing or not.
-   */
-  reset: function StyleGroupView_reset(aClosePanel)
-  {
-    this.close();
-    this.populated = false;
-    for (let i = 0, numViews = this.propertyViews.length; i < numViews; i++) {
-      this.propertyViews[i].reset();
-    }
-
-    if (this.properties) {
-      if (aClosePanel) {
-        if (this.element) {
-          this.element.removeChild(this.properties);
-        }
-
-        this.properties = null;
-      } else {
-        while (this.properties.hasChildNodes()) {
-          this.properties.removeChild(this.properties.firstChild);
-        }
-      }
-    }
-  },
-
-  /**
-   * Check if a CSS property is supported
-   *
-   * @param {string} aProperty the CSS property to check for
-   *
-   * @return {boolean} true or false
-   */
-  isPropertySupported: function(aProperty) {
-    return aProperty && aProperty in CssHtmlTree.supportedPropertyLookup;
+    CssHtmlTree.propertyNames.sort();
+    CssHtmlTree.propertyNames.push.apply(CssHtmlTree.propertyNames,
+      mozProps.sort());
   },
 };
 
 /**
  * A container to give easy access to property data from the template engine.
  *
  * @constructor
  * @param {CssHtmlTree} aTree the CssHtmlTree instance we are working with.
- * @param {StyleGroupView} aGroup the StyleGroupView instance we are working
- * with.
  * @param {string} aName the CSS property name for which this PropertyView
  * instance will render the rules.
  */
-function PropertyView(aTree, aGroup, aName)
+function PropertyView(aTree, aName)
 {
   this.tree = aTree;
-  this.group = aGroup;
   this.name = aName;
   this.getRTLAttr = CssHtmlTree.getRTLAttr;
 
   this.populated = false;
   this.showUnmatched = false;
 
   this.link = "https://developer.mozilla.org/en/CSS/" + aName;
 
-  this.templateRules = this.tree.styleDocument.getElementById("templateRules");
+  this.templateRules = aTree.styleDocument.getElementById("templateRules");
 
   // The parent element which contains the open attribute
   this.element = null;
   // Destination for templateRules.
   this.rules = null;
 
   this.str = {};
 }
@@ -603,17 +298,16 @@ PropertyView.prototype = {
    */
   click: function PropertyView_click(aEvent)
   {
     // Clicking on the property link itself is already handled
     if (aEvent.target.tagName.toLowerCase() == "a") {
       return;
     }
 
-    // TODO: Animate opening/closing. See bug 587752.
     if (this.element.hasAttribute("open")) {
       this.element.removeAttribute("open");
       return;
     }
 
     if (!this.populated) {
       let matchedRuleCount = this.propertyInfo.matchedRuleCount;
 
@@ -656,25 +350,29 @@ PropertyView.prototype = {
    */
   ruleTitle: function PropertyView_ruleTitle(aElement)
   {
     let result = "";
     let matchedRuleCount = this.propertyInfo.matchedRuleCount;
 
     if (matchedRuleCount > 0) {
       aElement.classList.add("rule-count");
+      aElement.firstElementChild.className = "expander";
 
       let str = CssHtmlTree.l10n("property.numberOfRules");
-      result = PluralForm.get(matchedRuleCount, str).replace("#1", matchedRuleCount);
+      result = PluralForm.get(matchedRuleCount, str)
+          .replace("#1", matchedRuleCount);
     } else if (this.showUnmatchedLink) {
       aElement.classList.add("rule-unmatched");
+      aElement.firstElementChild.className = "expander";
 
       let unmatchedRuleCount = this.propertyInfo.unmatchedRuleCount;
       let str = CssHtmlTree.l10n("property.numberOfUnmatchedRules");
-      result = PluralForm.get(unmatchedRuleCount, str).replace("#1", unmatchedRuleCount);
+      result = PluralForm.get(unmatchedRuleCount, str)
+          .replace("#1", unmatchedRuleCount);
     }
     return result;
   },
 
   /**
    * Close the property view.
    */
   close: function PropertyView_close()
@@ -767,17 +465,18 @@ SelectorView.STATUS_NAMES = [
 SelectorView.CLASS_NAMES = [
   "unmatched", "parentmatch", "matched", "bestmatch"
 ];
 
 SelectorView.prototype = {
   /**
    * Cache localized status names.
    *
-   * These statuses are localized inside the styleinspector.properties string bundle.
+   * These statuses are localized inside the styleinspector.properties string
+   * bundle.
    * @see CssLogic.jsm - the CssLogic.STATUS array.
    *
    * @return {void}
    */
   _cacheStatusNames: function SelectorView_cacheStatusNames()
   {
     if (SelectorView.STATUS_NAMES.length) {
       return;
--- a/browser/devtools/styleinspector/csshtmltree.xhtml
+++ b/browser/devtools/styleinspector/csshtmltree.xhtml
@@ -61,16 +61,20 @@
     href="chrome://browser/skin/devtools/csshtmltree.css" />
 </head>
 <body role="application">
 
 <!-- The output from #templateRoot (below) is inserted here. -->
 <div id="root">
 </div>
 
+<!-- The output from #templateProperty (below) is appended here. -->
+<div id="propertyContainer">
+</div>
+
 <!--
 To visually debug the templates without running firefox, alter the display:none
 -->
 <div style="display:none;">
   <!--
   templateRoot sits at the top of the window showing what we're looking at.
   For data it needs an instance of CssHtmlTree.
   -->
@@ -80,48 +84,37 @@ To visually debug the templates without 
       <ol>
         <li foreach="item in ${pathElements}" dir="${getRTLAttr}">
           <a href="#" onclick="${pathClick}" __pathElement="${item.element}">
             ${__element.pathElement = item.element; item.display}
           </a>
         </li>
       </ol>
     </p>
-
-    <div _id="groups">
-      <div foreach="group in ${styleGroups}" class="group" save="${group.element}" dir="${getRTLAttr}">
-        <h1 onclick="${group.click}" dir="${getRTLAttr}">
-          ${group.localName}
-          <div class="groupexpander"></div>
-        </h1>
-        <div save="${group.properties}"></div>
-      </div>
-    </div>
   </div>
 
   <!--
-  A templateProperties sits inside each templateGroups to show the properties
-  themselves. Each needs data like this:
+  TemplateProperty lists the properties themselves. Each needs data like this:
   {
-    property: [ ..., ] // Array of PropertyViews from CssHtmlTree.jsm
+    property: ... // PropertyView from CssHtmlTree.jsm
   }
   -->
-  <div id="templateProperties">
-    <div foreach="property in ${propertyViews}" class="property-view" save="${property.element}" dir="${getRTLAttr}">
-      <div class="property-header" onclick="${property.click}">
-        <span class="property-name" dir="${getRTLAttr}">
+  <div id="templateProperty">
+    <div class="property-view" save="${element}" dir="${getRTLAttr}">
+      <div class="property-header" onclick="${click}">
+        <div class="property-name" dir="${getRTLAttr}">
           <a class="link" target="_blank" title="&helpLinkTitle;"
-              href="${property.link}">${property.name}</a>
-        </span>
-        <span class="property-value" dir="ltr">${property.value}</span>
-        <span class="link" dir="${getRTLAttr}">
-          ${property.ruleTitle(__element)}<div class="expander"></div>
-        </span>
+              href="${link}">${name}</a>
+        </div>
+        <div class="property-value" dir="ltr">${value}</div>
+        <div class="link" dir="${getRTLAttr}">
+          <div></div>${ruleTitle(__element)}
+        </div>
       </div>
-      <table class="rules" save="${property.rules}" dir="${getRTLAttr}"></table>
+      <table class="rules" save="${rules}" dir="${getRTLAttr}"></table>
     </div>
   </div>
 
   <!--
   A templateRules sits inside each templateProperties showing the list of rules
   that affect that property. Each needs data like this:
   {
     selectors: ..., // from cssLogic.getPropertyInfo(x).[un]matchedSelectors
@@ -142,17 +135,19 @@ To visually debug the templates without 
         <td class="rule-link">
           <a target="_blank" href="view-source:${selector.selectorInfo.href}" class="link"
               title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a>
         </td>
       </tr>
     </loop>
     <tr if="${showUnmatchedLink}">
       <td colspan="4">
-        <a href="#" onclick="${showUnmatchedLinkClick}"
-            class="link">${showUnmatchedLinkText}</a>
+        <div class="expander unmatched-rule"></div>
+        <div class="unmatched">
+          <a href="#" onclick="${showUnmatchedLinkClick}" class="unmatchedlink">${showUnmatchedLinkText}</a>
+        </div>
       </td>
     </tr>
   </table>
 </div>
 
 </body>
 </html>
--- a/browser/devtools/styleinspector/test/browser/browser_styleinspector.js
+++ b/browser/devtools/styleinspector/test/browser/browser_styleinspector.js
@@ -34,99 +34,43 @@ function createDocument()
 }
 
 function runStyleInspectorTests()
 {
   Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
 
   ok(stylePanel.isOpen(), "style inspector is open");
 
-  checkForNewProperties();
-
   var spans = doc.querySelectorAll("span");
   ok(spans, "captain, we have the spans");
 
   let htmlTree = stylePanel.cssHtmlTree;
 
   for (var i = 0, numSpans = spans.length; i < numSpans; i++) {
     stylePanel.selectNode(spans[i]);
 
     is(spans[i], htmlTree.viewedElement,
       "style inspector node matches the selected node");
     is(htmlTree.viewedElement, stylePanel.cssLogic.viewedElement,
        "cssLogic node matches the cssHtmlTree node");
-
-    // The Fonts and Color group.
-    ok(groupRuleCount(0) > 0, "we have rules for the current span");
   }
 
   SI_CheckProperty();
   Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
   stylePanel.hidePopup();
 }
 
-function checkForNewProperties()
-{
-  let htmlTree = stylePanel.cssHtmlTree;
-  htmlTree.createStyleGroupViews();
-  let otherProps = htmlTree._getPropertiesByGroup().other;
-  let otherPlusUnknownProps = htmlTree.propertiesByGroup.other;
-
-  let missingProps = [];
-  for each (let prop in otherPlusUnknownProps) {
-    if (otherProps.indexOf(prop) == -1) {
-      missingProps.push(prop);
-    }
-  }
-
-  if (missingProps.length > 0) {
-    let n = 1;
-    let msg = "The following css properties need to be categorized in " +
-              "CssHtmlTree.getPropertiesByGroup():\r\n";
-    missingProps.forEach(function BSI_buildMissingProps(aProp) {
-      msg += "  " + (n++) + ". " + aProp + "\n";
-    });
-    ok(false, msg);
-  }
-}
-
 function SI_CheckProperty()
 {
-  let group = stylePanel.cssHtmlTree.styleGroups[0];
   let cssLogic = stylePanel.cssLogic;
-
   let propertyInfo = cssLogic.getPropertyInfo("color");
   ok(propertyInfo.matchedRuleCount > 0, "color property has matching rules");
   ok(propertyInfo.unmatchedRuleCount > 0, "color property has unmatched rules");
 }
 
-function groupRuleCount(groupId)
-{
-  let groupRules = 0;
-  let group = stylePanel.cssHtmlTree.styleGroups[groupId];
-
-  ok(group, "we have a StyleGroupView");
-  ok(group.tree, "we have the CssHtmlTree object");
-
-  let cssLogic = stylePanel.cssLogic;
-
-  ok(cssLogic, "we have the CssLogic object");
-
-  // we use the click method to populate the groups properties
-  group.click();
-
-  ok(group.properties.childElementCount > 0, "the StyleGroupView has properties");
-
-  group.propertyViews.forEach(function(property) {
-    groupRules += cssLogic.getPropertyInfo(property.name).matchedRuleCount;
-  });
-
-  return groupRules;
-}
-
 function finishUp()
 {
   Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
   ok(!stylePanel.isOpen(), "style inspector is closed");
   doc = stylePanel = null;
   gBrowser.removeCurrentTab();
   finish();
 }
--- a/browser/devtools/styleinspector/test/browser/browser_styleinspector_webconsole.htm
+++ b/browser/devtools/styleinspector/test/browser/browser_styleinspector_webconsole.htm
@@ -162,17 +162,17 @@
     span:lang(en) {
       font-family: sans-serif;
     }
 
     span:lang(it) {
       font-family: fantasy;
     }
 
-    html::selection {
+    html::-moz-selection {
       background-color: #f00;
       font-family: fantasy;
     }
   </style>
 </head>
 <body>
   <h2>font-size</h2>
   <div id="container">
--- a/browser/devtools/styleinspector/test/browser/browser_styleinspector_webconsole.js
+++ b/browser/devtools/styleinspector/test/browser/browser_styleinspector_webconsole.js
@@ -123,19 +123,16 @@ function teststylePanels() {
     let eltId = elt.id;
 
     // Check that the correct node is selected
     is(elt, htmlTree.viewedElement,
       "style inspector node matches the selected node (id=" + eltId + ")");
     is(htmlTree.viewedElement, stylePanels[i].cssLogic.viewedElement,
       "cssLogic node matches the cssHtmlTree node (id=" + eltId + ")");
 
-    ok(groupRuleCount(0, stylePanels[i]) > 0,
-       "we have rules for the current node (id=" + eltArray[i].id + ")");
-
     // Check that the correct css selector has been selected as active
     let matchedSelectors = cssLogic.getPropertyInfo("font-family").matchedSelectors;
     let sel = matchedSelectors[0];
     let selector = sel.selector.text;
     let value = sel.value;
 
     // Because we know which selectors should be the best match and what their
     // values should be we can check them
@@ -195,32 +192,8 @@ function cleanUp()
   let popupSet = document.getElementById("mainPopupSet");
   ok(!popupSet.lastChild.hasAttribute("hudToolId"),
      "all style inspector panels are now detached and ready for garbage collection");
 
   info("cleaning up");
   doc = hudBox = stylePanels = jsterm = null;
   finishTest();
 }
-
-function groupRuleCount(groupId, aStylePanel)
-{
-  let groupRules = 0;
-  let group = aStylePanel.cssHtmlTree.styleGroups[groupId];
-
-  ok(group, "we have a StyleGroupView");
-  ok(group.tree, "we have the CssHtmlTree object");
-
-  let cssLogic = aStylePanel.cssLogic;
-
-  ok(cssLogic, "we have the CssLogic object");
-
-  // we use the click event to populate the groups properties
-  group.click();
-
-  ok(group.properties.childElementCount > 0, "the StyleGroupView has properties");
-
-  group.propertyViews.forEach(function(property) {
-    groupRules += cssLogic.getPropertyInfo(property.name).matchedRuleCount;
-  });
-
-  return groupRules;
-}
--- a/browser/themes/gnomestripe/browser/devtools/csshtmltree.css
+++ b/browser/themes/gnomestripe/browser/devtools/csshtmltree.css
@@ -33,27 +33,26 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 body {
-  font-family: Lucida Grande, sans-serif;
+  font-family: sans-serif;
   font-size: 11px;
   background: #EEE;
 }
-
 .path {
   font-size: 11px;
   word-spacing: -1px;
 }
 .path ol {
-  list-style: none;
+  list-style: none outside none;
   margin: 0;
   padding: 0;
 }
 .path li {
   border-radius: 3px;
   padding: 2px 3px;
   text-shadow: #FFF 0 1px 0;
   font-weight: bold;
@@ -67,170 +66,136 @@ body {
 .path li:last-child {
   background: -moz-linear-gradient(top, #FFC, #DD8);
 }
 .path li:last-child:after {
   color: red;
   content: "";
 }
 
-#sheetList, #sheetList menuitem {
-  font-size: 1em;
-  font-weight: normal;
-}
-
-.sheet_line input {
-  vertical-align: middle;
-}
-
-.sheet_line label {
-  cursor: pointer;
-}
-
-#header, #footer {
+#header,
+#footer {
   padding: 5px;
 }
 
 #header label {
   font-weight: bold;
 }
-#sheets {
-  -moz-margin-end: 10px;
-  margin-top: 5px;
-}
-h1 {
-  font-size: 13px;
-  padding: 2px 10px;
-  margin: 0;
-  background: -moz-linear-gradient(top, #CCC, #AAA);
-  border-radius: 3px;
-  text-shadow: #FFF 0 1px 0;
-  cursor: pointer;
-}
 
 .property-header {
   padding: 2px 5px;
   background: -moz-linear-gradient(top, #F8F8F8, #E8E8E8);
   color: #666;
 }
 
-.property-name, .property-value, .rule-count, .rule-unmatched {
+.property-name,
+.property-value,
+.rule-count,
+.rule-unmatched {
   cursor: pointer;
 }
 
 /* Take away these two :visited rules to get a core dumper     */
 /* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
-.link { color: #55A;  }
-.link:visited { color: #55A;  }
-a.link { text-decoration: none; cursor: pointer }
-a.link:visited { text-decoration: none; }
-.rule-count, .rule-unmatched {
-  float: right;
+.link,
+.unmatchedlink {
+  color: #55A;
+}
+.link:visited,
+.unmatchedlink:visited {
+  color: #55A;
+}
+a.link,
+a.unmatchedlink {
+  text-decoration: none;
+  cursor: pointer;
 }
-.rule-count[dir="rtl"], .rule-unmatched[dir="rtl"] {
-  float: left;
+a.link:visited,
+a.unmatchedlink:visited {
+  text-decoration: none;
 }
-.property-view .rule-count .expander,
-.property-view .rule-unmatched .expander {
+
+.rule-count,
+.rule-unmatched {
+  padding: 5px 0 0 15px;
+}
+.unmatched {
+  display: inline-block;
+}
+.expander {
   width: 8px;
   height: 8px;
-  -moz-margin-start: 5px;
   display: inline-block;
+  -moz-margin-end: 5px;
+  margin-bottom: 1px;
   background: url("chrome://browser/skin/devtools/arrows.png");
 }
 
+.unmatched-rule {
+  -moz-margin-start: 25px;
+  background-position: 24px 0;
+}
+
 .property-view .rule-count .expander,
 .property-view .rule-unmatched .expander {
   background-position: 24px 0;
 }
 .property-view[dir="rtl"] .rule-count .expander,
 .property-view[dir="rtl"] .rule-unmatched .expander {
   background-position: 16px 0;
 }
 .property-view[open] .rule-count .expander,
 .property-view[open] .rule-unmatched .expander {
   background-position: 8px 0;
 }
 
 .property-name {
+  display: inline-block;
   font-size: 12px;
   font-weight: bold;
-  -moz-padding-end: 4px;
   color: #000;
 }
-span.property-value {
-  -moz-padding-end: 5px;
+.property-value {
+  display: inline-block;
   font-size: 10px;
 }
-.group {
-  margin-top: 10px;
-}
-
-.group > h1 {
-  color: #333;
-  font-size: 11px;
-}
-.group .groupexpander {
-  width: 8px;
-  height: 8px;
-  margin-top: 2px;
-  background: url("chrome://browser/skin/devtools/arrows.png");
-}
-.group > div {
-  display: none;
-}
-.group[open] > div {
-  display: block;
-}
-.group .groupexpander {
-  background-position: 48px 0;
-  float: right;
-}
-.group[dir="rtl"] .groupexpander {
-  background-position: 40px 0;
-  float: left;
-}
-.group[open] .groupexpander {
-  background-position: 32px 0;
-  float: right;
-}
-.group[open][dir="rtl"] .groupexpander {
-  background-position: 32px 0;
-  float: left;
-}
-
-.group, #header, #footer {
-  background: #FFF;
-  border: 1px solid #E1E1E1;
-  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-  border-radius: 4px 4px 4px 4px;
-}
 
 .property-view > .rules {
   display: none;
 }
 .property-view[open] > .rules {
   display: table;
 }
 .rules {
+  -moz-margin-start: 32px;
   max-height: 350px;
   overflow-y: auto;
 }
-.rule-specificty, .rule-status {
+.rule-status {
   white-space: nowrap;
 }
 .rule-link {
   text-align: end;
+  -moz-padding-start: 10px;
 }
 
 /* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
 .rule-text {
   direction: ltr;
+  -moz-padding-start: 10px;
 }
 
 .resizerbox {
   background-color: window;
 }
 
-.bestmatch { color: black; }
-.matched { text-decoration: line-through; }
-.parentmatch { color: #666; }
-.unmatched { color: brown; }
+.bestmatch {
+  color: black;
+}
+.matched {
+  text-decoration: line-through;
+}
+.parentmatch {
+  color: #666;
+}
+.unmatched {
+  color: brown;
+}
--- a/browser/themes/pinstripe/browser/devtools/csshtmltree.css
+++ b/browser/themes/pinstripe/browser/devtools/csshtmltree.css
@@ -33,27 +33,26 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 body {
-  font-family: Lucida Grande, sans-serif;
+  font-family: sans-serif;
   font-size: 11px;
   background: #EEE;
 }
-
 .path {
   font-size: 11px;
   word-spacing: -1px;
 }
 .path ol {
-  list-style: none;
+  list-style: none outside none;
   margin: 0;
   padding: 0;
 }
 .path li {
   border-radius: 3px;
   padding: 2px 3px;
   text-shadow: #FFF 0 1px 0;
   font-weight: bold;
@@ -67,170 +66,136 @@ body {
 .path li:last-child {
   background: -moz-linear-gradient(top, #FFC, #DD8);
 }
 .path li:last-child:after {
   color: red;
   content: "";
 }
 
-#sheetList, #sheetList menuitem {
-  font-size: 1em;
-  font-weight: normal;
-}
-
-.sheet_line input {
-  vertical-align: middle;
-}
-
-.sheet_line label {
-  cursor: pointer;
-}
-
-#header, #footer {
+#header,
+#footer {
   padding: 5px;
 }
 
 #header label {
   font-weight: bold;
 }
-#sheets {
-  -moz-margin-end: 10px;
-  margin-top: 5px;
-}
-h1 {
-  font-size: 13px;
-  padding: 2px 10px;
-  margin: 0;
-  background: -moz-linear-gradient(top, #CCC, #AAA);
-  border-radius: 3px;
-  text-shadow: #FFF 0 1px 0;
-  cursor: pointer;
-}
 
 .property-header {
   padding: 2px 5px;
   background: -moz-linear-gradient(top, #F8F8F8, #E8E8E8);
   color: #666;
 }
 
-.property-name, .property-value, .rule-count, .rule-unmatched {
+.property-name,
+.property-value,
+.rule-count,
+.rule-unmatched {
   cursor: pointer;
 }
 
 /* Take away these two :visited rules to get a core dumper     */
 /* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
-.link { color: #55A;  }
-.link:visited { color: #55A;  }
-a.link { text-decoration: none; cursor: pointer }
-a.link:visited { text-decoration: none; }
-.rule-count, .rule-unmatched {
-  float: right;
+.link,
+.unmatchedlink {
+  color: #55A;
+}
+.link:visited,
+.unmatchedlink:visited {
+  color: #55A;
+}
+a.link,
+a.unmatchedlink {
+  text-decoration: none;
+  cursor: pointer;
 }
-.rule-count[dir="rtl"], .rule-unmatched[dir="rtl"] {
-  float: left;
+a.link:visited,
+a.unmatchedlink:visited {
+  text-decoration: none;
 }
-.property-view .rule-count .expander,
-.property-view .rule-unmatched .expander {
+
+.rule-count,
+.rule-unmatched {
+  padding: 5px 0 0 15px;
+}
+.unmatched {
+  display: inline-block;
+}
+.expander {
   width: 8px;
   height: 8px;
-  -moz-margin-start: 5px;
   display: inline-block;
+  -moz-margin-end: 5px;
+  margin-bottom: 1px;
   background: url("chrome://browser/skin/devtools/arrows.png");
 }
 
+.unmatched-rule {
+  -moz-margin-start: 25px;
+  background-position: 24px 0;
+}
+
 .property-view .rule-count .expander,
 .property-view .rule-unmatched .expander {
   background-position: 24px 0;
 }
 .property-view[dir="rtl"] .rule-count .expander,
 .property-view[dir="rtl"] .rule-unmatched .expander {
   background-position: 16px 0;
 }
 .property-view[open] .rule-count .expander,
 .property-view[open] .rule-unmatched .expander {
   background-position: 8px 0;
 }
 
 .property-name {
+  display: inline-block;
   font-size: 12px;
   font-weight: bold;
-  -moz-padding-end: 4px;
   color: #000;
 }
-span.property-value {
-  -moz-padding-end: 5px;
+.property-value {
+  display: inline-block;
   font-size: 10px;
 }
-.group {
-  margin-top: 10px;
-}
-
-.group > h1 {
-  color: #333;
-  font-size: 11px;
-}
-.group .groupexpander {
-  width: 8px;
-  height: 8px;
-  margin-top: 2px;
-  background: url("chrome://browser/skin/devtools/arrows.png");
-}
-.group > div {
-  display: none;
-}
-.group[open] > div {
-  display: block;
-}
-.group .groupexpander {
-  background-position: 48px 0;
-  float: right;
-}
-.group[dir="rtl"] .groupexpander {
-  background-position: 40px 0;
-  float: left;
-}
-.group[open] .groupexpander {
-  background-position: 32px 0;
-  float: right;
-}
-.group[open][dir="rtl"] .groupexpander {
-  background-position: 32px 0;
-  float: left;
-}
-
-.group, #header, #footer {
-  background: #FFF;
-  border: 1px solid #E1E1E1;
-  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-  border-radius: 4px 4px 4px 4px;
-}
 
 .property-view > .rules {
   display: none;
 }
 .property-view[open] > .rules {
   display: table;
 }
 .rules {
+  -moz-margin-start: 32px;
   max-height: 350px;
   overflow-y: auto;
 }
-.rule-specificty, .rule-status {
+.rule-status {
   white-space: nowrap;
 }
 .rule-link {
   text-align: end;
+  -moz-padding-start: 10px;
 }
 
 /* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
 .rule-text {
   direction: ltr;
+  -moz-padding-start: 10px;
 }
 
 .resizerbox {
   background-color: window;
 }
 
-.bestmatch { color: black; }
-.matched { text-decoration: line-through; }
-.parentmatch { color: #666; }
-.unmatched { color: brown; }
+.bestmatch {
+  color: black;
+}
+.matched {
+  text-decoration: line-through;
+}
+.parentmatch {
+  color: #666;
+}
+.unmatched {
+  color: brown;
+}
--- a/browser/themes/winstripe/browser/devtools/csshtmltree.css
+++ b/browser/themes/winstripe/browser/devtools/csshtmltree.css
@@ -33,27 +33,26 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 body {
-  font-family: Lucida Grande, sans-serif;
+  font-family: sans-serif;
   font-size: 11px;
   background: #EEE;
 }
-
 .path {
   font-size: 11px;
   word-spacing: -1px;
 }
 .path ol {
-  list-style: none;
+  list-style: none outside none;
   margin: 0;
   padding: 0;
 }
 .path li {
   border-radius: 3px;
   padding: 2px 3px;
   text-shadow: #FFF 0 1px 0;
   font-weight: bold;
@@ -67,170 +66,136 @@ body {
 .path li:last-child {
   background: -moz-linear-gradient(top, #FFC, #DD8);
 }
 .path li:last-child:after {
   color: red;
   content: "";
 }
 
-#sheetList, #sheetList menuitem {
-  font-size: 1em;
-  font-weight: normal;
-}
-
-.sheet_line input {
-  vertical-align: middle;
-}
-
-.sheet_line label {
-  cursor: pointer;
-}
-
-#header, #footer {
+#header,
+#footer {
   padding: 5px;
 }
 
 #header label {
   font-weight: bold;
 }
-#sheets {
-  -moz-margin-end: 10px;
-  margin-top: 5px;
-}
-h1 {
-  font-size: 13px;
-  padding: 2px 10px;
-  margin: 0;
-  background: -moz-linear-gradient(top, #CCC, #AAA);
-  border-radius: 3px;
-  text-shadow: #FFF 0 1px 0;
-  cursor: pointer;
-}
 
 .property-header {
   padding: 2px 5px;
   background: -moz-linear-gradient(top, #F8F8F8, #E8E8E8);
   color: #666;
 }
 
-.property-name, .property-value, .rule-count, .rule-unmatched {
+.property-name,
+.property-value,
+.rule-count,
+.rule-unmatched {
   cursor: pointer;
 }
 
 /* Take away these two :visited rules to get a core dumper     */
 /* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
-.link { color: #55A;  }
-.link:visited { color: #55A;  }
-a.link { text-decoration: none; cursor: pointer }
-a.link:visited { text-decoration: none; }
-.rule-count, .rule-unmatched {
-  float: right;
+.link,
+.unmatchedlink {
+  color: #55A;
+}
+.link:visited,
+.unmatchedlink:visited {
+  color: #55A;
+}
+a.link,
+a.unmatchedlink {
+  text-decoration: none;
+  cursor: pointer;
 }
-.rule-count[dir="rtl"], .rule-unmatched[dir="rtl"] {
-  float: left;
+a.link:visited,
+a.unmatchedlink:visited {
+  text-decoration: none;
 }
-.property-view .rule-count .expander,
-.property-view .rule-unmatched .expander {
+
+.rule-count,
+.rule-unmatched {
+  padding: 5px 0 0 15px;
+}
+.unmatched {
+  display: inline-block;
+}
+.expander {
   width: 8px;
   height: 8px;
-  -moz-margin-start: 5px;
   display: inline-block;
+  -moz-margin-end: 5px;
+  margin-bottom: 1px;
   background: url("chrome://browser/skin/devtools/arrows.png");
 }
 
+.unmatched-rule {
+  -moz-margin-start: 25px;
+  background-position: 24px 0;
+}
+
 .property-view .rule-count .expander,
 .property-view .rule-unmatched .expander {
   background-position: 24px 0;
 }
 .property-view[dir="rtl"] .rule-count .expander,
 .property-view[dir="rtl"] .rule-unmatched .expander {
   background-position: 16px 0;
 }
 .property-view[open] .rule-count .expander,
 .property-view[open] .rule-unmatched .expander {
   background-position: 8px 0;
 }
 
 .property-name {
+  display: inline-block;
   font-size: 12px;
   font-weight: bold;
-  -moz-padding-end: 4px;
   color: #000;
 }
-span.property-value {
-  -moz-padding-end: 5px;
+.property-value {
+  display: inline-block;
   font-size: 10px;
 }
-.group {
-  margin-top: 10px;
-}
-
-.group > h1 {
-  color: #333;
-  font-size: 11px;
-}
-.group .groupexpander {
-  width: 8px;
-  height: 8px;
-  margin-top: 2px;
-  background: url("chrome://browser/skin/devtools/arrows.png");
-}
-.group > div {
-  display: none;
-}
-.group[open] > div {
-  display: block;
-}
-.group .groupexpander {
-  background-position: 48px 0;
-  float: right;
-}
-.group[dir="rtl"] .groupexpander {
-  background-position: 40px 0;
-  float: left;
-}
-.group[open] .groupexpander {
-  background-position: 32px 0;
-  float: right;
-}
-.group[open][dir="rtl"] .groupexpander {
-  background-position: 32px 0;
-  float: left;
-}
-
-.group, #header, #footer {
-  background: #FFF;
-  border: 1px solid #E1E1E1;
-  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-  border-radius: 4px 4px 4px 4px;
-}
 
 .property-view > .rules {
   display: none;
 }
 .property-view[open] > .rules {
   display: table;
 }
 .rules {
+  -moz-margin-start: 32px;
   max-height: 350px;
   overflow-y: auto;
 }
-.rule-specificty, .rule-status {
+.rule-status {
   white-space: nowrap;
 }
 .rule-link {
   text-align: end;
+  -moz-padding-start: 10px;
 }
 
 /* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
 .rule-text {
   direction: ltr;
+  -moz-padding-start: 10px;
 }
 
 .resizerbox {
   background-color: window;
 }
 
-.bestmatch { color: black; }
-.matched { text-decoration: line-through; }
-.parentmatch { color: #666; }
-.unmatched { color: brown; }
+.bestmatch {
+  color: black;
+}
+.matched {
+  text-decoration: line-through;
+}
+.parentmatch {
+  color: #666;
+}
+.unmatched {
+  color: brown;
+}