Bug 1247729 - Move the box model panel into the computed styles panel r=jdescottes
authorGabriel Luong <gabriel.luong@gmail.com>
Tue, 19 Jul 2016 04:30:13 -0400
changeset 347651 48d51227912b8ec3600758d59a995521e2fbea1c
parent 347650 4fb8d384921edc4ee47d640c50aadb02296347e2
child 347652 65524ee7219ac01b54b89836b67d70ea9d818dbc
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1247729
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 1247729 - Move the box model panel into the computed styles panel r=jdescottes
devtools/client/inspector/computed/computed.js
devtools/client/inspector/computed/test/browser_computed_cycle_color.js
devtools/client/inspector/computed/test/browser_computed_keybindings_01.js
devtools/client/inspector/computed/test/browser_computed_matched-selectors-toggle.js
devtools/client/inspector/computed/test/head.js
devtools/client/inspector/inspector-panel.js
devtools/client/inspector/inspector.xul
devtools/client/inspector/layout/layout.js
devtools/client/inspector/layout/test/head.js
devtools/client/inspector/shared/test/browser_styleinspector_context-menu-copy-color_01.js
devtools/client/inspector/shared/test/browser_styleinspector_refresh_when_active.js
devtools/client/inspector/test/head.js
devtools/client/locales/en-US/layoutview.dtd
devtools/client/responsivedesign/test/head.js
devtools/client/shared/telemetry.js
devtools/client/shared/test/browser_telemetry_sidebar.js
devtools/client/themes/computed.css
devtools/client/themes/layout.css
devtools/client/themes/rules.css
devtools/client/themes/toolbars.css
toolkit/components/telemetry/Histograms.json
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -24,16 +24,18 @@ const {XPCOMUtils} = require("resource:/
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 
 loader.lazyRequireGetter(this, "overlays",
   "devtools/client/inspector/shared/style-inspector-overlays");
 loader.lazyRequireGetter(this, "StyleInspectorMenu",
   "devtools/client/inspector/shared/style-inspector-menu");
 loader.lazyRequireGetter(this, "KeyShortcuts",
   "devtools/client/shared/key-shortcuts", true);
+loader.lazyRequireGetter(this, "LayoutView",
+  "devtools/client/inspector/layout/layout", true);
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
                                   "resource://gre/modules/PluralForm.jsm");
 
 XPCOMUtils.defineLazyGetter(CssComputedView, "_strings", function () {
   return Services.strings.createBundle(
     "chrome://devtools-shared/locale/styleinspector.properties");
 });
