Bug 1289995 - Implement the basic design spec of the box model in the computed view r=bgrins
authorGabriel Luong <gabriel.luong@gmail.com>
Fri, 29 Jul 2016 15:05:54 -0400
changeset 307307 cb8fe696526cea65b8bbdcb6f62ae0a7c4d13145
parent 307306 fc777f42356960dad649f977452d22d05e0154d9
child 307308 fa9e9291bfe34c20797978d5d6a8f4168bf961b8
push id30945
push usercbook@mozilla.com
push dateSat, 30 Jul 2016 14:50:21 +0000
treeherderautoland@9e48f74f44c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1289995
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1289995 - Implement the basic design spec of the box model in the computed view r=bgrins - Moves the computed view toolbar back to the top - Removes the outline to the property name and values and the arrow beside the property values in the computed view - Use the compact form of the box model - Hide the box model when filtering the computed view
devtools/client/inspector/computed/computed.js
devtools/client/inspector/computed/test/browser_computed_search-filter.js
devtools/client/inspector/computed/test/browser_computed_search-filter_clear.js
devtools/client/inspector/inspector-panel.js
devtools/client/inspector/inspector.xul
devtools/client/inspector/layout/layout.js
devtools/client/themes/computed.css
devtools/client/themes/layout.css
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -550,18 +550,20 @@ CssComputedView.prototype = {
 
     let filterTimeout = (this.searchField.value.length > 0)
       ? FILTER_CHANGED_TIMEOUT : 0;
     this.searchClearButton.hidden = this.searchField.value.length === 0;
 
     this._filterChangedTimeout = setTimeout(() => {
       if (this.searchField.value.length > 0) {
         this.searchField.setAttribute("filled", true);
+        this.inspector.emit("computed-view-filtered", true);
       } else {
         this.searchField.removeAttribute("filled");
+        this.inspector.emit("computed-view-filtered", false);
       }
 
       this.refreshPanel();
       this._filterChangeTimeout = null;
     }, filterTimeout);
   },
 
   /**
--- a/devtools/client/inspector/computed/test/browser_computed_search-filter.js
+++ b/devtools/client/inspector/computed/test/browser_computed_search-filter.js
@@ -28,16 +28,18 @@ function* testToggleDefaultStyles(inspec
   let checkbox = computedView.includeBrowserStylesCheckbox;
   let onRefreshed = inspector.once("computed-view-refreshed");
   checkbox.click();
   yield onRefreshed;
 }
 
 function* testAddTextInFilter(inspector, computedView) {
   info("setting filter text to \"color\"");
+  let doc = computedView.styleDocument;
+  let layoutWrapper = doc.querySelector("#layout-wrapper");
   let searchField = computedView.searchField;
   let onRefreshed = inspector.once("computed-view-refreshed");
   let win = computedView.styleWindow;
 
   // First check to make sure that accel + F doesn't focus search if the
   // container isn't focused
   inspector.panelWin.focus();
   EventUtils.synthesizeKey("f", { accelKey: true });
@@ -46,16 +48,18 @@ function* testAddTextInFilter(inspector,
 
   computedView.element.focus();
   EventUtils.synthesizeKey("f", { accelKey: true });
   is(inspector.panelDoc.activeElement, searchField, "Search field is focused");
 
   synthesizeKeys("color", win);
   yield onRefreshed;
 
+  ok(layoutWrapper.hidden, "Layout view is hidden");
+
   info("check that the correct properties are visible");
 
   let propertyViews = computedView.propertyViews;
   propertyViews.forEach(propView => {
     let name = propView.name;
     is(propView.visible, name.indexOf("color") > -1,
       "span " + name + " property visibility check");
   });
--- a/devtools/client/inspector/computed/test/browser_computed_search-filter_clear.js
+++ b/devtools/client/inspector/computed/test/browser_computed_search-filter_clear.js
@@ -44,24 +44,28 @@ function* testAddTextInFilter(inspector,
       "span " + name + " property visibility check");
   });
 }
 
 function* testClearSearchFilter(inspector, computedView) {
   info("Clearing the search filter");
 
   let win = computedView.styleWindow;
+  let doc = computedView.styleDocument;
+  let layoutWrapper = doc.querySelector("#layout-wrapper");
   let propertyViews = computedView.propertyViews;
   let searchField = computedView.searchField;
   let searchClearButton = computedView.searchClearButton;
   let onRefreshed = inspector.once("computed-view-refreshed");
 
   EventUtils.synthesizeMouseAtCenter(searchClearButton, {}, win);
   yield onRefreshed;
 
+  ok(!layoutWrapper.hidden, "Layout view is displayed");
+
   info("Check that the correct properties are visible");
 
   ok(!searchField.value, "Search filter is cleared");
   propertyViews.forEach((propView) => {
     is(propView.visible, propView.hasMatchedSelectors,
       "span " + propView.name + " property visibility check");
   });
 }
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -74,16 +74,18 @@ loader.lazyGetter(this, "clipboardHelper
  *      Fired when the computed rules view updates to a new node
  * - computed-view-property-expanded
  *      Fired when a property is expanded in the computed rules view
  * - computed-view-property-collapsed
  *      Fired when a property is collapsed in the computed rules view
  * - computed-view-sourcelinks-updated
  *      Fired when the stylesheet source links have been updated (when switching
  *      to source-mapped files)
+ * - computed-view-filtered
+ *      Fired when the computed rules view is filtered
  * - rule-view-refreshed
  *      Fired when the rule view updates to a new node
  * - rule-view-sourcelinks-updated
  *      Fired when the stylesheet source links have been updated (when switching
  *      to source-mapped files)
  */
 function InspectorPanel(iframeWindow, toolbox) {
   this._toolbox = toolbox;
--- a/devtools/client/inspector/inspector.xul
+++ b/devtools/client/inspector/inspector.xul
@@ -92,16 +92,31 @@
 
         <html:div id="ruleview-container" class="ruleview">
           <html:div id="ruleview-container-focusable" tabindex="-1">
           </html:div>
         </html:div>
       </html:div>
 
       <html:div id="sidebar-panel-computedview" class="devtools-monospace theme-sidebar inspector-tabpanel">
+        <html:div id="computedview-toolbar" class="devtools-toolbar">
+          <html:div class="devtools-searchbox">
+            <html:input id="computedview-searchbox"
+                        class="devtools-filterinput devtools-rule-searchbox"
+                        type="search"
+                        placeholder="&filterStylesPlaceholder;"/>
+            <html:button id="computedview-searchinput-clear" class="devtools-searchinput-clear"></html:button>
+          </html:div>
+          <html:label id="browser-style-checkbox-label" for="browser-style-checkbox">
+            <html:input id="browser-style-checkbox"
+                        type="checkbox"
+                        class="includebrowserstyles"
+                        label="&browserStylesLabel;"/>&browserStylesLabel;</html:label>
+        </html:div>
+
         <html:div id="computedview-container">
           <html:div id="computedview-container-focusable" tabindex="-1">
             <html:div id="layout-wrapper" tabindex="0">
               <html:div id="layout-header">
                 <html:div id="layout-expander" class="expander theme-twisty expandable" open=""></html:div>
                 <html:span>&layoutViewTitle;</html:span>
                 <html:button class="devtools-button" id="layout-geometry-editor" title="&geometry.button.tooltip;"></html:button>
               </html:div>
@@ -146,31 +161,16 @@
                 </html:div>
 
                 <html:div style="display: none">
                   <html:p id="layout-dummy"></html:p>
                 </html:div>
               </html:div>
             </html:div>
 
-            <html:div id="computedview-toolbar" class="devtools-toolbar">
-              <html:div class="devtools-searchbox">
-                <html:input id="computedview-searchbox"
-                            class="devtools-filterinput devtools-rule-searchbox"
-                            type="search"
-                            placeholder="&filterStylesPlaceholder;"/>
-                <html:button id="computedview-searchinput-clear" class="devtools-searchinput-clear"></html:button>
-              </html:div>
-              <html:label id="browser-style-checkbox-label" for="browser-style-checkbox">
-                <html:input id="browser-style-checkbox"
-                            type="checkbox"
-                            class="includebrowserstyles"
-                            label="&browserStylesLabel;"/>&browserStylesLabel;</html:label>
-            </html:div>
-
             <html:div id="propertyContainer" class="theme-separator" tabindex="0">
             </html:div>
 
             <html:div id="computedview-no-results" hidden="">
               &noPropertiesFound;
             </html:div>
           </html:div>
         </html:div>
--- a/devtools/client/inspector/layout/layout.js
+++ b/devtools/client/inspector/layout/layout.js
@@ -216,16 +216,20 @@ LayoutView.prototype = {
     this.onSidebarSelect = this.onSidebarSelect.bind(this);
     this.inspector.sidebar.on("select", this.onSidebarSelect);
 
     this.onToggleExpander = this.onToggleExpander.bind(this);
     this.expander.addEventListener("click", this.onToggleExpander);
     let header = this.doc.getElementById("layout-header");
     header.addEventListener("dblclick", this.onToggleExpander);
 
+    this.onFilterComputedView = this.onFilterComputedView.bind(this);
+    this.inspector.on("computed-view-filtered",
+      this.onFilterComputedView);
+
     this.onPickerStarted = this.onPickerStarted.bind(this);
     this.onMarkupViewLeave = this.onMarkupViewLeave.bind(this);
     this.onMarkupViewNodeHover = this.onMarkupViewNodeHover.bind(this);
     this.onWillNavigate = this.onWillNavigate.bind(this);
 
     this.initBoxModelHighlighter();
 
     // Store for the different dimensions of the node.
@@ -466,16 +470,17 @@ LayoutView.prototype = {
       this.inspector.markup.off("leave", this.onMarkupViewLeave);
       this.inspector.markup.off("node-hover", this.onMarkupViewNodeHover);
     }
 
     this.inspector.sidebar.off("computedview-selected", this.onNewNode);
     this.inspector.selection.off("new-node-front", this.onNewSelection);
     this.inspector.sidebar.off("select", this.onSidebarSelect);
     this.inspector._target.off("will-navigate", this.onWillNavigate);
+    this.inspector.off("computed-view-filtered", this.onFilterComputedView);
 
     this.inspector = null;
     this.doc = null;
     this.wrapper = null;
     this.container = null;
     this.expander = null;
     this.sizeLabel = null;
     this.sizeHeadingLabel = null;
@@ -564,16 +569,26 @@ LayoutView.prototype = {
   },
 
   onWillNavigate: function () {
     this._geometryEditorHighlighter.release().catch(console.error);
     this._geometryEditorHighlighter = null;
   },
 
   /**
+   * Event handler that responds to the computed view being filtered
+   * @param {String} reason
+   * @param {Boolean} hidden
+   *        Whether or not to hide the layout wrapper
+   */
+  onFilterComputedView: function (reason, hidden) {
+    this.wrapper.hidden = hidden;
+  },
+
+  /**
    * Stop tracking reflows and hide all values when no node is selected or the
    * layout-view is hidden, otherwise track reflows and show values.
    * @param {Boolean} isActive
    */
   setActive: function (isActive) {
     if (isActive === this.isActive) {
       return;
     }
--- a/devtools/client/themes/computed.css
+++ b/devtools/client/themes/computed.css
@@ -84,38 +84,37 @@
   display: inline-block;
   vertical-align: middle;
 }
 
 .property-name {
   overflow-x: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
-  outline: 0;
+  outline: 0 !important;
 }
 
-.property-value, .other-property-value {
+.other-property-value {
   background-image: url(images/arrow-e.png);
   background-repeat: no-repeat;
   background-size: 5px 8px;
 }
 
 @media (min-resolution: 1.1dppx) {
-  .property-value, .other-property-value {
+  .other-property-value {
     background-image: url(images/arrow-e@2x.png);
   }
 }
 
 .property-value {
   overflow-x: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
-  background-position: 2px center;
   padding-left: 10px;
-  outline: 0;
+  outline: 0 !important;
 }
 
 .other-property-value {
   background-position: left center;
   padding-left: 8px;
 }
 
 .property-content {
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -37,59 +37,45 @@
 #layout-main {
   position: relative;
   box-sizing: border-box;
   /* The regions are semi-transparent, so the white background is partly
      visible */
   background-color: white;
   color: var(--theme-selection-color);
   /* Make sure there is some space between the window's edges and the regions */
-  margin: 0 14px 10px 14px;
+  margin: 0 14px 4px 14px;
   width: calc(100% - 2 * 14px);
 }
 
 .layout-margin,
 .layout-size {
   color: var(--theme-highlight-blue);
 }
 
 /* Regions are 3 nested elements with wide borders and outlines */
 
 #layout-content {
-  height: 25px;
+  height: 18px;
 }
 
 #layout-margins,
 #layout-borders,
 #layout-padding {
   border-color: hsla(210,100%,85%,0.2);
-  border-width: 25px;
+  border-width: 18px;
   border-style: solid;
   outline: dotted 1px hsl(210,100%,85%);
 }
 
 #layout-margins {
   /* This opacity applies to all of the regions, since they are nested */
   opacity: .8;
 }
 
-/* Respond to window size change by changing the size of the regions */
-
-@media (max-height: 250px) {
-  #layout-content {
-    height: 18px;
-  }
-
-  #layout-margins,
-  #layout-borders,
-  #layout-padding {
-    border-width: 18px;
-  }
-}
-
 /* Regions colors */
 
 #layout-margins {
   border-color: #edff64;
 }
 
 #layout-borders {
   border-color: #444444;
