Bug 672743 - Remove category view from style inspector; r=msucan
authorMike Ratcliffe <mratcliffe@mozilla.com>
Tue, 30 Aug 2011 13:40:29 -0300
changeset 77572 c6309c9aa79a70c0b92ca335cd8d4340c796d4e9
parent 77571 54685bf66136dc5e346e1e0873d2fc9afb4f85c0
child 77573 8d3407891a21e389c14cb16a7e7a5ef7666bf2dc
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmsucan
bugs672743
milestone9.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 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;
+}