@@ -164,17 +166,16 @@ function CssComputedView(inspector, docu
   this._onCopy = this._onCopy.bind(this);
   this._onFilterStyles = this._onFilterStyles.bind(this);
   this._onClearSearch = this._onClearSearch.bind(this);
   this._onIncludeBrowserStyles = this._onIncludeBrowserStyles.bind(this);
   this._onFilterTextboxContextMenu =
     this._onFilterTextboxContextMenu.bind(this);
 
   let doc = this.styleDocument;
-  this.root = doc.getElementById("root");
   this.element = doc.getElementById("propertyContainer");
   this.searchField = doc.getElementById("computedview-searchbox");
   this.searchClearButton = doc.getElementById("computedview-searchinput-clear");
   this.includeBrowserStylesCheckbox =
     doc.getElementById("browser-style-checkbox");
 
   this.shortcuts = new KeyShortcuts({ window: this.styleWindow });
   this._onShortcut = this._onShortcut.bind(this);
@@ -772,17 +773,16 @@ CssComputedView.prototype = {
     this.searchField.removeEventListener("input", this._onFilterStyles);
     this.searchField.removeEventListener("contextmenu",
                                          this._onFilterTextboxContextMenu);
     this.searchClearButton.removeEventListener("click", this._onClearSearch);
     this.includeBrowserStylesCheckbox.removeEventListener("input",
       this._onIncludeBrowserStyles);
 
     // Nodes used in templating
-    this.root = null;
     this.element = null;
     this.panel = null;
     this.searchField = null;
     this.searchClearButton = null;
     this.includeBrowserStylesCheckbox = null;
 
     // Property views
     for (let propView of this.propertyViews) {
@@ -1402,85 +1402,86 @@ SelectorView.prototype = {
     });
   }
 };
 
 function ComputedViewTool(inspector, window) {
   this.inspector = inspector;
   this.document = window.document;
 
-  this.view = new CssComputedView(this.inspector, this.document,
+  this.computedView = new CssComputedView(this.inspector, this.document,
     this.inspector.pageStyle);
+  this.layoutView = new LayoutView(this.inspector, this.document);
 
   this.onSelected = this.onSelected.bind(this);
   this.refresh = this.refresh.bind(this);
   this.onPanelSelected = this.onPanelSelected.bind(this);
   this.onMutations = this.onMutations.bind(this);
   this.onResized = this.onResized.bind(this);
 
   this.inspector.selection.on("detached", this.onSelected);
   this.inspector.selection.on("new-node-front", this.onSelected);
   this.inspector.selection.on("pseudoclass", this.refresh);
   this.inspector.sidebar.on("computedview-selected", this.onPanelSelected);
   this.inspector.pageStyle.on("stylesheet-updated", this.refresh);
   this.inspector.walker.on("mutations", this.onMutations);
   this.inspector.walker.on("resize", this.onResized);
 
-  this.view.selectElement(null);
+  this.computedView.selectElement(null);
 
   this.onSelected();
 }
 
 ComputedViewTool.prototype = {
   isSidebarActive: function () {
-    if (!this.view) {
+    if (!this.computedView) {
       return false;
     }
     return this.inspector.sidebar.getCurrentTabID() == "computedview";
   },
 
   onSelected: function (event) {
     // Ignore the event if the view has been destroyed, or if it's inactive.
     // But only if the current selection isn't null. If it's been set to null,
     // let the update go through as this is needed to empty the view on
     // navigation.
-    if (!this.view) {
+    if (!this.computedView) {
       return;
     }
 
     let isInactive = !this.isSidebarActive() &&
                      this.inspector.selection.nodeFront;
     if (isInactive) {
       return;
     }
 
-    this.view.setPageStyle(this.inspector.pageStyle);
+    this.computedView.setPageStyle(this.inspector.pageStyle);
 
     if (!this.inspector.selection.isConnected() ||
         !this.inspector.selection.isElementNode()) {
-      this.view.selectElement(null);
+      this.computedView.selectElement(null);
       return;
     }
 
     if (!event || event == "new-node-front") {
       let done = this.inspector.updating("computed-view");
-      this.view.selectElement(this.inspector.selection.nodeFront).then(() => {
+      this.computedView.selectElement(this.inspector.selection.nodeFront).then(() => {
         done();
       });
     }
   },
 
   refresh: function () {
     if (this.isSidebarActive()) {
-      this.view.refreshPanel();
+      this.computedView.refreshPanel();
     }
   },
 
   onPanelSelected: function () {
-    if (this.inspector.selection.nodeFront === this.view._viewedElement) {
+    if (this.inspector.selection.nodeFront === this.computedView._viewedElement) {
       this.refresh();
     } else {
       this.onSelected();
     }
   },
 
   /**
    * When markup mutations occur, if an attribute of the selected node changes,
@@ -1511,17 +1512,18 @@ ComputedViewTool.prototype = {
     this.inspector.selection.off("pseudoclass", this.refresh);
     this.inspector.selection.off("new-node-front", this.onSelected);
     this.inspector.selection.off("detached", this.onSelected);
     this.inspector.sidebar.off("computedview-selected", this.onPanelSelected);
     if (this.inspector.pageStyle) {
       this.inspector.pageStyle.off("stylesheet-updated", this.refresh);
     }
 
-    this.view.destroy();
+    this.computedView.destroy();
+    this.layoutView.destroy();
 
-    this.view = this.document = this.inspector = null;
+    this.computedView = this.layoutView = this.document = this.inspector = null;
   }
 };
 
 exports.CssComputedView = CssComputedView;
 exports.ComputedViewTool = ComputedViewTool;
 exports.PropertyView = PropertyView;
--- a/devtools/client/inspector/computed/test/browser_computed_cycle_color.js
+++ b/devtools/client/inspector/computed/test/browser_computed_cycle_color.js
@@ -54,16 +54,17 @@ function* checkColorCycling(container, v
   for (let test of tests) {
     yield checkSwatchShiftClick(container, win, test.value, test.comment);
   }
 }
 
 function* checkSwatchShiftClick(container, win, expectedValue, comment) {
   let swatch = container.querySelector(".computedview-colorswatch");
   let valueNode = container.querySelector(".computedview-color");
+  swatch.scrollIntoView();
 
   let onUnitChange = swatch.once("unit-change");
   EventUtils.synthesizeMouseAtCenter(swatch, {
     type: "mousedown",
     shiftKey: true
   }, win);
   yield onUnitChange;
   is(valueNode.textContent, expectedValue, comment);
--- a/devtools/client/inspector/computed/test/browser_computed_keybindings_01.js
+++ b/devtools/client/inspector/computed/test/browser_computed_keybindings_01.js
@@ -20,16 +20,17 @@ add_task(function* () {
   let {inspector, view} = yield openComputedView();
   yield selectNode(".matches", inspector);
 
   let propView = getFirstVisiblePropertyView(view);
   let rulesTable = propView.matchedSelectorsContainer;
   let matchedExpander = propView.element;
 
   info("Focusing the property");
+  matchedExpander.scrollIntoView();
   let onMatchedExpanderFocus = once(matchedExpander, "focus", true);
   EventUtils.synthesizeMouseAtCenter(matchedExpander, {}, view.styleWindow);
   yield onMatchedExpanderFocus;
 
   yield checkToggleKeyBinding(view.styleWindow, "VK_SPACE", rulesTable,
                               inspector);
   yield checkToggleKeyBinding(view.styleWindow, "VK_RETURN", rulesTable,
                               inspector);
--- a/devtools/client/inspector/computed/test/browser_computed_matched-selectors-toggle.js
+++ b/devtools/client/inspector/computed/test/browser_computed_matched-selectors-toggle.js
@@ -25,17 +25,17 @@ add_task(function* () {
   yield testExpandOnDblClick(view, inspector);
   yield testCollapseOnDblClick(view, inspector);
 });
 
 function* testExpandOnTwistyClick({styleDocument, styleWindow}, inspector) {
   info("Testing that a property expands on twisty click");
 
   info("Getting twisty element");
-  let twisty = styleDocument.querySelector(".expandable");
+  let twisty = styleDocument.querySelector("#propertyContainer .expandable");
   ok(twisty, "Twisty found");
 
   let onExpand = inspector.once("computed-view-property-expanded");
   info("Clicking on the twisty element");
   twisty.click();
 
   yield onExpand;
 
@@ -44,17 +44,17 @@ function* testExpandOnTwistyClick({style
   ok(div.childNodes.length > 0,
     "Matched selectors are expanded on twisty click");
 }
 
 function* testCollapseOnTwistyClick({styleDocument, styleWindow}, inspector) {
   info("Testing that a property collapses on twisty click");
 
   info("Getting twisty element");
-  let twisty = styleDocument.querySelector(".expandable");
+  let twisty = styleDocument.querySelector("#propertyContainer .expandable");
   ok(twisty, "Twisty found");
 
   let onCollapse = inspector.once("computed-view-property-collapsed");
   info("Clicking on the twisty element");
   twisty.click();
 
   yield onCollapse;
 
@@ -66,16 +66,18 @@ function* testCollapseOnTwistyClick({sty
 
 function* testExpandOnDblClick({styleDocument, styleWindow}, inspector) {
   info("Testing that a property expands on container dbl-click");
 
   info("Getting computed property container");
   let container = styleDocument.querySelector(".property-view");
   ok(container, "Container found");
 
+  container.scrollIntoView();
+
   let onExpand = inspector.once("computed-view-property-expanded");
   info("Dbl-clicking on the container");
   EventUtils.synthesizeMouseAtCenter(container, {clickCount: 2}, styleWindow);
 
   yield onExpand;
 
   // Expanded means the matchedselectors div is not empty
   let div = styleDocument.querySelector(".property-content .matchedselectors");
--- a/devtools/client/inspector/computed/test/head.js
+++ b/devtools/client/inspector/computed/test/head.js
@@ -127,17 +127,17 @@ function getComputedViewPropertyValue(vi
  *        The instance of the computed view panel
  * @param {Number} index
  *        The index of the property to be expanded
  * @return a promise that resolves when the property has been expanded, or
  * rejects if the property was not found
  */
 function expandComputedViewPropertyByIndex(view, index) {
   info("Expanding property " + index + " in the computed view");
-  let expandos = view.styleDocument.querySelectorAll(".expandable");
+  let expandos = view.styleDocument.querySelectorAll("#propertyContainer .expandable");
   if (!expandos.length || !expandos[index]) {
     return promise.reject();
   }
 
   let onExpand = view.inspector.once("computed-view-property-expanded");
   expandos[index].click();
   return onExpand;
 }
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -26,17 +26,16 @@ const MenuItem = require("devtools/clien
 
 loader.lazyRequireGetter(this, "CSS", "CSS");
 
 loader.lazyRequireGetter(this, "CommandUtils", "devtools/client/shared/developer-toolbar", true);
 loader.lazyRequireGetter(this, "ComputedViewTool", "devtools/client/inspector/computed/computed", true);
 loader.lazyRequireGetter(this, "FontInspector", "devtools/client/inspector/fonts/fonts", true);
 loader.lazyRequireGetter(this, "HTMLBreadcrumbs", "devtools/client/inspector/breadcrumbs", true);
 loader.lazyRequireGetter(this, "InspectorSearch", "devtools/client/inspector/inspector-search", true);
-loader.lazyRequireGetter(this, "LayoutView", "devtools/client/inspector/layout/layout", true);
 loader.lazyRequireGetter(this, "MarkupView", "devtools/client/inspector/markup/markup", true);
 loader.lazyRequireGetter(this, "RuleViewTool", "devtools/client/inspector/rules/rules", true);
 loader.lazyRequireGetter(this, "ToolSidebar", "devtools/client/inspector/toolsidebar", true);
 loader.lazyRequireGetter(this, "ViewHelpers", "devtools/client/shared/widgets/view-helpers", true);
 
 loader.lazyGetter(this, "strings", () => {
   return Services.strings.createBundle("chrome://devtools/locale/inspector.properties");
 });
@@ -418,30 +417,24 @@ InspectorPanel.prototype = {
       strings.GetStringFromName("inspector.sidebar.ruleViewTitle"),
       defaultTab == "ruleview");
 
     this.sidebar.addExistingTab(
       "computedview",
       strings.GetStringFromName("inspector.sidebar.computedViewTitle"),
       defaultTab == "computedview");
 
-    this.sidebar.addExistingTab(
-      "layoutview",
-      strings.GetStringFromName("inspector.sidebar.layoutViewTitle"),
-      defaultTab == "layoutview");
-
     this._setDefaultSidebar = (event, toolId) => {
       Services.prefs.setCharPref("devtools.inspector.activeSidebar", toolId);
     };
 
     this.sidebar.on("select", this._setDefaultSidebar);
 
     this.ruleview = new RuleViewTool(this, this.panelWin);
     this.computedview = new ComputedViewTool(this, this.panelWin);
-    this.layoutview = new LayoutView(this, this.panelWin);
 
     if (this.target.form.animationsActor) {
       this.sidebar.addFrameTab(
         "animationinspector",
         strings.GetStringFromName("inspector.sidebar.animationInspectorTitle"),
         "chrome://devtools/content/animationinspector/animation-inspector.xhtml",
         defaultTab == "animationinspector");
     }
@@ -747,20 +740,16 @@ InspectorPanel.prototype = {
     if (this.computedview) {
       this.computedview.destroy();
     }
 
     if (this.fontInspector) {
       this.fontInspector.destroy();
     }
 
-    if (this.layoutview) {
-      this.layoutview.destroy();
-    }
-
     let cssPropertiesDestroyer = this._cssPropertiesLoaded.then(({front}) => {
       if (front) {
         front.destroy();
       }
     });
 
     this.sidebar.off("select", this._setDefaultSidebar);
     let sidebarDestroyer = this.sidebar.destroy();
--- a/devtools/client/inspector/inspector.xul
+++ b/devtools/client/inspector/inspector.xul
@@ -102,69 +102,74 @@
           </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">
-        </html:div>
-
-        <html:div id="computedview-no-results" hidden="">
-          &noPropertiesFound;
-        </html:div>
-      </html:div>
+        <html:div id="computedview-container">
+          <html:div id="layout-wrapper" class="theme-separator" 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>
 
-      <html:div id="sidebar-panel-layoutview" class="devtools-monospace theme-sidebar inspector-tabpanel">
-        <html:div id="layout-wrapper">
-          <html:div id="layout-container">
-            <html:p id="layout-header">
-              <html:span id="layout-element-size"></html:span>
-              <html:section id="layout-position-group">
-                <html:button class="devtools-button" id="layout-geometry-editor" title="&geometry.button.tooltip;"></html:button>
-                <html:span id="layout-element-position"></html:span>
-              </html:section>
-            </html:p>
-
-            <html:div id="layout-main">
-              <html:span class="layout-legend" data-box="margin" title="&margin.tooltip;">&margin.tooltip;</html:span>
-              <html:div id="layout-margins" data-box="margin" title="&margin.tooltip;">
-                <html:span class="layout-legend" data-box="border" title="&border.tooltip;">&border.tooltip;</html:span>
-                <html:div id="layout-borders" data-box="border" title="&border.tooltip;">
-                  <html:span class="layout-legend" data-box="padding" title="&padding.tooltip;">&padding.tooltip;</html:span>
-                  <html:div id="layout-padding" data-box="padding" title="&padding.tooltip;">
-                    <html:div id="layout-content" data-box="content" title="&content.tooltip;">
+            <html:div id="layout-container">
+              <html:div id="layout-main">
+                <html:span class="layout-legend" data-box="margin" title="&margin.tooltip;">&margin.tooltip;</html:span>
+                <html:div id="layout-margins" data-box="margin" title="&margin.tooltip;">
+                  <html:span class="layout-legend" data-box="border" title="&border.tooltip;">&border.tooltip;</html:span>
+                  <html:div id="layout-borders" data-box="border" title="&border.tooltip;">
+                    <html:span class="layout-legend" data-box="padding" title="&padding.tooltip;">&padding.tooltip;</html:span>
+                    <html:div id="layout-padding" data-box="padding" title="&padding.tooltip;">
+                      <html:div id="layout-content" data-box="content" title="&content.tooltip;">
+                      </html:div>
                     </html:div>
                   </html:div>
                 </html:div>
+
+                <html:p class="layout-margin layout-top"><html:span data-box="margin" class="layout-editable" title="margin-top"></html:span></html:p>
+                <html:p class="layout-margin layout-right"><html:span data-box="margin" class="layout-editable" title="margin-right"></html:span></html:p>
+                <html:p class="layout-margin layout-bottom"><html:span data-box="margin" class="layout-editable" title="margin-bottom"></html:span></html:p>
+                <html:p class="layout-margin layout-left"><html:span data-box="margin" class="layout-editable" title="margin-left"></html:span></html:p>
+
+                <html:p class="layout-border layout-top"><html:span data-box="border" class="layout-editable" title="border-top"></html:span></html:p>
+                <html:p class="layout-border layout-right"><html:span data-box="border" class="layout-editable" title="border-right"></html:span></html:p>
+                <html:p class="layout-border layout-bottom"><html:span data-box="border" class="layout-editable" title="border-bottom"></html:span></html:p>
+                <html:p class="layout-border layout-left"><html:span data-box="border" class="layout-editable" title="border-left"></html:span></html:p>
+
+                <html:p class="layout-padding layout-top"><html:span data-box="padding" class="layout-editable" title="padding-top"></html:span></html:p>
+                <html:p class="layout-padding layout-right"><html:span data-box="padding" class="layout-editable" title="padding-right"></html:span></html:p>
+                <html:p class="layout-padding layout-bottom"><html:span data-box="padding" class="layout-editable" title="padding-bottom"></html:span></html:p>
+                <html:p class="layout-padding layout-left"><html:span data-box="padding" class="layout-editable" title="padding-left"></html:span></html:p>
+
+                <html:p class="layout-size"><html:span data-box="content" title="&content.tooltip;"></html:span></html:p>
               </html:div>
 
-              <html:p class="layout-border layout-top"><html:span data-box="border" class="layout-editable" title="border-top"></html:span></html:p>
-              <html:p class="layout-border layout-right"><html:span data-box="border" class="layout-editable" title="border-right"></html:span></html:p>
-              <html:p class="layout-border layout-bottom"><html:span data-box="border" class="layout-editable" title="border-bottom"></html:span></html:p>
-              <html:p class="layout-border layout-left"><html:span data-box="border" class="layout-editable" title="border-left"></html:span></html:p>
-
-              <html:p class="layout-margin layout-top"><html:span data-box="margin" class="layout-editable" title="margin-top"></html:span></html:p>
-              <html:p class="layout-margin layout-right"><html:span data-box="margin" class="layout-editable" title="margin-right"></html:span></html:p>
-              <html:p class="layout-margin layout-bottom"><html:span data-box="margin" class="layout-editable" title="margin-bottom"></html:span></html:p>
-              <html:p class="layout-margin layout-left"><html:span data-box="margin" class="layout-editable" title="margin-left"></html:span></html:p>
+              <html:div id="layout-info">
+                <html:span id="layout-element-size"></html:span>
+                <html:section id="layout-position-group">
+                  <html:span id="layout-element-position"></html:span>
+                </html:section>
+              </html:div>
 
-              <html:p class="layout-padding layout-top"><html:span data-box="padding" class="layout-editable" title="padding-top"></html:span></html:p>
-              <html:p class="layout-padding layout-right"><html:span data-box="padding" class="layout-editable" title="padding-right"></html:span></html:p>
-              <html:p class="layout-padding layout-bottom"><html:span data-box="padding" class="layout-editable" title="padding-bottom"></html:span></html:p>
-              <html:p class="layout-padding layout-left"><html:span data-box="padding" class="layout-editable" title="padding-left"></html:span></html:p>
+              <html:div style="display: none">
+                <html:p id="layout-dummy"></html:p>
+              </html:div>
+            </html:div>
+          </html:div>
 
-              <html:p class="layout-size"><html:span data-box="content" title="&content.tooltip;"></html:span></html:p>
-            </html:div>
+          <html:div id="propertyContainer" class="theme-separator" tabindex="0">
+          </html:div>
 
-            <html:div style="display: none">
-              <html:p id="layout-dummy"></html:p>
-            </html:div>
+          <html:div id="computedview-no-results" hidden="">
+            &noPropertiesFound;
           </html:div>
         </html:div>
       </html:div>
 
       <html:div id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel">
         <html:div class="devtools-toolbar">
           <html:div class="devtools-searchbox">
             <html:input id="font-preview-text-input"
--- a/devtools/client/inspector/layout/layout.js
+++ b/devtools/client/inspector/layout/layout.js
@@ -63,17 +63,17 @@ EditingSession.prototype = {
    * no style rules affect the property.
    *
    * @param property  The name of the property as a string
    */
   getProperty: function (property) {
     // Create a hidden element for getPropertyFromRule to use
     let div = this._doc.createElement("div");
     div.setAttribute("style", "display: none");
-    this._doc.getElementById("sidebar-panel-layoutview").appendChild(div);
+    this._doc.getElementById("sidebar-panel-computedview").appendChild(div);
     this._element = this._doc.createElement("p");
     div.appendChild(this._element);
 
     // As the rules are in order of priority we can just iterate until we find
     // the first that defines a value for the property and return that.
     for (let rule of this._rules) {
       let value = this.getPropertyFromRule(rule, property);
       if (value !== "") {
@@ -178,43 +178,52 @@ EditingSession.prototype = {
     this._doc = null;
     this._rules = null;
     this._modifications.clear();
   }
 };
 
 /**
  * The layout-view panel
- * @param {InspectorPanel} inspector An instance of the inspector-panel
- * currently loaded in the toolbox
- * @param {Window} win The window containing the panel
+ * @param {InspectorPanel} inspector
+ *        An instance of the inspector-panel currently loaded in the toolbox
+ * @param {Document} document
+ *        The document that will contain the layout view.
  */
-function LayoutView(inspector, win) {
+function LayoutView(inspector, document) {
   this.inspector = inspector;
-  this.doc = win.document;
+  this.doc = document;
+  this.wrapper = this.doc.getElementById("layout-wrapper");
+  this.container = this.doc.getElementById("layout-container");
+  this.expander = this.doc.getElementById("layout-expander");
   this.sizeLabel = this.doc.querySelector(".layout-size > span");
   this.sizeHeadingLabel = this.doc.getElementById("layout-element-size");
   this._geometryEditorHighlighter = null;
 
   this.init();
 }
 
 LayoutView.prototype = {
   init: function () {
     this.update = this.update.bind(this);
 
     this.onNewSelection = this.onNewSelection.bind(this);
     this.inspector.selection.on("new-node-front", this.onNewSelection);
 
     this.onNewNode = this.onNewNode.bind(this);
-    this.inspector.sidebar.on("layoutview-selected", this.onNewNode);
+    this.inspector.sidebar.on("computedview-selected", this.onNewNode);
 
     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.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.
@@ -308,17 +317,16 @@ LayoutView.prototype = {
     // Mark document as RTL or LTR:
     let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
                     .getService(Ci.nsIXULChromeRegistry);
     let dir = chromeReg.isLocaleRTL("global");
     let container = this.doc.getElementById("layout-container");
     container.setAttribute("dir", dir ? "rtl" : "ltr");
 
     let nodeGeometry = this.doc.getElementById("layout-geometry-editor");
-
     this.onGeometryButtonClick = this.onGeometryButtonClick.bind(this);
     nodeGeometry.addEventListener("click", this.onGeometryButtonClick);
   },
 
   initBoxModelHighlighter: function () {
     let highlightElts = this.doc.querySelectorAll("#layout-container *[title]");
     this.onHighlightMouseOver = this.onHighlightMouseOver.bind(this);
     this.onHighlightMouseOut = this.onHighlightMouseOut.bind(this);
@@ -410,17 +418,17 @@ LayoutView.prototype = {
   },
 
   /**
    * Is the layoutview visible in the sidebar.
    * @return {Boolean}
    */
   isViewVisible: function () {
     return this.inspector &&
-           this.inspector.sidebar.getCurrentTabID() == "layoutview";
+           this.inspector.sidebar.getCurrentTabID() == "computedview";
   },
 
   /**
    * Is the layoutview visible in the sidebar and is the current node valid to
    * be displayed in the view.
    * @return {Boolean}
    */
   isViewVisibleAndNodeValid: function () {
@@ -435,55 +443,62 @@ LayoutView.prototype = {
   destroy: function () {
     let highlightElts = this.doc.querySelectorAll("#layout-container *[title]");
 
     for (let element of highlightElts) {
       element.removeEventListener("mouseover", this.onHighlightMouseOver, true);
       element.removeEventListener("mouseout", this.onHighlightMouseOut, true);
     }
 
+    this.expander.removeEventListener("click", this.onToggleExpander);
+    let header = this.doc.getElementById("layout-header");
+    header.removeEventListener("dblclick", this.onToggleExpander);
+
     let nodeGeometry = this.doc.getElementById("layout-geometry-editor");
     nodeGeometry.removeEventListener("click", this.onGeometryButtonClick);
 
     this.inspector.off("picker-started", this.onPickerStarted);
 
     // Inspector Panel will destroy `markup` object on "will-navigate" event,
     // therefore we have to check if it's still available in case LayoutView
     // is destroyed immediately after.
     if (this.inspector.markup) {
       this.inspector.markup.off("leave", this.onMarkupViewLeave);
       this.inspector.markup.off("node-hover", this.onMarkupViewNodeHover);
     }
 
-    this.inspector.sidebar.off("layoutview-selected", this.onNewNode);
+    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.sizeHeadingLabel = null;
-    this.sizeLabel = null;
     this.inspector = null;
     this.doc = null;
+    this.wrapper = null;
+    this.container = null;
+    this.expander = null;
+    this.sizeLabel = null;
+    this.sizeHeadingLabel = null;
 
     if (this.reflowFront) {
       this.untrackReflows();
       this.reflowFront.destroy();
       this.reflowFront = null;
     }
   },
 
   onSidebarSelect: function (e, sidebar) {
-    this.setActive(sidebar === "layoutview");
+    this.setActive(sidebar === "computedview");
   },
 
   /**
    * Selection 'new-node-front' event handler.
    */
   onNewSelection: function () {
-    let done = this.inspector.updating("layoutview");
+    let done = this.inspector.updating("computed-view");
     this.onNewNode()
       .then(() => this.hideGeometryEditor())
       .then(done, (err) => {
         console.error(err);
         done();
       }).catch(console.error);
   },
 
@@ -521,16 +536,28 @@ LayoutView.prototype = {
       this.showGeometryEditor();
     }
   },
 
   onPickerStarted: function () {
     this.hideGeometryEditor();
   },
 
+  onToggleExpander: function () {
+    let isOpen = this.expander.hasAttribute("open");
+
+    if (isOpen) {
+      this.container.hidden = true;
+      this.expander.removeAttribute("open");
+    } else {
+      this.container.hidden = false;
+      this.expander.setAttribute("open", "");
+    }
+  },
+
   onMarkupViewLeave: function () {
     this.showGeometryEditor(true);
   },
 
   onMarkupViewNodeHover: function () {
     this.hideGeometryEditor(false);
   },
 
@@ -545,34 +572,33 @@ LayoutView.prototype = {
    * @param {Boolean} isActive
    */
   setActive: function (isActive) {
     if (isActive === this.isActive) {
       return;
     }
     this.isActive = isActive;
 
-    let panel = this.doc.getElementById("sidebar-panel-layoutview");
-    panel.classList.toggle("inactive", !isActive);
-
     if (isActive) {
       this.trackReflows();
     } else {
       this.untrackReflows();
     }
   },
 
   /**
    * Compute the dimensions of the node and update the values in
-   * the layoutview/view.xhtml document.
+   * the inspector.xul document.
    * @return a promise that will be resolved when complete.
    */
   update: function () {
     let lastRequest = Task.spawn((function* () {
       if (!this.isViewVisibleAndNodeValid()) {
+        this.wrapper.hidden = true;
+        this.inspector.emit("layoutview-updated");
         return null;
       }
 
       let node = this.inspector.selection.nodeFront;
       let layout = yield this.inspector.pageStyle.getLayout(node, {
         autoMargins: this.isActive
       });
       let styleEntries = yield this.inspector.pageStyle.getApplied(node, {});
@@ -588,22 +614,16 @@ LayoutView.prototype = {
       let width = layout.width;
       let height = layout.height;
       let newLabel = SHARED_L10N.getFormatStr("dimensions", width, height);
 
       if (this.sizeHeadingLabel.textContent != newLabel) {
         this.sizeHeadingLabel.textContent = newLabel;
       }
 
-      // If the view isn't active, no need to do anything more.
-      if (!this.isActive) {
-        this.inspector.emit("layoutview-updated");
-        return null;
-      }
-
       for (let i in this.map) {
         let property = this.map[i].property;
         if (!(property in layout)) {
           // Depending on the actor version, some properties
           // might be missing.
           continue;
         }
         let parsedValue = parseFloat(layout[property]);
@@ -651,18 +671,20 @@ LayoutView.prototype = {
 
       let newValue = width + "\u00D7" + height;
       if (this.sizeLabel.textContent != newValue) {
         this.sizeLabel.textContent = newValue;
       }
 
       this.elementRules = styleEntries.map(e => e.rule);
 
+      this.wrapper.hidden = false;
+
       this.inspector.emit("layoutview-updated");
-      return undefined;
+      return null;
     }).bind(this)).catch(console.error);
 
     this._lastRequest = lastRequest;
     return this._lastRequest;
   },
 
   /**
    * Update the text in the tooltip shown when hovering over a value to provide
--- a/devtools/client/inspector/layout/test/head.js
+++ b/devtools/client/inspector/layout/test/head.js
@@ -50,33 +50,33 @@ function selectAndHighlightNode(nodeOrSe
 
 /**
  * Open the toolbox, with the inspector tool visible, and the layout-view
  * sidebar tab selected.
  * @return a promise that resolves when the inspector is ready and the layout
  * view is visible and ready
  */
 function openLayoutView() {
-  return openInspectorSidebarTab("layoutview").then(data => {
+  return openInspectorSidebarTab("computedview").then(data => {
     // The actual highligher show/hide methods are mocked in layoutview tests.
     // The highlighter is tested in devtools/inspector/test.
     function mockHighlighter({highlighter}) {
       highlighter.showBoxModel = function () {
         return promise.resolve();
       };
       highlighter.hideBoxModel = function () {
         return promise.resolve();
       };
     }
     mockHighlighter(data.toolbox);
 
     return {
       toolbox: data.toolbox,
       inspector: data.inspector,
-      view: data.inspector.layoutview,
+      view: data.inspector.computedview.layoutView,
       testActor: data.testActor
     };
   });
 }
 
 /**
  * Wait for the layoutview-updated event.
  * @return a promise
--- a/devtools/client/inspector/shared/test/browser_styleinspector_context-menu-copy-color_01.js
+++ b/devtools/client/inspector/shared/test/browser_styleinspector_context-menu-copy-color_01.js
@@ -19,17 +19,17 @@ add_task(function* () {
   yield testView("ruleview", inspector);
   yield testView("computedview", inspector);
 });
 
 function* testView(viewId, inspector) {
   info("Testing " + viewId);
 
   yield inspector.sidebar.select(viewId);
-  let view = inspector[viewId].view;
+  let view = inspector[viewId].view || inspector[viewId].computedView;
   yield selectNode("div", inspector);
 
   testIsColorValueNode(view);
   testIsColorPopupOnAllNodes(view);
   yield clearCurrentNodeSelection(inspector);
 }
 
 /**
--- a/devtools/client/inspector/shared/test/browser_styleinspector_refresh_when_active.js
+++ b/devtools/client/inspector/shared/test/browser_styleinspector_refresh_when_active.js
@@ -15,17 +15,17 @@ add_task(function* () {
   yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
   let {inspector, view} = yield openRuleView();
 
   yield selectNode("#one", inspector);
 
   is(getRuleViewPropertyValue(view, "element", "color"), "red",
     "The rule-view shows the properties for test node one");
 
-  let cView = inspector.computedview.view;
+  let cView = inspector.computedview.computedView;
   let prop = getComputedViewProperty(cView, "color");
   ok(!prop, "The computed-view doesn't show the properties for test node one");
 
   info("Switching to the computed-view");
   let onComputedViewReady = inspector.once("computed-view-refreshed");
   selectComputedView(inspector);
   yield onComputedViewReady;
 
--- a/devtools/client/inspector/test/head.js
+++ b/devtools/client/inspector/test/head.js
@@ -292,17 +292,17 @@ function openRuleView() {
  * view is visible and ready
  */
 function openComputedView() {
   return openInspectorSidebarTab("computedview").then(data => {
     return {
       toolbox: data.toolbox,
       inspector: data.inspector,
       testActor: data.testActor,
-      view: data.inspector.computedview.view
+      view: data.inspector.computedview.computedView
     };
   });
 }
 
 /**
  * Select the rule view sidebar tab on an already opened inspector panel.
  *
  * @param {InspectorPanel} inspector
@@ -318,17 +318,17 @@ function selectRuleView(inspector) {
  * Select the computed view sidebar tab on an already opened inspector panel.
  *
  * @param {InspectorPanel} inspector
  *        The opened inspector panel
  * @return {CssComputedView} the computed view
  */
 function selectComputedView(inspector) {
   inspector.sidebar.select("computedview");
-  return inspector.computedview.view;
+  return inspector.computedview.computedView;
 }
 
 /**
  * Get the NodeFront for a node that matches a given css selector, via the
  * protocol.
  * @param {String|NodeFront} selector
  * @param {InspectorPanel} inspector The instance of InspectorPanel currently
  * loaded in the toolbox
--- a/devtools/client/locales/en-US/layoutview.dtd
+++ b/devtools/client/locales/en-US/layoutview.dtd
@@ -11,16 +11,17 @@
   - You want to make that choice consistent across the developer tools.
   - A good criteria is the language in which you'd find the best
   - documentation on web development on the web. -->
 
 <!-- LOCALIZATION NOTE (*.tooltip): These tooltips are not regular tooltips.
   -  The text appears on the bottom right corner of the layout view when
   -  the corresponding box is hovered. -->
 
+<!ENTITY layoutViewTitle          "Box Model">
 <!ENTITY margin.tooltip           "margin">
 <!ENTITY border.tooltip           "border">
 <!ENTITY padding.tooltip          "padding">
 <!ENTITY content.tooltip          "content">
 
 <!-- LOCALIZATION NOTE: This label is displayed as a tooltip that appears when
   -  hovering over the button that allows users to edit the position of an
   -  element in the page. -->
--- a/devtools/client/responsivedesign/test/head.js
+++ b/devtools/client/responsivedesign/test/head.js
@@ -142,17 +142,17 @@ var openInspectorSideBar = Task.async(fu
   let {toolbox, inspector} = yield openInspector();
 
   info("Selecting the " + id + " sidebar");
   inspector.sidebar.select(id);
 
   return {
     toolbox: toolbox,
     inspector: inspector,
-    view: inspector[id].view
+    view: inspector[id].view || inspector[id].computedView
   };
 });
 
 /**
  * Checks whether the inspector's sidebar corresponding to the given id already
  * exists
  * @param {InspectorPanel}
  * @param {String}
--- a/devtools/client/shared/telemetry.js
+++ b/devtools/client/shared/telemetry.js
@@ -92,21 +92,16 @@ Telemetry.prototype = {
       userHistogram: "DEVTOOLS_RULEVIEW_OPENED_PER_USER_FLAG",
       timerHistogram: "DEVTOOLS_RULEVIEW_TIME_ACTIVE_SECONDS"
     },
     computedview: {
       histogram: "DEVTOOLS_COMPUTEDVIEW_OPENED_COUNT",
       userHistogram: "DEVTOOLS_COMPUTEDVIEW_OPENED_PER_USER_FLAG",
       timerHistogram: "DEVTOOLS_COMPUTEDVIEW_TIME_ACTIVE_SECONDS"
     },
-    layoutview: {
-      histogram: "DEVTOOLS_LAYOUTVIEW_OPENED_COUNT",
-      userHistogram: "DEVTOOLS_LAYOUTVIEW_OPENED_PER_USER_FLAG",
-      timerHistogram: "DEVTOOLS_LAYOUTVIEW_TIME_ACTIVE_SECONDS"
-    },
     fontinspector: {
       histogram: "DEVTOOLS_FONTINSPECTOR_OPENED_COUNT",
       userHistogram: "DEVTOOLS_FONTINSPECTOR_OPENED_PER_USER_FLAG",
       timerHistogram: "DEVTOOLS_FONTINSPECTOR_TIME_ACTIVE_SECONDS"
     },
     animationinspector: {
       histogram: "DEVTOOLS_ANIMATIONINSPECTOR_OPENED_COUNT",
       userHistogram: "DEVTOOLS_ANIMATIONINSPECTOR_OPENED_PER_USER_FLAG",
--- a/devtools/client/shared/test/browser_telemetry_sidebar.js
+++ b/devtools/client/shared/test/browser_telemetry_sidebar.js
@@ -23,17 +23,17 @@ add_task(function* () {
   gBrowser.removeCurrentTab();
 });
 
 function* testSidebar(toolbox) {
   info("Testing sidebar");
 
   let inspector = toolbox.getCurrentPanel();
   let sidebarTools = ["ruleview", "computedview", "fontinspector",
-                      "layoutview", "animationinspector"];
+                      "animationinspector"];
 
   // Concatenate the array with itself so that we can open each tool twice.
   sidebarTools.push.apply(sidebarTools, sidebarTools);
 
   return new Promise(resolve => {
     // See TOOL_DELAY for why we need setTimeout here
     setTimeout(function selectSidebarTab() {
       let tool = sidebarTools.pop();
--- a/devtools/client/themes/computed.css
+++ b/devtools/client/themes/computed.css
@@ -27,21 +27,27 @@
   margin-right: 5px;
 
   /* Vertically center the 'Browser styles' checkbox in the
      Computed panel with its label. */
   display: flex;
   align-items: center;
 }
 
+#computedview-container {
+  overflow: auto;
+}
+
 #propertyContainer {
   -moz-user-select: text;
   overflow-y: auto;
   overflow-x: hidden;
   flex: auto;
+  border-top-width: 1px;
+  border-top-style: dotted;
 }
 
 .row-striped {
   background: var(--theme-body-background);
 }
 
 .property-view-hidden,
 .property-content-hidden {
@@ -54,17 +60,19 @@
   flex-wrap: wrap;
 }
 
 .property-name-container {
   width: 202px;
 }
 
 .property-value-container {
-  width: 168px;
+  display: flex;
+  flex: 1 1 168px;
+  overflow: hidden;
 }
 
 .property-name-container > *,
 .property-value-container > * {
   display: inline-block;
   vertical-align: middle;
 }
 
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -1,72 +1,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/ */
 
-#sidebar-panel-layoutview {
-  display: block;
-  overflow: auto;
-  height: 100%;
-}
-
-#layout-wrapper {
-  /* The sidebar-panel is not focusable, this wrapper will catch click events in
-     all the empty area around the layout-container */
-  height: 100%;
-}
-
 #layout-container {
   /* The view will grow bigger as the window gets resized, until 400px */
   max-width: 400px;
   margin: 0px auto;
   padding: 0;
-  /* "Contain" the absolutely positioned #layout-main element */
-  position: relative;
-}
-
-/* Header: contains the position and size of the element */
-
-#layout-header {
-  box-sizing: border-box;
-  width: 100%;
-  padding: 4px 14px;
-  display: -moz-box;
-  vertical-align: top;
-}
-
-#layout-header:dir(rtl) {
-  -moz-box-direction: reverse;
 }
 
-#layout-header > span {
-  display: -moz-box;
-}
+/* Header */
 
-#layout-element-size {
-  -moz-box-flex: 1;
+#layout-header,
+#layout-info {
+  display: flex;
+  align-items: center;
+  padding: 4px 17px;
 }
 
-#layout-element-size:dir(rtl) {
-  -moz-box-pack: end;
+#layout-geometry-editor {
+  visibility: hidden;
 }
 
-@media (max-height: 250px) {
-  #layout-header {
-    padding-top: 0;
-    padding-bottom: 0;
-    margin-top: 10px;
-    margin-bottom: 8px;
-  }
+#layout-geometry-editor::before {
+  background: url(images/geometry-editor.svg) no-repeat center center / 16px 16px;
 }
 
 /* Main: contains the box-model regions */
 
 #layout-main {
-  position: absolute;
+  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;
   width: calc(100% - 2 * 14px);
@@ -311,17 +279,17 @@
     left: 16px;
   }
 
   .layout-border.layout-right {
     right: 17px;
   }
 }
 
-/* Legend, displayed inside regions */
+/* Legend: displayed inside regions */
 
 .layout-legend {
   position: absolute;
   margin: 5px 6px;
   z-index: 1;
 }
 
 .layout-legend[data-box="margin"] {
@@ -351,28 +319,18 @@
 }
 
 /* Make sure the content size doesn't appear as editable like the other sizes */
 
 .layout-size > span {
   cursor: default;
 }
 
-/* Hide all values when the view is inactive */
+/* Layout info: contains the position and size of the element */
 
-#layout-container.inactive > #layout-header > #layout-element-position,
-#layout-container.inactive > #layout-header > #layout-element-size,
-#layout-container.inactive > #layout-main > p {
-   visibility: hidden;
+#layout-element-size {
+  flex: 1;
 }
 
 #layout-position-group {
   display: flex;
   align-items: center;
 }
-
-#layout-geometry-editor {
-  visibility: hidden;
-}
-
-#layout-geometry-editor::before {
-  background: url(images/geometry-editor.svg) no-repeat center center / 16px 16px;
-}
--- a/devtools/client/themes/rules.css
+++ b/devtools/client/themes/rules.css
@@ -40,17 +40,16 @@
 #ruleview-toolbar-container {
   display: flex;
   flex-direction: column;
   height: auto;
 }
 
 #ruleview-toolbar {
   display: flex;
-  height: 23px;
 }
 
 #ruleview-toolbar > .devtools-searchbox:first-child {
   padding-inline-start: 0px;
 }
 
 #ruleview-command-toolbar {
   display: flex;
--- a/devtools/client/themes/toolbars.css
+++ b/devtools/client/themes/toolbars.css
@@ -385,16 +385,17 @@
 .devtools-filterinput .textbox-input::-moz-placeholder {
   font-style: normal;
 }
 
 /* Searchbox is a div container element for a search input element */
 .devtools-searchbox {
   display: flex;
   flex: 1;
+  height: 23px;
   position: relative;
   padding: 0 3px;
 }
 
 /* The spacing is accomplished with a padding on the searchbox */
 .devtools-searchbox > .devtools-textinput,
 .devtools-searchbox > .devtools-searchinput,
 .devtools-searchbox > .devtools-filterinput {
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -6316,24 +6316,16 @@
   "DEVTOOLS_COMPUTEDVIEW_OPENED_COUNT": {
     "alert_emails": ["dev-developer-tools@lists.mozilla.org"],
     "expires_in_version": "never",
     "kind": "count",
     "bug_numbers": [1247985],
     "description": "Number of times the DevTools Computed View has been opened.",
     "releaseChannelCollection": "opt-out"
   },
-  "DEVTOOLS_LAYOUTVIEW_OPENED_COUNT": {
-    "alert_emails": ["dev-developer-tools@lists.mozilla.org"],
-    "expires_in_version": "never",
-    "kind": "count",
-    "bug_numbers": [1247985],
-    "description": "Number of times the DevTools Layout View has been opened.",
-    "releaseChannelCollection": "opt-out"
-  },
   "DEVTOOLS_FONTINSPECTOR_OPENED_COUNT": {
     "alert_emails": ["dev-developer-tools@lists.mozilla.org"],
     "expires_in_version": "never",
     "kind": "count",
     "bug_numbers": [1247985],
     "description": "Number of times the DevTools Font Inspector has been opened.",
     "releaseChannelCollection": "opt-out"
   },
@@ -6597,21 +6589,16 @@
     "kind": "flag",
     "description": "Number of users that have opened the DevTools Rule View."
   },
   "DEVTOOLS_COMPUTEDVIEW_OPENED_PER_USER_FLAG": {
     "expires_in_version": "never",
     "kind": "flag",
     "description": "Number of users that have opened the DevTools Computed View."
   },
-  "DEVTOOLS_LAYOUTVIEW_OPENED_PER_USER_FLAG": {
-    "expires_in_version": "never",
-    "kind": "flag",
-    "description": "Number of users that have opened the DevTools Layout View."
-  },
   "DEVTOOLS_FONTINSPECTOR_OPENED_PER_USER_FLAG": {
     "expires_in_version": "never",
     "kind": "flag",
     "description": "Number of users that have opened the DevTools Font Inspector."
   },
   "DEVTOOLS_ANIMATIONINSPECTOR_OPENED_PER_USER_FLAG": {
     "expires_in_version": "never",
     "kind": "flag",
@@ -6808,23 +6795,16 @@
   },
   "DEVTOOLS_COMPUTEDVIEW_TIME_ACTIVE_SECONDS": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 10000000,
     "n_buckets": 100,
     "description": "How long has the computed view been active (seconds)"
   },
-  "DEVTOOLS_LAYOUTVIEW_TIME_ACTIVE_SECONDS": {
-    "expires_in_version": "never",
-    "kind": "exponential",
-    "high": 10000000,
-    "n_buckets": 100,
-    "description": "How long has the layout view been active (seconds)"
-  },
   "DEVTOOLS_FONTINSPECTOR_TIME_ACTIVE_SECONDS": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 10000000,
     "n_buckets": 100,
     "description": "How long has the font inspector been active (seconds)"
   },
   "DEVTOOLS_ANIMATIONINSPECTOR_TIME_ACTIVE_SECONDS": {