Commit 830b2192 authored by Paul Irish's avatar Paul Irish Committed by Commit Bot

DevTools: Move Audits2 report selection from TreeOutline -> ComboBox


Bug: 745958
Change-Id: I87c0de5d5c7e9d5fc8b6fd38d95dec8013934db8
Reviewed-on: https://chromium-review.googlesource.com/576359
Commit-Queue: Paul Irish <paulirish@chromium.org>
Reviewed-by: default avatarAlexei Filippov <alph@chromium.org>
Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488136}
parent 1c955f05
...@@ -48,7 +48,6 @@ all_devtools_files = [ ...@@ -48,7 +48,6 @@ all_devtools_files = [
"front_end/audits2/Audits2Panel.js", "front_end/audits2/Audits2Panel.js",
"front_end/audits2/audits2Dialog.css", "front_end/audits2/audits2Dialog.css",
"front_end/audits2/audits2Panel.css", "front_end/audits2/audits2Panel.css",
"front_end/audits2/audits2Tree.css",
"front_end/audits2/lighthouse/renderer/dom.js", "front_end/audits2/lighthouse/renderer/dom.js",
"front_end/audits2/lighthouse/renderer/details-renderer.js", "front_end/audits2/lighthouse/renderer/details-renderer.js",
"front_end/audits2/lighthouse/renderer/category-renderer.js", "front_end/audits2/lighthouse/renderer/category-renderer.js",
......
## Adding new icons
1. Use Inkscape 0.48.4. Newer versions are incompatible because of DPI issues.
1. Choose an existing spritesheet, like `largeIcons.svg` to add the icon to
1. Open that file with Inkscape and import the new SVG into the document
1. Place in an open spot, and use guides to scale the icon to a good size, relative to other icons
1. Any straight lines should be snapped to the closest pixel value.
- Use the `Edit paths by nodes` tool (F2) to edit the path directly.
- Tweak the X, Y values at the top to be integers.
1. Generate pngs from the SVGs:
- `./scripts/convert_svg_images_to_png.py`
1. In `ui/Icon.js` add an entry in `UI.Icon.Descriptors`.
- Look at the spritesheet's axes to identify the correct grid position.
1. You may want to regenerate devtools resources:
- `ninja -C ~/chromium/src/out/Release/ devtools_frontend_resources`
This source diff could not be displayed because it is too large. You can view the blob instead.
{ {
"securityIcons.svg": "27676f7c1f1542659c7c49a8052259dc", "securityIcons.svg": "27676f7c1f1542659c7c49a8052259dc",
"largeIcons.svg": "486eeb024854b5dc7ae0a13e3d8e04bd", "largeIcons.svg": "23525deeadff5f16ca9e8af2a1176fd0",
"breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
"checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a",
"errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* @implements {SDK.SDKModelObserver<!SDK.ServiceWorkerManager>} * @implements {SDK.SDKModelObserver<!SDK.ServiceWorkerManager>}
* @unrestricted * @unrestricted
*/ */
Audits2.Audits2Panel = class extends UI.PanelWithSidebar { Audits2.Audits2Panel = class extends UI.Panel {
constructor() { constructor() {
super('audits2'); super('audits2');
this.registerRequiredCSS('audits2/audits2Panel.css'); this.registerRequiredCSS('audits2/audits2Panel.css');
...@@ -15,27 +15,26 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar { ...@@ -15,27 +15,26 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar {
this._protocolService = new Audits2.ProtocolService(); this._protocolService = new Audits2.ProtocolService();
this._protocolService.registerStatusCallback(msg => this._updateStatus(Common.UIString(msg))); this._protocolService.registerStatusCallback(msg => this._updateStatus(Common.UIString(msg)));
var toolbar = new UI.Toolbar('', this.panelSidebarElement()); var toolbar = new UI.Toolbar('', this.element);
var newButton = new UI.ToolbarButton(Common.UIString('New audit\u2026'), 'largeicon-add'); var newButton = new UI.ToolbarButton(Common.UIString('New audit\u2026'), 'largeicon-add');
toolbar.appendToolbarItem(newButton); toolbar.appendToolbarItem(newButton);
newButton.addEventListener(UI.ToolbarButton.Events.Click, this._showLauncherUI.bind(this)); newButton.addEventListener(UI.ToolbarButton.Events.Click, this._showLauncherUI.bind(this));
var deleteButton = new UI.ToolbarButton(Common.UIString('Delete audit'), 'largeicon-delete'); var downloadButton = new UI.ToolbarButton(Common.UIString('Download report'), 'largeicon-download');
toolbar.appendToolbarItem(deleteButton); toolbar.appendToolbarItem(downloadButton);
deleteButton.addEventListener(UI.ToolbarButton.Events.Click, this._deleteSelected.bind(this)); downloadButton.addEventListener(UI.ToolbarButton.Events.Click, this._downloadSelected.bind(this));
toolbar.appendSeparator(); toolbar.appendSeparator();
this._reportSelector = new Audits2.ReportSelector();
toolbar.appendToolbarItem(this._reportSelector.comboBox());
var clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largeicon-clear'); var clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largeicon-clear');
toolbar.appendToolbarItem(clearButton); toolbar.appendToolbarItem(clearButton);
clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearAll.bind(this)); clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearAll.bind(this));
this._treeOutline = new UI.TreeOutlineInShadow(); this._auditResultsElement = this.contentElement.createChild('div', 'audits2-results-container');
this._treeOutline.registerRequiredCSS('audits2/lighthouse/report-styles.css');
this._treeOutline.registerRequiredCSS('audits2/audits2Tree.css');
this.panelSidebarElement().appendChild(this._treeOutline.element);
this._dropTarget = new UI.DropTarget( this._dropTarget = new UI.DropTarget(
this.contentElement, [UI.DropTarget.Types.Files], Common.UIString('Drop audit file here'), this.contentElement, [UI.DropTarget.Types.Files], Common.UIString('Drop audit file here'),
this._handleDrop.bind(this)); this._handleDrop.bind(this));
...@@ -148,22 +147,20 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar { ...@@ -148,22 +147,20 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar {
} }
_clearAll() { _clearAll() {
this._treeOutline.removeChildren(); this._reportSelector.clearAll();
this._showLandingPage(); this._showLandingPage();
} }
_deleteSelected() { _downloadSelected() {
var selection = this._treeOutline.selectedTreeElement; this._reportSelector.downloadSelected();
if (selection)
selection._deleteItem();
} }
_showLandingPage() { _showLandingPage() {
if (this._treeOutline.rootElement().childCount()) if (this._reportSelector.comboBox().size())
return; return;
this.mainElement().removeChildren(); this._auditResultsElement.removeChildren();
var landingPage = this.mainElement().createChild('div', 'vbox audits2-landing-page'); var landingPage = this._auditResultsElement.createChild('div', 'vbox audits2-landing-page');
var landingCenter = landingPage.createChild('div', 'vbox audits2-landing-center'); var landingCenter = landingPage.createChild('div', 'vbox audits2-landing-center');
landingCenter.createChild('div', 'audits2-logo'); landingCenter.createChild('div', 'audits2-logo');
var text = landingCenter.createChild('div', 'audits2-landing-text'); var text = landingCenter.createChild('div', 'audits2-landing-text');
...@@ -220,7 +217,7 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar { ...@@ -220,7 +217,7 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar {
this._dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.SetExactWidthMaxHeight); this._dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.SetExactWidthMaxHeight);
this._dialog.setMaxContentSize(new UI.Size(500, 400)); this._dialog.setMaxContentSize(new UI.Size(500, 400));
this._dialog.show(this.mainElement()); this._dialog.show(this._auditResultsElement);
auditsViewElement.tabIndex = 0; auditsViewElement.tabIndex = 0;
auditsViewElement.focus(); auditsViewElement.focus();
} }
...@@ -385,11 +382,9 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar { ...@@ -385,11 +382,9 @@ Audits2.Audits2Panel = class extends UI.PanelWithSidebar {
this._updateStatus(Common.UIString('Auditing failed.')); this._updateStatus(Common.UIString('Auditing failed.'));
return; return;
} }
var treeElement = var optionElement =
new Audits2.Audits2Panel.TreeElement(lighthouseResult, this.mainElement(), this._showLandingPage.bind(this)); new Audits2.ReportSelector.Item(lighthouseResult, this._auditResultsElement, this._showLandingPage.bind(this));
this._treeOutline.appendChild(treeElement); this._reportSelector.prepend(optionElement);
treeElement._populate();
treeElement.select();
this._hideDialog(); this._hideDialog();
} }
...@@ -612,80 +607,105 @@ Audits2.ProtocolService = class extends Common.Object { ...@@ -612,80 +607,105 @@ Audits2.ProtocolService = class extends Common.Object {
} }
}; };
Audits2.Audits2Panel.TreeElement = class extends UI.TreeElement {
Audits2.ReportSelector = class {
constructor() {
this._comboBox = new UI.ToolbarComboBox(this._handleChange.bind(this), 'audits2-report');
this._comboBox.setMaxWidth(270);
this._comboBox.setMinWidth(200);
this._itemByOptionElement = new Map();
}
/**
* @param {!Event} event
*/
_handleChange(event) {
var item = this._selectedItem();
if (item)
item.select();
}
/**
* @return {!Audits2.ReportSelector.Item}
*/
_selectedItem() {
var option = this._comboBox.selectedOption();
return this._itemByOptionElement.get(option);
}
/**
* @return {!UI.ToolbarComboBox}
*/
comboBox() {
return this._comboBox;
}
/**
* @param {!Audits2.ReportSelector.Item} item
*/
prepend(item) {
var optionEl = item.optionElement();
var selectEl = this._comboBox.selectElement();
this._itemByOptionElement.set(optionEl, item);
selectEl.insertBefore(optionEl, selectEl.firstElementChild);
this._comboBox.select(optionEl);
item.select();
}
clearAll() {
for (var elem of this._comboBox.options())
this._itemByOptionElement.get(elem).delete();
}
downloadSelected() {
var item = this._selectedItem();
item.download();
}
};
Audits2.ReportSelector.Item = class {
/** /**
* @param {!ReportRenderer.ReportJSON} lighthouseResult * @param {!ReportRenderer.ReportJSON} lighthouseResult
* @param {!Element} resultsView * @param {!Element} resultsView
* @param {function()} showLandingCallback * @param {function()} showLandingCallback
*/ */
constructor(lighthouseResult, resultsView, showLandingCallback) { constructor(lighthouseResult, resultsView, showLandingCallback) {
super('', false);
this._lighthouseResult = lighthouseResult; this._lighthouseResult = lighthouseResult;
this._resultsView = resultsView; this._resultsView = resultsView;
this._showLandingCallback = showLandingCallback; this._showLandingCallback = showLandingCallback;
/** @type {?Element} */ /** @type {?Element} */
this._reportContainer = null; this._reportContainer = null;
var url = new Common.ParsedURL(lighthouseResult.url); var url = new Common.ParsedURL(lighthouseResult.url);
var timestamp = lighthouseResult.generatedTime; var timestamp = lighthouseResult.generatedTime;
var titleElement = this.titleElement(); this._element = createElement('option');
titleElement.classList.add('audits2-report-tree-item'); this._element.label = `${url.domain()} ${new Date(timestamp).toLocaleString()}`;
titleElement.createChild('div').textContent = url.domain();
titleElement.createChild('span', 'dimmed').textContent = new Date(timestamp).toLocaleString();
this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), false);
} }
_populate() { select() {
for (var category of this._lighthouseResult.reportCategories) {
var treeElement = new Audits2.Audits2Panel.TreeSubElement(category.id, category.name, category.score);
this.appendChild(treeElement);
}
}
/**
* @override
* @param {boolean=} selectedByUser
* @return {boolean}
*/
onselect(selectedByUser) {
this._renderReport(); this._renderReport();
return true;
} }
/** /**
* @override * @return {!Element}
*/ */
ondelete() { optionElement() {
this._deleteItem(); return this._element;
return true;
} }
_deleteItem() { delete() {
this.treeOutline.removeChild(this); if (this._element)
this._element.remove();
this._showLandingCallback(); this._showLandingCallback();
} }
/** download() {
* @param {!Event} event var url = new Common.ParsedURL(this._lighthouseResult.url).domain();
*/ var timestamp = this._lighthouseResult.generatedTime;
_handleContextMenuEvent(event) { var fileName = `${url}-${new Date(timestamp).toISO8601Compact()}.json`;
var contextMenu = new UI.ContextMenu(event); Workspace.fileManager.save(fileName, JSON.stringify(this._lighthouseResult), true);
contextMenu.appendItem(Common.UIString('Save as\u2026'), () => {
var url = new Common.ParsedURL(this._lighthouseResult.url).domain();
var timestamp = this._lighthouseResult.generatedTime;
var fileName = `${url}-${new Date(timestamp).toISO8601Compact()}.json`;
Workspace.fileManager.save(fileName, JSON.stringify(this._lighthouseResult), true);
});
contextMenu.appendItem(Common.UIString('Delete'), () => this._deleteItem());
contextMenu.show();
}
/**
* @override
*/
onunbind() {
if (this._reportContainer && this._reportContainer.parentElement)
this._reportContainer.remove();
} }
_renderReport() { _renderReport() {
...@@ -712,36 +732,6 @@ Audits2.Audits2Panel.TreeElement = class extends UI.TreeElement { ...@@ -712,36 +732,6 @@ Audits2.Audits2Panel.TreeElement = class extends UI.TreeElement {
} }
}; };
Audits2.Audits2Panel.TreeSubElement = class extends UI.TreeElement {
/**
* @param {string} id
* @param {string} name
* @param {number} score
*/
constructor(id, name, score) {
super('');
this._id = id;
this.listItemElement.textContent = name;
var label = Util.calculateRating(score);
var subtitleElement = this.listItemElement.createChild('span', 'lh-vars audits2-tree-subtitle-' + label);
subtitleElement.textContent = String(Math.round(score));
}
/**
* @override
* @return {boolean}
*/
onselect() {
this.parent._renderReport();
var node = this.parent._resultsView.querySelector('.lh-category[id=' + this._id + ']');
if (node) {
node.scrollIntoView(true);
return true;
}
return false;
}
};
Audits2.DetailsRenderer = class extends DetailsRenderer { Audits2.DetailsRenderer = class extends DetailsRenderer {
/** /**
* @param {!DOM} dom * @param {!DOM} dom
......
/*
* Copyright 2017 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
.tree-outline .audits2-report-tree-item {
min-height: 36px;
padding: 2px 3px;
line-height: 16px;
}
.tree-outline li {
min-height: 25px;
}
.audits2-tree-subtitle-pass,
.audits2-tree-subtitle-average,
.audits2-tree-subtitle-fail {
flex: auto;
text-align: end;
margin-right: 10px;
}
.audits2-tree-subtitle-pass {
color: var(--pass-color);
}
.audits2-tree-subtitle-average {
color: var(--average-color);
}
.audits2-tree-subtitle-fail {
color: var(--fail-color);
}
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
"resources": [ "resources": [
"audits2Dialog.css", "audits2Dialog.css",
"audits2Panel.css", "audits2Panel.css",
"audits2Tree.css",
"lighthouse/report-styles.css", "lighthouse/report-styles.css",
"lighthouse/templates.html" "lighthouse/templates.html"
] ]
......
...@@ -174,6 +174,7 @@ UI.Icon.Descriptors = { ...@@ -174,6 +174,7 @@ UI.Icon.Descriptors = {
'largeicon-dock-to-bottom': {position: 'd8', spritesheet: 'largeicons', isMask: true}, 'largeicon-dock-to-bottom': {position: 'd8', spritesheet: 'largeicons', isMask: true},
'largeicon-dock-to-left': {position: 'd7', spritesheet: 'largeicons', isMask: true}, 'largeicon-dock-to-left': {position: 'd7', spritesheet: 'largeicons', isMask: true},
'largeicon-dock-to-right': {position: 'd6', spritesheet: 'largeicons', isMask: true}, 'largeicon-dock-to-right': {position: 'd6', spritesheet: 'largeicons', isMask: true},
'largeicon-download': {position: 'h6', spritesheet: 'largeicons', isMask: true},
'largeicon-edit': {position: 'a5', spritesheet: 'largeicons', isMask: true}, 'largeicon-edit': {position: 'a5', spritesheet: 'largeicons', isMask: true},
'largeicon-eyedropper': {position: 'b5', spritesheet: 'largeicons', isMask: true}, 'largeicon-eyedropper': {position: 'b5', spritesheet: 'largeicons', isMask: true},
'largeicon-filter': {position: 'c5', spritesheet: 'largeicons', isMask: true}, 'largeicon-filter': {position: 'c5', spritesheet: 'largeicons', isMask: true},
......
...@@ -965,6 +965,13 @@ UI.ToolbarComboBox = class extends UI.ToolbarItem { ...@@ -965,6 +965,13 @@ UI.ToolbarComboBox = class extends UI.ToolbarItem {
setMaxWidth(width) { setMaxWidth(width) {
this._selectElement.style.maxWidth = width + 'px'; this._selectElement.style.maxWidth = width + 'px';
} }
/**
* @param {number} width
*/
setMinWidth(width) {
this._selectElement.style.minWidth = width + 'px';
}
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment