Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Unified Diff: third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/category-renderer.js

Issue 2856653002: Roll Lighthouse & add error reporting (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/category-renderer.js
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/report-renderer.js b/third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/category-renderer.js
similarity index 53%
copy from third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/report-renderer.js
copy to third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/category-renderer.js
index 88c28fbeb4f18e243f165202aa60a53c62668ade..fa662daf03ad9418f85002ea16c55b6e36e09d19 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/report-renderer.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/category-renderer.js
@@ -15,98 +15,22 @@
*/
'use strict';
-/**
- * @fileoverview The entry point for rendering the Lighthouse report based on the JSON output.
- * This file is injected into the report HTML along with the JSON report.
- *
- * Dummy text for ensuring report robustness: </script> pre$`post %%LIGHTHOUSE_JSON%%
- */
-
-const RATINGS = {
- PASS: {label: 'pass', minScore: 75},
- AVERAGE: {label: 'average', minScore: 45},
- FAIL: {label: 'fail'}
-};
-
-/**
- * Convert a score to a rating label.
- * @param {number} score
- * @return {string}
- */
-function calculateRating(score) {
- let rating = RATINGS.FAIL.label;
- if (score >= RATINGS.PASS.minScore) {
- rating = RATINGS.PASS.label;
- } else if (score >= RATINGS.AVERAGE.minScore) {
- rating = RATINGS.AVERAGE.label;
- }
- return rating;
-}
-
-/**
- * Format number.
- * @param {number} number
- * @return {string}
- */
-function formatNumber(number) {
- return number.toLocaleString(undefined, {maximumFractionDigits: 1});
-}
+/* globals self, Util */
-class ReportRenderer {
+class CategoryRenderer {
/**
* @param {!DOM} dom
* @param {!DetailsRenderer} detailsRenderer
*/
constructor(dom, detailsRenderer) {
+ /** @private {!DOM} */
this._dom = dom;
+ /** @private {!DetailsRenderer} */
this._detailsRenderer = detailsRenderer;
-
+ /** @private {!Document|!Element} */
this._templateContext = this._dom.document();
}
- /**
- * @param {!ReportRenderer.ReportJSON} report
- * @return {!Element}
- */
- renderReport(report) {
- try {
- return this._renderReport(report);
- } catch (e) {
- return this._renderException(e);
- }
- }
-
- /**
- * @param {!DocumentFragment|!Element} element DOM node to populate with values.
- * @param {number} score
- * @param {string} scoringMode
- * @param {string} title
- * @param {string} description
- * @return {!Element}
- */
- _populateScore(element, score, scoringMode, title, description) {
- // Fill in the blanks.
- const valueEl = element.querySelector('.lh-score__value');
- valueEl.textContent = formatNumber(score);
- valueEl.classList.add(`lh-score__value--${calculateRating(score)}`,
- `lh-score__value--${scoringMode}`);
-
- element.querySelector('.lh-score__title').textContent = title;
- element.querySelector('.lh-score__description')
- .appendChild(this._dom.createSpanFromMarkdown(description));
-
- return /** @type {!Element} **/ (element);
- }
-
- /**
- * Define a custom element for <templates> to be extracted from. For example:
- * this.setTemplateContext(new DOMParser().parseFromString(htmlStr, 'text/html'))
- * @param {!Document|!Element} context
- */
- setTemplateContext(context) {
- this._templateContext = context;
- }
-
/**
* @param {!ReportRenderer.AuditJSON} audit
* @return {!Element}
@@ -125,8 +49,13 @@ class ReportRenderer {
title += ` (target: ${audit.result.optimalValue})`;
}
+ if (audit.result.debugString) {
+ const debugStrEl = tmpl.appendChild(this._dom.createElement('div', 'lh-debug'));
+ debugStrEl.textContent = audit.result.debugString;
+ }
+
// Append audit details to header section so the entire audit is within a <details>.
- const header = tmpl.querySelector('.lh-score__header');
+ const header = /** @type {!HTMLDetailsElement} */ (this._dom.find('.lh-score__header', tmpl));
header.open = audit.score < 100; // expand failed audits
if (audit.result.details) {
header.appendChild(this._detailsRenderer.render(audit.result.details));
@@ -135,6 +64,28 @@ class ReportRenderer {
return this._populateScore(tmpl, audit.score, scoringMode, title, description);
}
+ /**
+ * @param {!DocumentFragment|!Element} element DOM node to populate with values.
+ * @param {number} score
+ * @param {string} scoringMode
+ * @param {string} title
+ * @param {string} description
+ * @return {!Element}
+ */
+ _populateScore(element, score, scoringMode, title, description) {
+ // Fill in the blanks.
+ const valueEl = this._dom.find('.lh-score__value', element);
+ valueEl.textContent = Util.formatNumber(score);
+ valueEl.classList.add(`lh-score__value--${Util.calculateRating(score)}`,
+ `lh-score__value--${scoringMode}`);
+
+ this._dom.find('.lh-score__title', element).textContent = title;
+ this._dom.find('.lh-score__description', element)
+ .appendChild(this._dom.createSpanFromMarkdown(description));
+
+ return /** @type {!Element} **/ (element);
+ }
+
/**
* @param {!ReportRenderer.CategoryJSON} category
* @return {!Element}
@@ -146,33 +97,58 @@ class ReportRenderer {
}
/**
- * @param {!Error} e
+ * @param {!ReportRenderer.AuditJSON} audit
* @return {!Element}
*/
- _renderException(e) {
- const element = this._dom.createElement('div', 'lh-exception');
- element.textContent = String(e.stack);
+ _renderAudit(audit) {
+ const element = this._dom.createElement('div', 'lh-audit');
+ element.appendChild(this._renderAuditScore(audit));
return element;
}
/**
- * @param {!ReportRenderer.ReportJSON} report
- * @return {!Element}
+ * @param {!Document|!Element} context
*/
- _renderReport(report) {
- const element = this._dom.createElement('div', 'lh-report');
- for (const category of report.reportCategories) {
- element.appendChild(this._renderCategory(category));
- }
- return element;
+ setTemplateContext(context) {
+ this._templateContext = context;
+ }
+
+ /**
+ * @param {!ReportRenderer.CategoryJSON} category
+ * @return {!DocumentFragment}
+ */
+ renderScoreGauge(category) {
+ const tmpl = this._dom.cloneTemplate('#tmpl-lh-gauge', this._templateContext);
+ this._dom.find('.lh-gauge__wrapper', tmpl).href = `#${category.id}`;
+ this._dom.find('.lh-gauge__label', tmpl).textContent = category.name;
+
+ const score = Math.round(category.score);
+ const fillRotation = Math.floor((score / 100) * 180);
+
+ const gauge = this._dom.find('.lh-gauge', tmpl);
+ gauge.setAttribute('data-progress', score); // .dataset not supported in jsdom.
+ gauge.classList.add(`lh-gauge--${Util.calculateRating(score)}`);
+
+ this._dom.findAll('.lh-gauge__fill', gauge).forEach(el => {
+ el.style.transform = `rotate(${fillRotation}deg)`;
+ });
+
+ this._dom.find('.lh-gauge__mask--full', gauge).style.transform =
+ `rotate(${fillRotation}deg)`;
+ this._dom.find('.lh-gauge__fill--fix', gauge).style.transform =
+ `rotate(${fillRotation * 2}deg)`;
+ this._dom.find('.lh-gauge__percentage', gauge).textContent = score;
+
+ return tmpl;
}
/**
* @param {!ReportRenderer.CategoryJSON} category
* @return {!Element}
*/
- _renderCategory(category) {
+ render(category) {
const element = this._dom.createElement('div', 'lh-category');
+ element.id = category.id;
element.appendChild(this._renderCategoryScore(category));
const passedAudits = category.audits.filter(audit => audit.score === 100);
@@ -182,8 +158,10 @@ class ReportRenderer {
element.appendChild(this._renderAudit(audit));
}
- // don't create a passed section if there are no passed
- if (!passedAudits.length) return element;
+ // Don't create a passed section if there are no passed.
+ if (!passedAudits.length) {
+ return element;
+ }
const passedElem = this._dom.createElement('details', 'lh-passed-audits');
const passedSummary = this._dom.createElement('summary', 'lh-passed-audits-summary');
@@ -196,57 +174,10 @@ class ReportRenderer {
element.appendChild(passedElem);
return element;
}
-
- /**
- * @param {!ReportRenderer.AuditJSON} audit
- * @return {!Element}
- */
- _renderAudit(audit) {
- const element = this._dom.createElement('div', 'lh-audit');
- element.appendChild(this._renderAuditScore(audit));
- return element;
- }
}
if (typeof module !== 'undefined' && module.exports) {
- module.exports = ReportRenderer;
+ module.exports = CategoryRenderer;
+} else {
+ self.CategoryRenderer = CategoryRenderer;
}
-
-/**
- * @typedef {{
- * id: string, weight:
- * number, score: number,
- * result: {
- * description: string,
- * displayValue: string,
- * helpText: string,
- * score: (number|boolean),
- * scoringMode: string,
- * details: (!DetailsRenderer.DetailsJSON|!DetailsRenderer.CardsDetailsJSON|undefined)
- * }
- * }}
- */
-ReportRenderer.AuditJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- * name: string,
- * weight: number,
- * score: number,
- * description: string,
- * audits: !Array<!ReportRenderer.AuditJSON>
- * }}
- */
-ReportRenderer.CategoryJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- * lighthouseVersion: !string,
- * generatedTime: !string,
- * initialUrl: !string,
- * url: !string,
- * audits: ?Object,
- * reportCategories: !Array<!ReportRenderer.CategoryJSON>
- * }}
- */
-ReportRenderer.ReportJSON; // eslint-disable-line no-unused-expressions

Powered by Google App Engine
This is Rietveld 408576698