DevTools: [Audits] Roll to Lighthouse 3.2.0
Bug: 772558
Change-Id: I39c0c5b701bd22857168da62e2be440114c853ae
Reviewed-on: https://chromium-review.googlesource.com/c/1249489
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Commit-Queue: Paul Irish <paulirish@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#598608}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: fef3d59edbfb9fb47427c747d102966fdd397512
diff --git a/front_end/audits2/Audits2ReportRenderer.js b/front_end/audits2/Audits2ReportRenderer.js
index cad5a0b..b875240 100644
--- a/front_end/audits2/Audits2ReportRenderer.js
+++ b/front_end/audits2/Audits2ReportRenderer.js
@@ -16,7 +16,7 @@
const defaultPassTrace = artifacts.traces.defaultPass;
const timelineButton = UI.createTextButton(Common.UIString('View Trace'), onViewTraceClick, 'view-trace');
- el.querySelector('.lh-metric-column').appendChild(timelineButton);
+ el.querySelector('.lh-column').appendChild(timelineButton);
return el;
async function onViewTraceClick() {
diff --git a/front_end/audits2/lighthouse/renderer/category-renderer.js b/front_end/audits2/lighthouse/renderer/category-renderer.js
index 4daf750..973526c 100644
--- a/front_end/audits2/lighthouse/renderer/category-renderer.js
+++ b/front_end/audits2/lighthouse/renderer/category-renderer.js
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
'use strict';
@@ -75,10 +86,10 @@
if (audit.result.scoreDisplayMode === 'error') {
auditEl.classList.add(`lh-audit--error`);
const textEl = this.dom.find('.lh-audit__display-text', auditEl);
- textEl.textContent = 'Error!';
+ textEl.textContent = Util.UIStrings.errorLabel;
textEl.classList.add('tooltip-boundary');
const tooltip = this.dom.createChildOf(textEl, 'div', 'tooltip tooltip--error');
- tooltip.textContent = audit.result.errorMessage || 'Report error: no audit information';
+ tooltip.textContent = audit.result.errorMessage || Util.UIStrings.errorMissingAuditInfo;
} else if (audit.result.explanation) {
const explEl = this.dom.createChildOf(titleEl, 'div', 'lh-audit-explanation');
explEl.textContent = audit.result.explanation;
@@ -89,9 +100,9 @@
// Add list of warnings or singular warning
const warningsEl = this.dom.createChildOf(titleEl, 'div', 'lh-warnings');
if (warnings.length === 1) {
- warningsEl.textContent = `Warning: ${warnings.join('')}`;
+ warningsEl.textContent = `${Util.UIStrings.warningHeader} ${warnings.join('')}`;
} else {
- warningsEl.textContent = 'Warnings: ';
+ warningsEl.textContent = Util.UIStrings.warningHeader;
const warningsUl = this.dom.createChildOf(warningsEl, 'ul');
for (const warning of warnings) {
const item = this.dom.createChildOf(warningsUl, 'li');
@@ -158,7 +169,7 @@
const itemCountEl = this.dom.createChildOf(summmaryEl, 'div', 'lh-audit-group__itemcount');
if (expandable) {
const chevronEl = summmaryEl.appendChild(this._createChevron());
- chevronEl.title = 'Show audits';
+ chevronEl.title = Util.UIStrings.auditGroupExpandTooltip;
}
if (group.description) {
@@ -169,6 +180,7 @@
headerEl.textContent = group.title;
if (opts.itemCount) {
+ // TODO(i18n): support multiple locales here
itemCountEl.textContent = `${opts.itemCount} audits`;
}
return groupEl;
@@ -211,7 +223,7 @@
*/
renderPassedAuditsSection(elements) {
const passedElem = this.renderAuditGroup({
- title: `Passed audits`,
+ title: Util.UIStrings.passedAuditsGroupTitle,
}, {expandable: true, itemCount: this._getTotalAuditsLength(elements)});
passedElem.classList.add('lh-passed-audits');
elements.forEach(elem => passedElem.appendChild(elem));
@@ -224,7 +236,7 @@
*/
_renderNotApplicableAuditsSection(elements) {
const notApplicableElem = this.renderAuditGroup({
- title: `Not applicable`,
+ title: Util.UIStrings.notApplicableAuditsGroupTitle,
}, {expandable: true, itemCount: this._getTotalAuditsLength(elements)});
notApplicableElem.classList.add('lh-audit-group--not-applicable');
elements.forEach(elem => notApplicableElem.appendChild(elem));
@@ -237,7 +249,7 @@
* @return {Element}
*/
_renderManualAudits(manualAudits, manualDescription) {
- const group = {title: 'Additional items to manually check', description: manualDescription};
+ const group = {title: Util.UIStrings.manualAuditsGroupTitle, description: manualDescription};
const auditGroupElem = this.renderAuditGroup(group,
{expandable: true, itemCount: manualAudits.length});
auditGroupElem.classList.add('lh-audit-group--manual');
@@ -282,7 +294,7 @@
percentageEl.textContent = scoreOutOf100.toString();
if (category.score === null) {
percentageEl.textContent = '?';
- percentageEl.title = 'Errors occurred while auditing';
+ percentageEl.title = Util.UIStrings.errorLabel;
}
this.dom.find('.lh-gauge__label', tmpl).textContent = category.title;
diff --git a/front_end/audits2/lighthouse/renderer/crc-details-renderer.js b/front_end/audits2/lighthouse/renderer/crc-details-renderer.js
index 5c5fe79..0ab3741 100644
--- a/front_end/audits2/lighthouse/renderer/crc-details-renderer.js
+++ b/front_end/audits2/lighthouse/renderer/crc-details-renderer.js
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
'use strict';
@@ -115,11 +126,11 @@
dom.find('.crc-node__tree-hostname', treevalEl).textContent = hostname ? `(${hostname})` : '';
if (!segment.hasChildren) {
+ const {startTime, endTime, transferSize} = segment.node.request;
const span = dom.createElement('span', 'crc-node__chain-duration');
- span.textContent = ' - ' + Util.chainDuration(
- segment.node.request.startTime, segment.node.request.endTime) + 'ms, ';
+ span.textContent = ' - ' + Util.formatMilliseconds((endTime - startTime) * 1000) + ', ';
const span2 = dom.createElement('span', 'crc-node__chain-duration');
- span2.textContent = Util.formatBytesToKB(segment.node.request.transferSize, 0.01);
+ span2.textContent = Util.formatBytesToKB(transferSize, 0.01);
treevalEl.appendChild(span);
treevalEl.appendChild(span2);
@@ -157,11 +168,11 @@
const containerEl = dom.find('.lh-crc', tmpl);
// Fill in top summary.
+ dom.find('.crc-initial-nav', tmpl).textContent = Util.UIStrings.crcInitialNavigation;
+ dom.find('.lh-crc__longest_duration_label', tmpl).textContent =
+ Util.UIStrings.crcLongestDurationLabel;
dom.find('.lh-crc__longest_duration', tmpl).textContent =
- Util.formatNumber(details.longestChain.duration) + 'ms';
- dom.find('.lh-crc__longest_length', tmpl).textContent = details.longestChain.length.toString();
- dom.find('.lh-crc__longest_transfersize', tmpl).textContent =
- Util.formatBytesToKB(details.longestChain.transferSize);
+ Util.formatMilliseconds(details.longestChain.duration);
// Construct visual tree.
const root = CriticalRequestChainRenderer.initTree(details.chains);
diff --git a/front_end/audits2/lighthouse/renderer/details-renderer.js b/front_end/audits2/lighthouse/renderer/details-renderer.js
index 9f48a3e..a5cf44b 100644
--- a/front_end/audits2/lighthouse/renderer/details-renderer.js
+++ b/front_end/audits2/lighthouse/renderer/details-renderer.js
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
'use strict';
diff --git a/front_end/audits2/lighthouse/renderer/dom.js b/front_end/audits2/lighthouse/renderer/dom.js
index 69ce25b..fa1d564 100644
--- a/front_end/audits2/lighthouse/renderer/dom.js
+++ b/front_end/audits2/lighthouse/renderer/dom.js
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
'use strict';
diff --git a/front_end/audits2/lighthouse/renderer/performance-category-renderer.js b/front_end/audits2/lighthouse/renderer/performance-category-renderer.js
index 3b25314..873c0b7 100644
--- a/front_end/audits2/lighthouse/renderer/performance-category-renderer.js
+++ b/front_end/audits2/lighthouse/renderer/performance-category-renderer.js
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2018 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2018 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
'use strict';
@@ -101,24 +112,31 @@
/**
* @param {LH.ReportResult.Category} category
* @param {Object<string, LH.Result.ReportGroup>} groups
+ * @param {'PSI'=} environment 'PSI' and undefined are the only valid values
* @return {Element}
* @override
*/
- render(category, groups) {
+ render(category, groups, environment) {
const element = this.dom.createElement('div', 'lh-category');
- this.createPermalinkSpan(element, category.id);
- element.appendChild(this.renderCategoryHeader(category));
+ if (environment === 'PSI') {
+ const gaugeEl = this.dom.createElement('div', 'lh-score__gauge');
+ gaugeEl.appendChild(this.renderScoreGauge(category));
+ element.appendChild(gaugeEl);
+ } else {
+ this.createPermalinkSpan(element, category.id);
+ element.appendChild(this.renderCategoryHeader(category));
+ }
// Metrics
const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
- const metricAuditsEl = this.renderAuditGroup(groups['metrics'], {expandable: false});
+ const metricAuditsEl = this.renderAuditGroup(groups.metrics, {expandable: false});
const keyMetrics = metricAudits.filter(a => a.weight >= 3);
const otherMetrics = metricAudits.filter(a => a.weight < 3);
- const metricsBoxesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-metric-container');
- const metricsColumn1El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-metric-column');
- const metricsColumn2El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-metric-column');
+ const metricsBoxesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-columns');
+ const metricsColumn1El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-column');
+ const metricsColumn2El = this.dom.createChildOf(metricsBoxesEl, 'div', 'lh-column');
keyMetrics.forEach(item => {
metricsColumn1El.appendChild(this._renderMetric(item));
@@ -126,9 +144,13 @@
otherMetrics.forEach(item => {
metricsColumn2El.appendChild(this._renderMetric(item));
});
- const estValuesEl = this.dom.createChildOf(metricsColumn2El, 'div',
- 'lh-metrics__disclaimer lh-metrics__disclaimer');
- estValuesEl.textContent = 'Values are estimated and may vary.';
+
+ // 'Values are estimated and may vary' is used as the category description for PSI
+ if (environment !== 'PSI') {
+ const estValuesEl = this.dom.createChildOf(metricsColumn2El, 'div',
+ 'lh-metrics__disclaimer lh-metrics__disclaimer');
+ estValuesEl.textContent = Util.UIStrings.varianceDisclaimer;
+ }
metricAuditsEl.classList.add('lh-audit-group--metrics');
element.appendChild(metricAuditsEl);
@@ -156,6 +178,12 @@
const scale = Math.max(Math.ceil(maxWaste / 1000) * 1000, minimumScale);
const groupEl = this.renderAuditGroup(groups['load-opportunities'], {expandable: false});
const tmpl = this.dom.cloneTemplate('#tmpl-lh-opportunity-header', this.templateContext);
+
+ this.dom.find('.lh-load-opportunity__col--one', tmpl).textContent =
+ Util.UIStrings.opportunityResourceColumnLabel;
+ this.dom.find('.lh-load-opportunity__col--two', tmpl).textContent =
+ Util.UIStrings.opportunitySavingsColumnLabel;
+
const headerEl = this.dom.find('.lh-load-opportunity__header', tmpl);
groupEl.appendChild(headerEl);
opportunityAudits.forEach((item, i) =>
diff --git a/front_end/audits2/lighthouse/renderer/report-renderer.js b/front_end/audits2/lighthouse/renderer/report-renderer.js
index de990d2..23e772f 100644
--- a/front_end/audits2/lighthouse/renderer/report-renderer.js
+++ b/front_end/audits2/lighthouse/renderer/report-renderer.js
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
'use strict';
@@ -29,20 +40,21 @@
}
/**
- * @param {LH.ReportResult} report
+ * @param {LH.Result} result
* @param {Element} container Parent element to render the report into.
*/
- renderReport(report, container) {
- // If any mutations happen to the report within the renderers, we want the original object untouched
- const clone = /** @type {LH.ReportResult} */ (JSON.parse(JSON.stringify(report)));
+ renderReport(result, container) {
+ // Mutate the UIStrings if necessary (while saving originals)
+ const originalUIStrings = JSON.parse(JSON.stringify(Util.UIStrings));
- // TODO(phulce): we all agree this is technical debt we should fix
- if (typeof clone.categories !== 'object') throw new Error('No categories provided.');
- clone.reportCategories = Object.values(clone.categories);
- ReportRenderer.smooshAuditResultsIntoCategories(clone.audits, clone.reportCategories);
+ const report = Util.prepareReportResult(result);
container.textContent = ''; // Remove previous report.
- container.appendChild(this._renderReport(clone));
+ container.appendChild(this._renderReport(report));
+
+ // put the UIStrings back into original state
+ Util.updateAllUIStrings(originalUIStrings);
+
return /** @type {Element} **/ (container);
}
@@ -103,8 +115,14 @@
{name: 'URL', description: report.finalUrl},
{name: 'Fetch time', description: Util.formatDateTime(report.fetchTime)},
...envValues,
- {name: 'User agent', description: report.userAgent},
+ {name: 'User agent (host)', description: report.userAgent},
+ {name: 'User agent (network)', description: report.environment &&
+ report.environment.networkUserAgent},
+ {name: 'CPU/Memory Power', description: report.environment &&
+ report.environment.benchmarkIndex.toFixed(0)},
].forEach(runtime => {
+ if (!runtime.description) return;
+
const item = this._dom.cloneTemplate('#tmpl-lh-env__items', env);
this._dom.find('.lh-env__name', item).textContent = `${runtime.name}:`;
this._dom.find('.lh-env__description', item).textContent = runtime.description;
@@ -126,6 +144,9 @@
}
const container = this._dom.cloneTemplate('#tmpl-lh-warnings--toplevel', this._templateContext);
+ const message = this._dom.find('.lh-warnings__msg', container);
+ message.textContent = Util.UIStrings.toplevelWarningsMessage;
+
const warnings = this._dom.find('ul', container);
for (const warningString of report.runWarnings) {
const warning = warnings.appendChild(this._dom.createElement('li'));
@@ -150,7 +171,6 @@
header = this._renderReportHeader(report);
}
headerContainer.appendChild(header);
- const scoresContainer = this._dom.find('.lh-scores-container', headerContainer);
const container = this._dom.createElement('div', 'lh-container');
const reportSection = container.appendChild(this._dom.createElement('div', 'lh-report'));
@@ -187,6 +207,9 @@
if (scoreHeader) {
const scoreScale = this._dom.cloneTemplate('#tmpl-lh-scorescale', this._templateContext);
+ this._dom.find('.lh-scorescale-label', scoreScale).textContent =
+ Util.UIStrings.scorescaleLabel;
+ const scoresContainer = this._dom.find('.lh-scores-container', headerContainer);
scoresContainer.appendChild(scoreHeader);
scoresContainer.appendChild(scoreScale);
}
@@ -199,22 +222,11 @@
return reportFragment;
}
-
- /**
- * Place the AuditResult into the auditDfn (which has just weight & group)
- * @param {Object<string, LH.Audit.Result>} audits
- * @param {Array<LH.ReportResult.Category>} reportCategories
- */
- static smooshAuditResultsIntoCategories(audits, reportCategories) {
- for (const category of reportCategories) {
- category.auditRefs.forEach(auditMeta => {
- const result = audits[auditMeta.id];
- auditMeta.result = result;
- });
- }
- }
}
+/** @type {LH.I18NRendererStrings} */
+ReportRenderer._UIStringsStash = {};
+
if (typeof module !== 'undefined' && module.exports) {
module.exports = ReportRenderer;
} else {
diff --git a/front_end/audits2/lighthouse/renderer/util.js b/front_end/audits2/lighthouse/renderer/util.js
index 87fc3a7..2b1996a 100644
--- a/front_end/audits2/lighthouse/renderer/util.js
+++ b/front_end/audits2/lighthouse/renderer/util.js
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
'use strict';
@@ -9,11 +20,11 @@
const ELLIPSIS = '\u2026';
const NBSP = '\xa0';
-const PASS_THRESHOLD = 0.75;
+const PASS_THRESHOLD = 0.9;
const RATINGS = {
PASS: {label: 'pass', minScore: PASS_THRESHOLD},
- AVERAGE: {label: 'average', minScore: 0.45},
+ AVERAGE: {label: 'average', minScore: 0.5},
FAIL: {label: 'fail'},
ERROR: {label: 'error'},
};
@@ -28,6 +39,52 @@
}
/**
+ * Returns a new LHR that's reshaped for slightly better ergonomics within the report rendereer.
+ * Also, sets up the localized UI strings used within renderer and number/date formatting
+ * The LHR passed in is not mutated.
+ * TODO(team): we all agree the LHR shape change is technical debt we should fix
+ * @param {LH.Result} result
+ * @return {LH.ReportResult}
+ */
+ static prepareReportResult(result) {
+ // If any mutations happen to the report within the renderers, we want the original object untouched
+ const clone = /** @type {LH.ReportResult} */ (JSON.parse(JSON.stringify(result)));
+
+ // If LHR is older (≤3.0.3), it has no locale setting. Set default.
+ if (!clone.configSettings.locale) {
+ clone.configSettings.locale = 'en';
+ }
+ Util.setNumberDateLocale(clone.configSettings.locale);
+ if (clone.i18n && clone.i18n.rendererFormattedStrings) {
+ Util.updateAllUIStrings(clone.i18n.rendererFormattedStrings);
+ }
+
+ if (typeof clone.categories !== 'object') throw new Error('No categories provided.');
+ clone.reportCategories = Object.values(clone.categories);
+
+ // For convenience, smoosh all AuditResults into their auditDfn (which has just weight & group)
+ for (const category of clone.reportCategories) {
+ category.auditRefs.forEach(auditMeta => {
+ const result = clone.audits[auditMeta.id];
+ auditMeta.result = result;
+ });
+ }
+
+ return clone;
+ }
+
+
+ /**
+ * @param {LH.I18NRendererStrings} rendererFormattedStrings
+ */
+ static updateAllUIStrings(rendererFormattedStrings) {
+ // TODO(i18n): don't mutate these here but on the LHR and pass that around everywhere
+ for (const [key, value] of Object.entries(rendererFormattedStrings)) {
+ Util.UIStrings[key] = value;
+ }
+ }
+
+ /**
* @param {string|Array<string|number>=} displayValue
* @return {string}
*/
@@ -85,10 +142,7 @@
case 'numeric':
case 'binary':
default:
- // Numeric audits that are within PASS_THRESHOLD will still show up with failing.
- // For opportunities, we want to have them show up with other failing for contrast.
- // For diagnostics, we sort by score so they'll be lowest priority.
- return Number(audit.score) === 1;
+ return Number(audit.score) >= RATINGS.PASS.minScore;
}
}
@@ -126,7 +180,7 @@
*/
static formatNumber(number, granularity = 0.1) {
const coarseValue = Math.round(number / granularity) * granularity;
- return coarseValue.toLocaleString();
+ return coarseValue.toLocaleString(Util.numberDateLocale);
}
/**
@@ -135,7 +189,8 @@
* @return {string}
*/
static formatBytesToKB(size, granularity = 0.1) {
- const kbs = (Math.round(size / 1024 / granularity) * granularity).toLocaleString();
+ const kbs = (Math.round(size / 1024 / granularity) * granularity)
+ .toLocaleString(Util.numberDateLocale);
return `${kbs}${NBSP}KB`;
}
@@ -146,7 +201,7 @@
*/
static formatMilliseconds(ms, granularity = 10) {
const coarseTime = Math.round(ms / granularity) * granularity;
- return `${coarseTime.toLocaleString()}${NBSP}ms`;
+ return `${coarseTime.toLocaleString(Util.numberDateLocale)}${NBSP}ms`;
}
/**
@@ -156,7 +211,7 @@
*/
static formatSeconds(ms, granularity = 0.1) {
const coarseTime = Math.round(ms / 1000 / granularity) * granularity;
- return `${coarseTime.toLocaleString()}${NBSP}s`;
+ return `${coarseTime.toLocaleString(Util.numberDateLocale)}${NBSP}s`;
}
/**
@@ -165,18 +220,19 @@
* @return {string}
*/
static formatDateTime(date) {
+ /** @type {Intl.DateTimeFormatOptions} */
const options = {
month: 'short', day: 'numeric', year: 'numeric',
hour: 'numeric', minute: 'numeric', timeZoneName: 'short',
};
- let formatter = new Intl.DateTimeFormat('en-US', options);
+ let formatter = new Intl.DateTimeFormat(Util.numberDateLocale, options);
// Force UTC if runtime timezone could not be detected.
// See https://github.com/GoogleChrome/lighthouse/issues/1056
const tz = formatter.resolvedOptions().timeZone;
if (!tz || tz.toLowerCase() === 'etc/unknown') {
options.timeZone = 'UTC';
- formatter = new Intl.DateTimeFormat('en-US', options);
+ formatter = new Intl.DateTimeFormat(Util.numberDateLocale, options);
}
return formatter.format(new Date(date));
}
@@ -297,15 +353,6 @@
}
/**
- * @param {number} startTime
- * @param {number} endTime
- * @return {string}
- */
- static chainDuration(startTime, endTime) {
- return Util.formatNumber((endTime - startTime) * 1000);
- }
-
- /**
* @param {LH.Config.Settings} settings
* @return {Array<{name: string, description: string}>}
*/
@@ -368,7 +415,12 @@
summary = 'Unknown';
}
- const deviceEmulation = settings.disableDeviceEmulation ? 'No emulation' : 'Emulated Nexus 5X';
+ let deviceEmulation = 'No emulation';
+ if (!settings.disableDeviceEmulation) {
+ if (settings.emulatedFormFactor === 'mobile') deviceEmulation = 'Emulated Nexus 5X';
+ if (settings.emulatedFormFactor === 'desktop') deviceEmulation = 'Emulated Desktop';
+ }
+
return {
deviceEmulation,
cpuThrottling,
@@ -376,8 +428,68 @@
summary: `${deviceEmulation}, ${summary}`,
};
}
+
+ /**
+ * Set the locale to be used for Util's number and date formatting functions.
+ * @param {LH.Locale} locale
+ */
+ static setNumberDateLocale(locale) {
+ Util.numberDateLocale = locale;
+
+ // When testing, use a locale with more exciting numeric formatting
+ if (Util.numberDateLocale === 'en-XA') Util.numberDateLocale = 'de';
+ }
}
+/**
+ * This value is updated on each run to the locale of the report
+ * @type {LH.Locale}
+ */
+Util.numberDateLocale = 'en';
+
+/**
+ * Report-renderer-specific strings.
+ * @type {LH.I18NRendererStrings}
+ */
+Util.UIStrings = {
+ /** Disclaimer shown to users below the metric values (First Contentful Paint, Time to Interactive, etc) to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. */
+ varianceDisclaimer: 'Values are estimated and may vary.',
+ /** Column heading label for the listing of opportunity audits. Each audit title represents an opportunity. There are only 2 columns, so no strict character limit. */
+ opportunityResourceColumnLabel: 'Opportunity',
+ /** Column heading label for the estimated page load savings of opportunity audits. Estimated Savings is the total amount of time (in seconds) that Lighthouse computed could be reduced from the total page load time, if the suggested action is taken. There are only 2 columns, so no strict character limit. */
+ opportunitySavingsColumnLabel: 'Estimated Savings',
+
+ /** An error string displayed next to a particular audit when it has errored, but not provided any specific error message. */
+ errorMissingAuditInfo: 'Report error: no audit information',
+ /** A label, shown next to an audit title or metric title, indicating that there was an error computing it. The user can hover on the label to reveal a tooltip with the extended error message. Translation should be short (< 20 characters). */
+ errorLabel: 'Error!',
+ /** This label is shown above a bulleted list of warnings. It is shown directly below an audit that produced warnings. Warnings describe situations the user should be aware of, as Lighthouse was unable to complete all the work required on this audit. For example, The 'Unable to decode image (biglogo.jpg)' warning may show up below an image encoding audit. */
+ warningHeader: 'Warnings: ',
+ /** The tooltip text on an expandable chevron icon. Clicking the icon expands a section to reveal a list of audit results that was hidden by default. */
+ auditGroupExpandTooltip: 'Show audits',
+ /** Section heading shown above a list of audits that are passing. 'Passed' here refers to a passing grade. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list. */
+ passedAuditsGroupTitle: 'Passed audits',
+ /** Section heading shown above a list of audits that do not apply to the page. For example, if an audit is 'Are images optimized?', but the page has no images on it, the audit will be marked as not applicable. This is neither passing or failing. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list. */
+ notApplicableAuditsGroupTitle: 'Not applicable',
+ /** Section heading shown above a list of audits that were not computed by Lighthouse. They serve as a list of suggestions for the user to go and manually check. For example, Lighthouse can't automate testing cross-browser compatibility, so that is listed within this section, so the user is reminded to test it themselves. This section is collapsed by default, as the user should be focusing on the failed audits instead. Users can click this heading to reveal the list. */
+ manualAuditsGroupTitle: 'Additional items to manually check',
+
+ /** Label shown preceding any important warnings that may have invalidated the entire report. For example, if the user has Chrome extensions installed, they may add enough performance overhead that Lighthouse's performance metrics are unreliable. If shown, this will be displayed at the top of the report UI. */
+ toplevelWarningsMessage: 'There were issues affecting this run of Lighthouse:',
+ /** Label preceding a pictorial explanation of the scoring scale: 0-50 is red (bad), 50-90 is orange (ok), 90-100 is green (good). These colors are used throughout the report to provide context for how good/bad a particular result is. */
+ scorescaleLabel: 'Score scale:',
+
+ /** String of text shown in a graphical representation of the flow of network requests for the web page. This label represents the initial network request that fetches an HTML page. This navigation may be redirected (eg. Initial navigation to http://example.com redirects to https://www.example.com). */
+ crcInitialNavigation: 'Initial Navigation',
+ /** Label of value shown in the summary of critical request chains. Refers to the total amount of time (milliseconds) of the longest critical path chain/sequence of network requests. Example value: 2310 ms */
+ crcLongestDurationLabel: 'Maximum critical path latency:',
+
+ /** Explanation shown to users below performance results to inform them that the test was done with a 3G network connection and to warn them that the numbers they see will likely change slightly the next time they run Lighthouse. 'Lighthouse' becomes link text to additional documentation. */
+ lsPerformanceCategoryDescription: '[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on emulated 3G. Values are estimated and may vary.',
+ /** Title of the lab data section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. "Lab" is an abbreviated form of "laboratory", and refers to the fact that the data is from a controlled test of a website, not measurements from real users visiting that site. */
+ labDataTitle: 'Lab Data',
+};
+
if (typeof module !== 'undefined' && module.exports) {
module.exports = Util;
} else {
diff --git a/front_end/audits2/lighthouse/report-styles.css b/front_end/audits2/lighthouse/report-styles.css
index d175f72..c65e8e5 100644
--- a/front_end/audits2/lighthouse/report-styles.css
+++ b/front_end/audits2/lighthouse/report-styles.css
@@ -1,7 +1,18 @@
/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * @license
+ * Copyright 2017 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
.lh-vars {
@@ -43,7 +54,6 @@
--metric-timeline-rule-color: #b3b3b3;
--display-value-gray: hsl(216, 5%, 39%);
--report-width: calc(60 * var(--body-font-size));
- --report-content-width: calc(var(--report-width));
--report-header-height: 161px;
--report-header-color: #202124;
--navitem-font-size: var(--body-font-size);
@@ -69,16 +79,17 @@
/* Voodoo magic here to get narrow columns. 0 doesn't size the column like our friend 1px does */
--bytes-col-width: 1px;
-
--pass-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>check</title><path fill="hsl(139, 70%, 30%)" d="M24 4C12.95 4 4 12.95 4 24c0 11.04 8.95 20 20 20 11.04 0 20-8.96 20-20 0-11.05-8.96-20-20-20zm-4 30L10 24l2.83-2.83L20 28.34l15.17-15.17L38 16 20 34z"/></svg>');
--average-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>info</title><path fill="hsl(31, 100%, 45%)" d="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm2 30h-4V22h4v12zm0-16h-4v-4h4v4z"/></svg>');
--fail-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>warn</title><path fill="hsl(1, 73%, 45%)" d="M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z"/></svg>');
- --av-timer-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><path d="M0 0h48v48H0z" fill="none"/><path d="M22 34c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zm0-28v8h4v-3.84c6.78.97 12 6.79 12 13.84 0 7.73-6.27 14-14 14s-14-6.27-14-14c0-3.36 1.18-6.43 3.15-8.85L24 26l2.83-2.83-13.6-13.6-.02.04C8.84 12.89 6 18.11 6 24c0 9.94 8.04 18 17.99 18S42 33.94 42 24 33.94 6 23.99 6H22zm14 18c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-24 0c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z" fill="hsl(216, 5%, 39%)"/></svg>');
+ --content-paste-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="hsl(216, 5%, 39%)" d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
+ --av-timer-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="hsl(216, 5%, 39%)"><path d="M0 0h24v24H0z" fill="none"/><path d="M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.03-6.61l1.42-1.42c-.43-.51-.9-.99-1.41-1.41l-1.42 1.42A8.962 8.962 0 0 0 12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9a8.994 8.994 0 0 0 7.03-14.61zM12 20c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg>');
--photo-filter-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><path fill="none" d="M0 0h48v48H0V0z"/><path d="M38.04 20v18H10V10h18V6H10.04c-2.2 0-4 1.8-4 4v28c0 2.2 1.8 4 4 4h28c2.2 0 4-1.8 4-4V20h-4zM34 20l1.88-4.12L40 14l-4.12-1.88L34 8l-1.88 4.12L28 14l4.12 1.88zm-7.5 1.5L24 16l-2.5 5.5L16 24l5.5 2.5L24 32l2.5-5.5L32 24z" fill="hsl(216, 5%, 39%)"/></svg>');
--visibility-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><path d="M0 0h48v48H0z" fill="none"/><path d="M24 9C14 9 5.46 15.22 2 24c3.46 8.78 12 15 22 15 10.01 0 18.54-6.22 22-15-3.46-8.78-11.99-15-22-15zm0 25c-5.52 0-10-4.48-10-10s4.48-10 10-10 10 4.48 10 10-4.48 10-10 10zm0-16c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6z" fill="hsl(216, 5%, 39%)"/></svg>');
--check-circle-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><path d="M0 0h48v48H0z" fill="none"/><path d="M24 4C12.95 4 4 12.95 4 24c0 11.04 8.95 20 20 20 11.04 0 20-8.96 20-20 0-11.05-8.96-20-20-20zm-4 30L10 24l2.83-2.83L20 28.34l15.17-15.17L38 16 20 34z" fill="hsl(216, 5%, 39%)"/></svg>');
--check-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><path d="M0 0h48v48H0z" fill="none"/><path d="M18 32.34L9.66 24l-2.83 2.83L18 38l24-24-2.83-2.83z"/></svg>');
+
--search-icon-url: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><path d="M31 28h-1.59l-.55-.55C30.82 25.18 32 22.23 32 19c0-7.18-5.82-13-13-13S6 11.82 6 19s5.82 13 13 13c3.23 0 6.18-1.18 8.45-3.13l.55.55V31l10 9.98L40.98 38 31 28zm-12 0a9 9 0 1 1 .001-18.001A9 9 0 0 1 19 28z" fill="hsl(216, 5%, 39%)"/><path d="M0 0h48v48H0z" fill="none" /></svg>');
--remove-circle-icon-url: url('data:image/svg+xml;utf8,<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" fill="hsl(216, 5%, 39%)"/></svg>');
}
@@ -131,27 +142,30 @@
outline: -webkit-focus-ring-color auto 3px;
}
.lh-root summary:focus {
- outline: 1px solid hsl(217, 89%, 61%);
+ outline: none;
+ box-shadow: 0 0 0 1px hsl(217, 89%, 61%);
}
-
.lh-root [hidden] {
display: none !important;
}
+.lh-root details > summary {
+ cursor: pointer;
+}
+
.lh-audit-group a,
.lh-category-header__description a {
color: #0c50c7;
}
-
-.lh-audit__description,
-.lh-load-opportunity__description,
-.lh-details {
+.lh-audit__description {
--inner-audit-left-padding: calc(var(--text-indent) + var(--lh-audit-index-width) + 2 * var(--audit-item-gap));
--inner-audit-right-padding: calc(var(--text-indent) + 2px);
- margin-left: var(--inner-audit-left-padding);
- margin-right: var(--inner-audit-right-padding);
+ padding-left: var(--inner-audit-left-padding);
+ padding-right: var(--inner-audit-right-padding);
+ padding-top: 8px;
+ padding-bottom: 8px;
}
.lh-details {
@@ -159,7 +173,7 @@
margin-top: var(--default-padding);
margin-bottom: var(--default-padding);
/* whatever the .lh-details side margins are */
- width: calc(100% - var(--inner-audit-left-padding) - var(--inner-audit-right-padding));
+ width: 100%;
}
.lh-details.flex .lh-code {
@@ -288,7 +302,6 @@
.lh-audit__header {
display: flex;
padding: var(--lh-audit-vpadding) var(--text-indent);
- cursor: pointer;
}
.lh-audit--load-opportunity .lh-audit__header {
@@ -307,17 +320,39 @@
/* Perf Metric */
-.lh-metric-container {
+.lh-columns {
display: flex;
+ width: 100%;
+}
+@media screen and (max-width: 640px) {
+ .lh-columns {
+ flex-wrap: wrap;
+
+ }
}
-.lh-metric-column {
+.lh-column {
flex: 1;
}
-.lh-metric-column:first-of-type {
- margin-right: 20px;
+.lh-column:first-of-type {
+ margin-right: 24px;
}
+@media screen and (max-width: 800px) {
+ .lh-column:first-of-type {
+ margin-right: 8px;
+ }
+}
+@media screen and (max-width: 640px) {
+ .lh-column {
+ flex-basis: 100%;
+ }
+ .lh-column:first-of-type {
+ margin-right: 0px;
+ }
+}
+
+
.lh-metric {
border-bottom: 1px solid var(--report-secondary-border-color);
}
@@ -336,6 +371,7 @@
font-size: var(--body-font-size);
line-height: var(--body-line-height);
display: flex;
+ white-space: nowrap;
}
.lh-metric__name {
@@ -378,6 +414,7 @@
.lh-metric--average .lh-metric__value {
color: var(--average-color);
+ padding-left: 16px;
}
.lh-metric--average .lh-metric__value::after {
background: var(--average-icon-url) no-repeat 50% 50%;
@@ -470,10 +507,10 @@
.lh-filmstrip-container {
padding: 0 var(--expandable-indent);
- margin: 0 auto;
+ /* smaller gap between metrics and filmstrip */
+ margin: -16px auto 0 auto;
}
-
.lh-filmstrip {
display: flex;
flex-direction: row;
@@ -492,16 +529,22 @@
max-width: 60px;
}
+@media screen and (max-width: 750px) {
+ .lh-filmstrip {
+ flex-wrap: wrap;
+ justify-content: left;
+ }
+ .lh-filmstrip__frame {
+ margin: calc(var(--default-padding) / 3);
+ }
+}
+
/* Audit */
.lh-audit {
border-bottom: 1px solid var(--report-secondary-border-color);
}
-.lh-audit:last-child {
- border-bottom: none;
-}
-
.lh-audit--error .lh-audit__display-text {
color: var(--fail-color);
}
@@ -509,12 +552,7 @@
/* Audit Group */
.lh-audit-group {
- padding: var(--lh-audit-group-vpadding) 0;
- border-bottom: 1px solid var(--report-secondary-border-color);
-}
-
-.lh-audit-group:last-child {
- border-bottom: none;
+ margin: var(--lh-audit-group-vpadding) 0;
}
.lh-audit-group__header {
@@ -549,7 +587,7 @@
background-image: var(--check-icon-url);
}
.lh-audit-group--diagnostics .lh-audit-group__header::before {
- background-image: var(--search-icon-url);
+ background-image: var(--content-paste-icon-url);
}
.lh-audit-group--opportunities .lh-audit-group__header::before {
background-image: var(--photo-filter-icon-url);
@@ -563,7 +601,7 @@
/* Removing too much whitespace */
.lh-audit-group--metrics {
- margin-top: -28px;
+ margin-top: calc(var(--circle-size)/2 * -1);
border-bottom: none;
}
@@ -575,7 +613,10 @@
.lh-audit-group__itemcount {
color: var(--display-value-gray);
- margin: 0 10px;
+ margin: 3px 10px 0;
+}
+.lh-audit-group__summary .lh-chevron {
+ margin-top: calc((var(--body-line-height) - 5px) / 2);
}
.lh-audit-group__description {
@@ -601,7 +642,7 @@
.lh-container {
display: flex;
- max-width: var(--report-content-width);
+ max-width: var(--report-width);
word-wrap: break-word;
margin: 0 auto;
}
@@ -620,7 +661,7 @@
.lh-header-container {
display: block;
margin: 0 auto;
- max-width: var(--report-content-width);
+ max-width: var(--report-width);
position: relative;
word-wrap: break-word;
}
@@ -672,7 +713,7 @@
.lh-scores-header {
display: flex;
- justify-content: center;
+ justify-content: left;
overflow-x: hidden;
position: relative;
padding: var(--section-indent) calc(var(--section-indent) / 2) calc(var(--section-indent) * 2);
@@ -682,6 +723,10 @@
border: 0;
}
+.lh-scores-header .lh-gauge__wrapper {
+ margin: 0 4px;
+}
+
.lh-scorescale {
color: var(--medium-75-gray);
padding: 0 calc(var(--section-indent) * 1.5) 0;
@@ -692,6 +737,7 @@
.lh-scorescale-range {
margin-left: 10px;
+ white-space: nowrap;
}
.lh-scorescale-range::before {
@@ -728,9 +774,7 @@
.lh-category {
--circle-size: calc(2.5 * var(--header-font-size));
-
padding: var(--section-padding);
- border-top: 1px solid var(--report-border-color);
}
.lh-category:first-of-type {
@@ -767,7 +811,7 @@
float: right;
}
-.lh-category .lh-score__gauge {
+.lh-category-header .lh-score__gauge {
margin-left: var(--section-indent);
}
@@ -862,19 +906,28 @@
padding: 8px 6px;
}
+/* Looks unnecessary, but mostly for keeping the <th>s left-aligned */
.lh-table-column--text,
+.lh-table-column--url,
+/* .lh-table-column--thumbnail, */
+/* .lh-table-column--empty,*/
+.lh-table-column--code,
+.lh-table-column--node {
+ text-align: left;
+}
+
.lh-table-column--bytes,
.lh-table-column--timespanMs,
.lh-table-column--ms {
text-align: right;
}
+
.lh-table-column--thumbnail {
width: calc(var(--image-preview-size) * 2);
}
.lh-table-column--url {
- text-align: left;
min-width: 250px;
white-space: nowrap;
max-width: 0;
@@ -882,8 +935,9 @@
/* Keep bytes columns narrow if they follow the URL column */
.lh-table-column--url + th.lh-table-column--bytes,
-.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--bytes {
- width: var(--bytes-col-width);
+.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--bytes,
+.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--timespanMs {
+ max-width: var(--bytes-col-width);
}
.lh-table-column--code {
diff --git a/front_end/audits2/lighthouse/templates.html b/front_end/audits2/lighthouse/templates.html
index 770432f..29e93cb 100644
--- a/front_end/audits2/lighthouse/templates.html
+++ b/front_end/audits2/lighthouse/templates.html
@@ -1,7 +1,24 @@
+<!--
+@license
+Copyright 2018 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS-IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
<!-- Lighthouse run warnings -->
<template id="tmpl-lh-warnings--toplevel">
<div class="lh-warnings lh-warnings--toplevel">
- <strong>There were issues affecting this run of Lighthouse:</strong>
+ <strong class="lh-warnings__msg"></strong>
<ul></ul>
</div>
</template>
@@ -9,10 +26,10 @@
<!-- Lighthouse score scale -->
<template id="tmpl-lh-scorescale">
<div class="lh-scorescale">
- <span class="lh-scorescale-label">Score scale:</span>
- <span class="lh-scorescale-range lh-scorescale-range--fail">0-44</span>
- <span class="lh-scorescale-range lh-scorescale-range--average">45-74</span>
- <span class="lh-scorescale-range lh-scorescale-range--pass">75-100</span>
+ <span class="lh-scorescale-label"></span>
+ <span class="lh-scorescale-range lh-scorescale-range--fail">0-49</span>
+ <span class="lh-scorescale-range lh-scorescale-range--average">50-89</span>
+ <span class="lh-scorescale-range lh-scorescale-range--pass">90-100</span>
</div>
</template>
@@ -90,12 +107,8 @@
<!-- Lighthouse perf opportunity header -->
<template id="tmpl-lh-opportunity-header">
<div class="lh-load-opportunity__header lh-load-opportunity__cols">
- <div class="lh-load-opportunity__col lh-load-opportunity__col--one">
- Resource to optimize
- </div>
- <div class="lh-load-opportunity__col lh-load-opportunity__col--two">
- Estimated Savings
- </div>
+ <div class="lh-load-opportunity__col lh-load-opportunity__col--one"></div>
+ <div class="lh-load-opportunity__col lh-load-opportunity__col--two"></div>
</div>
</template>
@@ -151,7 +164,7 @@
position: absolute;
top: var(--report-header-height);
right: 50%;
- transform: translate3d(calc(var(--report-content-width) / 2), -100%, 0);
+ transform: translate3d(calc(var(--report-width) / 2), -100%, 0);
opacity: 1;
transform-origin: bottom right;
will-change: transform, opacity;
@@ -394,6 +407,7 @@
<div class="lh-export">
<button class="report-icon report-icon--share lh-export__button" title="Export report"></button>
<div class="lh-export__dropdown">
+ <!-- TODO(i18n): localize export dropdown -->
<a href="#" class="report-icon report-icon--print" data-action="print-summary">Print Summary</a>
<a href="#" class="report-icon report-icon--print" data-action="print-expanded">Print Expanded</a>
<a href="#" class="report-icon report-icon--copy" data-action="copy">Copy JSON</a>
@@ -436,6 +450,7 @@
}
</style>
<footer class="lh-footer">
+ <!-- TODO(i18n): localize runtime settings -->
<div class="lh-env">
<div class="lh-env__title">Runtime settings</div>
<ul class="lh-env__items">
@@ -512,11 +527,12 @@
.lh-gauge__percentage {
--spacer: calc((var(--circle-size) - var(--inset-size)) / 2);
- width: var(--inset-size);
+ width: 100%;
height: var(--inset-size);
position: absolute;
border-radius: inherit;
font-size: var(--header-font-size);
+ line-height: var(--header-font-size);
text-align: center;
top: calc(var(--circle-size) / 3);
}
@@ -603,14 +619,17 @@
color: #595959;
font-style: italic;
}
+ .lh-crc__summary-value {
+ margin-bottom: 10px;
+ }
</style>
<div>
- Longest chain: <b class="lh-crc__longest_duration"><!-- fill me: longestChain.duration --></b>
- over <b class="lh-crc__longest_length"><!-- fill me: longestChain.length --></b> requests, totalling
- <b class="lh-crc__longest_transfersize"><!-- fill me: longestChain.length --></b>
+ <div class="lh-crc__summary-value">
+ <span class="lh-crc__longest_duration_label"></span> <b class="lh-crc__longest_duration"></b>
+ </div>
</div>
<div class="lh-crc">
- <div class="crc-initial-nav">Initial Navigation</div>
+ <div class="crc-initial-nav"></div>
<!-- stamp for each chain -->
<template id="tmpl-lh-crc__chains">
<div class="crc-node">