| 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
|
|
|