☠☠ backed out by 34a128489d88 ☠ ☠ | |
author | Gabriel Luong <gabriel.luong@gmail.com> |
Wed, 13 Jul 2016 12:20:57 -0700 | |
changeset 304914 | a097b61f58102776941bd3fa0023092ac3f27a3f |
parent 304913 | 3e3b1eb03a908d02dac0bcb25c93eb8b734b5124 |
child 304915 | 105d425837e7032cf740863d00a36dc65d278a2b |
push id | 30446 |
push user | cbook@mozilla.com |
push date | Thu, 14 Jul 2016 09:44:34 +0000 |
treeherder | mozilla-central@cd9da00ffcc3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jdescottes |
bugs | 1247729 |
milestone | 50.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
|
--- 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("command", this.includeBrowserStylesChanged); // 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/framework/sidebar", 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"); }); @@ -415,17 +414,16 @@ InspectorPanel.prototype = { 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.addTab("animationinspector", "chrome://devtools/content/animationinspector/animation-inspector.xhtml", {selected: defaultTab == "animationinspector", insertBefore: "fontinspector"}); } @@ -689,20 +687,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 @@ -53,19 +53,16 @@ <tabbox id="inspector-sidebar" handleCtrlTab="false" class="devtools-sidebar-tabs" hidden="true"> <tabs> <tab id="sidebar-tab-ruleview" label="&ruleViewTitle;" crop="end"/> <tab id="sidebar-tab-computedview" label="&computedViewTitle;" crop="end"/> - <tab id="sidebar-tab-layoutview" - label="&layoutViewTitle;" - crop="end"/> <tab id="sidebar-tab-fontinspector" label="&fontInspectorTitle;" crop="end" hidden="true"/> </tabs> <tabpanels flex="1"> <tabpanel id="sidebar-panel-ruleview" class="devtools-monospace theme-sidebar inspector-tabpanel"> <html:div id="ruleview-toolbar-container" class="devtools-toolbar"> @@ -103,69 +100,74 @@ <html:button id="computedview-searchinput-clear" class="devtools-searchinput-clear"></html:button> </html:div> <checkbox id="browser-style-checkbox" class="includebrowserstyles" checked="false" label="&browserStylesLabel;"/> </html:div> - <html:div id="propertyContainer"> - </html:div> - - <html:div id="computedview-no-results" hidden=""> - &noPropertiesFound; - </html:div> - </tabpanel> + <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> - <tabpanel 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> </tabpanel> <tabpanel 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/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 @@ -19,20 +19,25 @@ } #browser-style-checkbox { /* Bug 1200073 - extra space before the browser styles checkbox so they aren't squished together in a small window. */ margin-inline-start: 5px; } +#computedview-container { + overflow: auto; +} + #propertyContainer { -moz-user-select: text; - overflow: auto; flex: auto; + border-top-width: 1px; + border-top-style: dotted; } .row-striped { background: var(--theme-body-background); } .property-view-hidden, .property-content-hidden { @@ -45,17 +50,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,71 +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; -} - -#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); @@ -310,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"] { @@ -350,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 @@ -43,17 +43,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 @@ -428,16 +428,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 @@ -6323,24 +6323,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" }, @@ -6604,21 +6596,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", @@ -6815,23 +6802,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": {