@@ -142,77 +128,77 @@
 
 .layout-top,
 .layout-bottom {
   width: calc(100% - 2px);
   text-align: center;
 }
 
 .layout-padding.layout-top {
-  top: 55px;
+  top: 37px;
 }
 
 .layout-padding.layout-bottom {
-  bottom: 57px;
+  bottom: 38px;
 }
 
 .layout-border.layout-top {
-  top: 30px;
+  top: 19px;
 }
 
 .layout-border.layout-bottom {
-  bottom: 31px;
+  bottom: 20px;
 }
 
 .layout-margin.layout-top {
-  top: 5px;
+  top: 1px;
 }
 
 .layout-margin.layout-bottom {
-  bottom: 6px;
+  bottom: 2px;
 }
 
 .layout-size,
 .layout-margin.layout-left,
 .layout-margin.layout-right,
 .layout-border.layout-left,
 .layout-border.layout-right,
 .layout-padding.layout-left,
 .layout-padding.layout-right {
   top: 22px;
-  line-height: 132px;
+  line-height: 80px;
 }
 
 .layout-size {
   width: calc(100% - 2px);
 }
 
 .layout-margin.layout-right,
 .layout-margin.layout-left,
 .layout-border.layout-left,
 .layout-border.layout-right,
 .layout-padding.layout-right,
 .layout-padding.layout-left {
-  width: 25px;
+  width: 21px;
 }
 
 .layout-padding.layout-left {
-  left: 52px;
+  left: 35px;
 }
 
 .layout-padding.layout-right {
-  right: 51px;
+  right: 35px;
 }
 
 .layout-border.layout-left {
-  left: 26px;
+  left: 16px;
 }
 
 .layout-border.layout-right {
-  right: 26px;
+  right: 17px;
 }
 
 .layout-margin.layout-right {
   right: 0;
 }
 
 .layout-margin.layout-left {
   left: 0;
@@ -221,98 +207,28 @@
 .layout-rotate.layout-left:not(.layout-editing) {
   transform: rotate(-90deg);
 }
 
 .layout-rotate.layout-right:not(.layout-editing) {
   transform: rotate(90deg);
 }
 
-/* Coordinates should be different when the window is small, because we make
-   the regions smaller then */
-
-@media (max-height: 250px) {
-  .layout-padding.layout-top {
-    top: 37px;
-  }
-
-  .layout-padding.layout-bottom {
-    bottom: 38px;
-  }
-
-  .layout-border.layout-top {
-    top: 19px;
-  }
-
-  .layout-border.layout-bottom {
-    bottom: 20px;
-  }
-
-  .layout-margin.layout-top {
-    top: 1px;
-  }
-
-  .layout-margin.layout-bottom {
-    bottom: 2px;
-  }
-
-  .layout-size,
-  .layout-margin.layout-left,
-  .layout-margin.layout-right,
-  .layout-border.layout-left,
-  .layout-border.layout-right,
-  .layout-padding.layout-left,
-  .layout-padding.layout-right {
-    line-height: 80px;
-  }
-
-  .layout-margin.layout-right,
-  .layout-margin.layout-left,
-  .layout-border.layout-left,
-  .layout-border.layout-right,
-  .layout-padding.layout-right,
-  .layout-padding.layout-left {
-    width: 21px;
-  }
-
-  .layout-padding.layout-left {
-    left: 35px;
-  }
-
-  .layout-padding.layout-right {
-    right: 35px;
-  }
-
-  .layout-border.layout-left {
-    left: 16px;
-  }
-
-  .layout-border.layout-right {
-    right: 17px;
-  }
-}
-
 /* Legend: displayed inside regions */
 
 .layout-legend {
   position: absolute;
-  margin: 5px 6px;
+  margin: 2px 6px;
   z-index: 1;
 }
 
 .layout-legend[data-box="margin"] {
   color: var(--theme-highlight-blue);
 }
 
-@media (max-height: 250px) {
-  .layout-legend {
-    margin: 2px 6px;
-  }
-}
-
 /* Editable fields */
 
 .layout-editable {
   border: 1px dashed transparent;
   -moz-user-select: text;
 }
 
 .layout-editable:hover {