lighthouse 8.6.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/report/bundle.esm.js +5994 -0
- package/dist/report/flow.js +30 -13
- package/dist/report/standalone.js +41 -35
- package/flow-report/.eslintrc.cjs +2 -0
- package/flow-report/assets/standalone-flow-template.html +3 -2
- package/flow-report/assets/styles.css +108 -31
- package/flow-report/src/app.tsx +18 -18
- package/flow-report/src/common.tsx +28 -15
- package/flow-report/src/header.tsx +12 -13
- package/flow-report/src/help-dialog.tsx +3 -4
- package/flow-report/src/i18n/i18n.tsx +57 -16
- package/flow-report/src/i18n/ui-strings.js +50 -0
- package/flow-report/src/icons.tsx +36 -8
- package/flow-report/src/sidebar/flow.tsx +3 -3
- package/flow-report/src/sidebar/sidebar.tsx +35 -14
- package/flow-report/src/summary/category.tsx +97 -24
- package/flow-report/src/summary/summary.tsx +21 -14
- package/flow-report/src/topbar.tsx +9 -5
- package/flow-report/src/util.ts +33 -26
- package/flow-report/src/wrappers/category-score.tsx +0 -3
- package/flow-report/src/wrappers/markdown.tsx +27 -0
- package/flow-report/src/wrappers/report-renderer.tsx +10 -3
- package/flow-report/src/wrappers/report.tsx +27 -6
- package/flow-report/standalone-flow.tsx +4 -3
- package/flow-report/test/common-test.tsx +32 -17
- package/flow-report/test/flow-report-pptr-test.ts +46 -0
- package/flow-report/test/header-test.tsx +6 -6
- package/flow-report/test/setup/env-setup.ts +1 -1
- package/flow-report/test/sidebar/sidebar-test.tsx +43 -1
- package/flow-report/test/summary/category-test.tsx +120 -24
- package/flow-report/test/summary/summary-test.tsx +1 -1
- package/flow-report/test/topbar-test.tsx +1 -0
- package/flow-report/test/util-test.tsx +32 -11
- package/flow-report/test/wrappers/category-score-test.tsx +87 -0
- package/flow-report/test/wrappers/markdown-test.tsx +29 -0
- package/flow-report/tsconfig.json +1 -0
- package/jest.config.js +4 -2
- package/lighthouse-cli/.eslintrc.cjs +2 -0
- package/lighthouse-cli/cli-flags.js +1 -1
- package/lighthouse-cli/run.js +1 -1
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +0 -0
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +4 -2
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +1 -1
- package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
- package/lighthouse-core/audits/accessibility/axe-audit.js +7 -1
- package/lighthouse-core/audits/audit.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +2 -0
- package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +4 -2
- package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +11 -10
- package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +5 -3
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +2 -1
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +2 -1
- package/lighthouse-core/audits/deprecations.js +33 -11
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +27 -11
- package/lighthouse-core/audits/errors-in-console.js +0 -2
- package/lighthouse-core/audits/image-aspect-ratio.js +5 -5
- package/lighthouse-core/audits/image-size-responsive.js +6 -6
- package/lighthouse-core/audits/installable-manifest.js +5 -3
- package/lighthouse-core/audits/preload-lcp-image.js +7 -5
- package/lighthouse-core/audits/script-treemap-data.js +1 -1
- package/lighthouse-core/audits/unsized-images.js +2 -3
- package/lighthouse-core/computed/image-records.js +4 -3
- package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +3 -4
- package/lighthouse-core/computed/metrics/tbt-utils.js +57 -0
- package/lighthouse-core/computed/metrics/total-blocking-time.js +3 -53
- package/lighthouse-core/computed/resource-summary.js +1 -1
- package/lighthouse-core/config/config-helpers.js +21 -10
- package/lighthouse-core/config/constants.js +3 -4
- package/lighthouse-core/config/default-config.js +61 -71
- package/lighthouse-core/fraggle-rock/config/config.js +1 -1
- package/lighthouse-core/fraggle-rock/config/default-config.js +4 -5
- package/lighthouse-core/fraggle-rock/gather/base-gatherer.js +6 -1
- package/lighthouse-core/fraggle-rock/gather/session.js +3 -4
- package/lighthouse-core/gather/connections/cri.js +1 -1
- package/lighthouse-core/gather/driver/storage.js +0 -1
- package/lighthouse-core/gather/driver.js +3 -7
- package/lighthouse-core/gather/fetcher.js +4 -7
- package/lighthouse-core/gather/gather-runner.js +29 -6
- package/lighthouse-core/gather/gatherers/accessibility.js +27 -0
- package/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js +1 -0
- package/lighthouse-core/gather/gatherers/image-elements.js +0 -3
- package/lighthouse-core/gather/gatherers/inspector-issues.js +5 -0
- package/lighthouse-core/lib/asset-saver.js +7 -4
- package/lighthouse-core/lib/emulation.js +45 -1
- package/lighthouse-core/lib/i18n/i18n.js +19 -8
- package/lighthouse-core/lib/lh-env.js +2 -0
- package/lighthouse-core/lib/proto-preprocessor.js +14 -2
- package/lighthouse-core/lib/tappable-rects.js +8 -15
- package/lighthouse-core/lib/url-shim.js +1 -1
- package/lighthouse-core/runner.js +1 -1
- package/lighthouse-core/util-commonjs.js +65 -46
- package/package.json +27 -17
- package/readme.md +3 -3
- package/report/.eslintrc.cjs +2 -0
- package/report/README.md +1 -1
- package/report/assets/standalone-template.html +2 -3
- package/report/assets/styles.css +360 -254
- package/report/assets/templates.html +21 -76
- package/report/clients/bundle.js +1 -0
- package/report/clients/standalone.js +6 -15
- package/report/generator/README.md +1 -1
- package/report/renderer/api.js +32 -0
- package/report/renderer/category-renderer.js +59 -19
- package/report/renderer/components.js +59 -110
- package/report/renderer/crc-details-renderer.js +15 -12
- package/report/renderer/dom.js +16 -1
- package/report/renderer/drop-down-menu.js +2 -2
- package/report/renderer/element-screenshot-renderer.js +8 -8
- package/report/renderer/features-util.js +1 -1
- package/report/renderer/open-tab.js +9 -3
- package/report/renderer/performance-category-renderer.js +55 -34
- package/report/renderer/pwa-category-renderer.js +0 -10
- package/report/renderer/report-renderer.js +91 -44
- package/report/renderer/report-ui-features.js +36 -33
- package/report/renderer/swap-locale-feature.js +3 -3
- package/report/renderer/topbar-features.js +53 -48
- package/report/renderer/util.js +66 -46
- package/report/test/clients/bundle-test.js +70 -0
- package/report/test/renderer/category-renderer-test.js +48 -3
- package/report/test/renderer/i18n-test.js +0 -7
- package/report/test/renderer/performance-category-renderer-test.js +51 -14
- package/report/test/renderer/pwa-category-renderer-test.js +6 -6
- package/report/test/renderer/report-renderer-axe-test.js +10 -12
- package/report/test/renderer/report-renderer-test.js +23 -22
- package/report/test/renderer/report-ui-features-test.js +20 -10
- package/report/test/renderer/text-encoding-test.js +1 -1
- package/report/test/renderer/util-test.js +35 -31
- package/report/test-assets/faux-psi-template.html +3 -11
- package/report/test-assets/faux-psi.js +26 -22
- package/report/types/html-renderer.d.ts +2 -0
- package/report/types/report-renderer.d.ts +23 -0
- package/shared/localization/format.js +64 -30
- package/shared/localization/locales/ar-XB.json +72 -75
- package/shared/localization/locales/ar.json +72 -75
- package/shared/localization/locales/bg.json +72 -75
- package/shared/localization/locales/ca.json +72 -75
- package/shared/localization/locales/cs.json +89 -92
- package/shared/localization/locales/da.json +72 -75
- package/shared/localization/locales/de.json +89 -92
- package/shared/localization/locales/el.json +72 -75
- package/shared/localization/locales/en-GB.json +72 -75
- package/shared/localization/locales/en-US.json +75 -75
- package/shared/localization/locales/en-XA.json +72 -75
- package/shared/localization/locales/en-XL.json +75 -75
- package/shared/localization/locales/es-419.json +90 -93
- package/shared/localization/locales/es.json +90 -93
- package/shared/localization/locales/fi.json +72 -75
- package/shared/localization/locales/fil.json +72 -75
- package/shared/localization/locales/fr.json +89 -92
- package/shared/localization/locales/he.json +73 -76
- package/shared/localization/locales/hi.json +72 -75
- package/shared/localization/locales/hr.json +72 -75
- package/shared/localization/locales/hu.json +89 -92
- package/shared/localization/locales/id.json +89 -92
- package/shared/localization/locales/it.json +89 -92
- package/shared/localization/locales/ja.json +89 -92
- package/shared/localization/locales/ko.json +89 -92
- package/shared/localization/locales/lt.json +89 -92
- package/shared/localization/locales/lv.json +95 -98
- package/shared/localization/locales/nl.json +89 -92
- package/shared/localization/locales/no.json +72 -75
- package/shared/localization/locales/pl.json +72 -75
- package/shared/localization/locales/pt-PT.json +72 -75
- package/shared/localization/locales/pt.json +89 -92
- package/shared/localization/locales/ro.json +90 -93
- package/shared/localization/locales/ru.json +89 -92
- package/shared/localization/locales/sk.json +89 -92
- package/shared/localization/locales/sl.json +89 -92
- package/shared/localization/locales/sr-Latn.json +89 -92
- package/shared/localization/locales/sr.json +89 -92
- package/shared/localization/locales/sv.json +72 -75
- package/shared/localization/locales/ta.json +89 -92
- package/shared/localization/locales/te.json +89 -92
- package/shared/localization/locales/th.json +89 -92
- package/shared/localization/locales/tr.json +89 -92
- package/shared/localization/locales/uk.json +92 -95
- package/shared/localization/locales/vi.json +89 -92
- package/shared/localization/locales/zh-HK.json +89 -92
- package/shared/localization/locales/zh-TW.json +89 -92
- package/shared/localization/locales/zh.json +89 -92
- package/shared/localization/locales.js +6 -0
- package/shared/test/localization/format-test.js +45 -9
- package/shared/test/localization/swap-locale-test.js +0 -12
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +19 -11
- package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
- package/third-party/download-content-shell/download-content-shell.js +2 -2
- package/third-party/download-content-shell/utils.js +0 -24
- package/tsconfig-all.json +2 -2
- package/tsconfig.json +0 -1
- package/types/artifacts.d.ts +7 -7
- package/types/enquirer.d.ts +3 -1
- package/types/lhr/audit-details.d.ts +6 -5
- package/types/lhr/flow.d.ts +3 -2
- package/types/lhr/lhr.d.ts +1 -1
- package/types/node.d.ts +5 -5
- package/types/rollup-plugin-postprocess.d.ts +10 -0
- package/changelog.md +0 -5490
- package/lighthouse-core/audits/dobetterweb/appcache-manifest.js +0 -67
- package/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js +0 -96
- package/lighthouse-core/audits/redirects-http.js +0 -59
- package/lighthouse-core/gather/gatherers/dobetterweb/appcache.js +0 -34
- package/lighthouse-core/gather/gatherers/http-redirect.js +0 -46
- package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +0 -6699
- package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +0 -6672
- package/lighthouse-core/scripts/package.json +0 -4
- package/report/clients/psi.js +0 -158
- package/report/test/clients/psi-test.js +0 -143
- package/shared/localization/locales/en-US.ctc.json +0 -6877
- package/shared/localization/locales/en-XL.ctc.json +0 -6852
|
@@ -155,6 +155,28 @@ describe('util helpers', () => {
|
|
|
155
155
|
const preparedResult = Util.prepareReportResult(clonedSampleResult);
|
|
156
156
|
assert.deepStrictEqual(preparedResult.audits, sampleResult.audits);
|
|
157
157
|
});
|
|
158
|
+
|
|
159
|
+
it('corrects performance category without hidden group', () => {
|
|
160
|
+
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
|
|
161
|
+
|
|
162
|
+
clonedSampleResult.lighthouseVersion = '8.6.0';
|
|
163
|
+
delete clonedSampleResult.categoryGroups['hidden'];
|
|
164
|
+
for (const auditRef of clonedSampleResult.categories['performance'].auditRefs) {
|
|
165
|
+
if (auditRef.group === 'hidden') {
|
|
166
|
+
delete auditRef.group;
|
|
167
|
+
} else if (!auditRef.group) {
|
|
168
|
+
auditRef.group = 'diagnostics';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
assert.notDeepStrictEqual(clonedSampleResult.categories, sampleResult.categories);
|
|
172
|
+
assert.notDeepStrictEqual(clonedSampleResult.categoryGroups, sampleResult.categoryGroups);
|
|
173
|
+
|
|
174
|
+
// Original audit results should be restored.
|
|
175
|
+
const clonedPreparedResult = Util.prepareReportResult(clonedSampleResult);
|
|
176
|
+
const preparedResult = Util.prepareReportResult(sampleResult);
|
|
177
|
+
assert.deepStrictEqual(clonedPreparedResult.categories, preparedResult.categories);
|
|
178
|
+
assert.deepStrictEqual(clonedPreparedResult.categoryGroups, preparedResult.categoryGroups);
|
|
179
|
+
});
|
|
158
180
|
});
|
|
159
181
|
|
|
160
182
|
it('appends stack pack descriptions to auditRefs', () => {
|
|
@@ -401,10 +423,10 @@ describe('util helpers', () => {
|
|
|
401
423
|
const category = {
|
|
402
424
|
id: 'performance',
|
|
403
425
|
auditRefs: [
|
|
404
|
-
{weight: 3, result: {score: 1, scoreDisplayMode: 'binary'}, group: '
|
|
405
|
-
{weight: 2, result: {score: 1, scoreDisplayMode: 'binary'}, group: '
|
|
406
|
-
{weight: 0, result: {score: 1, scoreDisplayMode: 'binary'}, group: '
|
|
407
|
-
{weight: 1, result: {score: 0, scoreDisplayMode: 'binary'}, group: '
|
|
426
|
+
{weight: 3, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'metrics'},
|
|
427
|
+
{weight: 2, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'metrics'},
|
|
428
|
+
{weight: 0, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'metrics'},
|
|
429
|
+
{weight: 1, result: {score: 0, scoreDisplayMode: 'binary'}, group: 'metrics'},
|
|
408
430
|
],
|
|
409
431
|
};
|
|
410
432
|
const fraction = Util.calculateCategoryFraction(category);
|
|
@@ -416,14 +438,14 @@ describe('util helpers', () => {
|
|
|
416
438
|
});
|
|
417
439
|
});
|
|
418
440
|
|
|
419
|
-
it('ignores manual audits, N/A audits, and
|
|
441
|
+
it('ignores manual audits, N/A audits, and hidden audits', () => {
|
|
420
442
|
const category = {
|
|
421
443
|
id: 'performance',
|
|
422
444
|
auditRefs: [
|
|
423
|
-
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: '
|
|
424
|
-
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}},
|
|
425
|
-
{weight: 1, result: {score: 0, scoreDisplayMode: 'manual'}, group: '
|
|
426
|
-
{weight: 1, result: {score: 0, scoreDisplayMode: 'notApplicable'}, group: '
|
|
445
|
+
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'metrics'},
|
|
446
|
+
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'hidden'},
|
|
447
|
+
{weight: 1, result: {score: 0, scoreDisplayMode: 'manual'}, group: 'metrics'},
|
|
448
|
+
{weight: 1, result: {score: 0, scoreDisplayMode: 'notApplicable'}, group: 'metrics'},
|
|
427
449
|
],
|
|
428
450
|
};
|
|
429
451
|
const fraction = Util.calculateCategoryFraction(category);
|
|
@@ -435,32 +457,14 @@ describe('util helpers', () => {
|
|
|
435
457
|
});
|
|
436
458
|
});
|
|
437
459
|
|
|
438
|
-
it('does not ignore audits with no group in non-performance category', () => {
|
|
439
|
-
const category = {
|
|
440
|
-
id: 'seo',
|
|
441
|
-
auditRefs: [
|
|
442
|
-
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
|
|
443
|
-
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}},
|
|
444
|
-
{weight: 1, result: {score: 0, scoreDisplayMode: 'manual'}, group: 'diagnostics'},
|
|
445
|
-
],
|
|
446
|
-
};
|
|
447
|
-
const fraction = Util.calculateCategoryFraction(category);
|
|
448
|
-
expect(fraction).toEqual({
|
|
449
|
-
numPassableAudits: 2,
|
|
450
|
-
numPassed: 2,
|
|
451
|
-
numInformative: 0,
|
|
452
|
-
totalWeight: 2,
|
|
453
|
-
});
|
|
454
|
-
});
|
|
455
|
-
|
|
456
460
|
it('tracks informative audits separately', () => {
|
|
457
461
|
const category = {
|
|
458
462
|
id: 'performance',
|
|
459
463
|
auditRefs: [
|
|
460
|
-
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: '
|
|
461
|
-
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: '
|
|
462
|
-
{weight: 0, result: {score: 1, scoreDisplayMode: 'informative'}, group: '
|
|
463
|
-
{weight: 1, result: {score: 0, scoreDisplayMode: 'informative'}, group: '
|
|
464
|
+
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'metrics'},
|
|
465
|
+
{weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'metrics'},
|
|
466
|
+
{weight: 0, result: {score: 1, scoreDisplayMode: 'informative'}, group: 'metrics'},
|
|
467
|
+
{weight: 1, result: {score: 0, scoreDisplayMode: 'informative'}, group: 'metrics'},
|
|
464
468
|
],
|
|
465
469
|
};
|
|
466
470
|
const fraction = Util.calculateCategoryFraction(category);
|
|
@@ -66,7 +66,6 @@
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
.tab-panel {
|
|
69
|
-
padding: 30px 0;
|
|
70
69
|
border-top: 1px solid #ccc;
|
|
71
70
|
}
|
|
72
71
|
|
|
@@ -92,10 +91,7 @@ body {
|
|
|
92
91
|
<body >
|
|
93
92
|
<noscript>PSI requires JavaScript. Please enable.</noscript>
|
|
94
93
|
|
|
95
|
-
<div class="
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<div class="tabset lh-vars lh-root">
|
|
94
|
+
<div class="tabset">
|
|
99
95
|
|
|
100
96
|
<input type="radio" name="tabset" id="tab1" aria-controls="mobile" checked>
|
|
101
97
|
<label for="tab1">Mobile</label>
|
|
@@ -104,13 +100,9 @@ body {
|
|
|
104
100
|
<label for="tab2">Desktop</label>
|
|
105
101
|
|
|
106
102
|
<div class="tab-panels">
|
|
107
|
-
<section id="mobile" class="tab-panel">
|
|
108
|
-
<main></main>
|
|
109
|
-
</section>
|
|
103
|
+
<section id="mobile" class="tab-panel"></section>
|
|
110
104
|
|
|
111
|
-
<section id="desktop" class="tab-panel">
|
|
112
|
-
<main></main>
|
|
113
|
-
</section>
|
|
105
|
+
<section id="desktop" class="tab-panel"></section>
|
|
114
106
|
|
|
115
107
|
</div>
|
|
116
108
|
</div>
|
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
/** @fileoverview This file
|
|
8
|
+
/** @fileoverview This file exercises two LH reports within the same DOM. */
|
|
9
9
|
|
|
10
|
-
/** @typedef {import('../clients/
|
|
10
|
+
/** @typedef {import('../clients/bundle.js')} lighthouseRenderer */
|
|
11
|
+
|
|
12
|
+
/** @type {lighthouseRenderer} */
|
|
13
|
+
// @ts-expect-error
|
|
14
|
+
const lighthouseRenderer = window['report'];
|
|
11
15
|
|
|
12
16
|
(async function __initPsiReports__() {
|
|
13
17
|
// @ts-expect-error
|
|
@@ -22,22 +26,23 @@
|
|
|
22
26
|
for (const [tabId, lhr] of Object.entries(lhrs)) {
|
|
23
27
|
await distinguishLHR(lhr, tabId);
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
const pldd = /** @type {PrepareLabDataResult} */ (window.prepareLabData(lhr, document));
|
|
27
|
-
const {scoreGaugeEl, perfCategoryEl,
|
|
28
|
-
finalScreenshotDataUri, scoreScaleEl, installFeatures} = pldd;
|
|
29
|
-
|
|
30
|
-
const container = document.querySelector(`#${tabId} main`);
|
|
29
|
+
const container = document.querySelector(`section#${tabId}`);
|
|
31
30
|
if (!container) throw new Error('Unexpected DOM. Bailing.');
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const reportRootEl = lighthouseRenderer.renderReport(lhr, {
|
|
34
|
+
omitTopbar: true,
|
|
35
|
+
disableAutoDarkModeAndFireworks: true,
|
|
36
|
+
});
|
|
37
|
+
// TODO: display warnings if appropriate.
|
|
38
|
+
for (const el of reportRootEl.querySelectorAll('.lh-warnings')) {
|
|
39
|
+
el.setAttribute('hidden', 'true');
|
|
40
|
+
}
|
|
41
|
+
container.append(reportRootEl);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.error(e);
|
|
44
|
+
container.textContent = 'Error: LHR failed to render.';
|
|
38
45
|
}
|
|
39
|
-
container.append(perfCategoryEl);
|
|
40
|
-
installFeatures(container);
|
|
41
46
|
}
|
|
42
47
|
})();
|
|
43
48
|
|
|
@@ -49,7 +54,6 @@
|
|
|
49
54
|
* @param {string} tabId
|
|
50
55
|
*/
|
|
51
56
|
async function distinguishLHR(lhr, tabId) {
|
|
52
|
-
lhr.categories.performance.title += ` ${tabId}`; // for easier identification
|
|
53
57
|
if (tabId === 'desktop') {
|
|
54
58
|
lhr.categories.performance.score = 0.81;
|
|
55
59
|
}
|
|
@@ -78,15 +82,15 @@ async function decorateScreenshot(datauri, tabId) {
|
|
|
78
82
|
img.src = datauri;
|
|
79
83
|
});
|
|
80
84
|
const c = document.createElement('canvas');
|
|
81
|
-
c.width = img.width;
|
|
82
|
-
c.height = img.height;
|
|
85
|
+
c.width = tabId === 'desktop' ? 280 : img.width;
|
|
86
|
+
c.height = tabId === 'desktop' ? 194 : img.height;
|
|
83
87
|
|
|
84
88
|
const ctx = c.getContext('2d');
|
|
85
89
|
if (!ctx) throw new Error();
|
|
86
|
-
ctx.drawImage(img, 0, 0);
|
|
87
|
-
ctx.font = `${
|
|
90
|
+
ctx.drawImage(img, 0, 0, c.width, c.height);
|
|
91
|
+
ctx.font = `${c.width / 2}px serif`;
|
|
88
92
|
ctx.textAlign = 'center';
|
|
89
93
|
ctx.globalAlpha = 0.7;
|
|
90
|
-
ctx.fillText(tabId === 'mobile' ? '📱' : '💻',
|
|
94
|
+
ctx.fillText(tabId === 'mobile' ? '📱' : '💻', c.width / 2, Math.min(c.height / 2, 700));
|
|
91
95
|
return c.toDataURL();
|
|
92
96
|
}
|
|
@@ -8,6 +8,7 @@ import AuditDetails from '../../types/lhr/audit-details';
|
|
|
8
8
|
import {FormattedIcu as FormattedIcu_, IcuMessage as IcuMessage_} from '../../types/lhr/i18n';
|
|
9
9
|
import LHResult from '../../types/lhr/lhr';
|
|
10
10
|
import ReportResult_ from './report-result';
|
|
11
|
+
import Renderer_ from './report-renderer';
|
|
11
12
|
import * as Settings from '../../types/lhr/settings';
|
|
12
13
|
import Treemap_ from '../../types/lhr/treemap';
|
|
13
14
|
|
|
@@ -16,6 +17,7 @@ declare global {
|
|
|
16
17
|
module LH {
|
|
17
18
|
export import Result = LHResult;
|
|
18
19
|
export import ReportResult = ReportResult_;
|
|
20
|
+
export import Renderer = Renderer_;
|
|
19
21
|
export import Locale = Settings.Locale;
|
|
20
22
|
export type IcuMessage = IcuMessage_;
|
|
21
23
|
export type FormattedIcu<T> = FormattedIcu_<T>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
+
* 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
|
|
4
|
+
* 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.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Result as AuditResult } from "../../types/lhr/audit-result";
|
|
8
|
+
|
|
9
|
+
declare module Renderer {
|
|
10
|
+
function renderReport(lhr: AuditResult, options?: Options): HTMLElement;
|
|
11
|
+
|
|
12
|
+
interface Options {
|
|
13
|
+
/**
|
|
14
|
+
* Don't automatically apply dark-mode to dark based on (prefers-color-scheme: dark). (DevTools and PSI don't want this.)
|
|
15
|
+
* Also, the fireworks easter-egg will want to flip to dark, so this setting will also disable chance of fireworks. */
|
|
16
|
+
disableAutoDarkModeAndFireworks?: boolean;
|
|
17
|
+
|
|
18
|
+
/** Disable the topbar UI component */
|
|
19
|
+
omitTopbar?: boolean;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default Renderer;
|
|
@@ -7,26 +7,26 @@
|
|
|
7
7
|
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
|
|
10
|
-
const MessageFormat = require('intl-messageformat')
|
|
10
|
+
const MessageFormat = require('intl-messageformat');
|
|
11
11
|
const {isObjectOfUnknownValues, isObjectOrArrayOfUnknownValues} = require('../type-verifiers.js');
|
|
12
12
|
|
|
13
13
|
/** Contains available locales with messages. May be an empty object if bundled. */
|
|
14
|
-
|
|
14
|
+
/** @type {import('./locales')} */
|
|
15
|
+
// @ts-expect-error TODO(esmodules): remove when file is es modules.
|
|
16
|
+
const LOCALE_MESSAGES = require('./locales.js').default || require('./locales.js');
|
|
17
|
+
|
|
18
|
+
const DEFAULT_LOCALE = 'en-US';
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* The locale tags for the localized messages available to Lighthouse on disk.
|
|
18
|
-
* When bundled, these will be inlined by
|
|
22
|
+
* When bundled, these will be inlined by `inline-fs`.
|
|
19
23
|
* These locales are considered the "canonical" locales. We support other locales which
|
|
20
24
|
* are simply aliases to one of these. ex: es-AR (alias) -> es-419 (canonical)
|
|
21
25
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.filter(basename => basename.endsWith('.json') && !basename.endsWith('.ctc.json'))
|
|
27
|
-
.map(locale => locale.replace('.json', ''))
|
|
28
|
-
.sort();
|
|
29
|
-
}
|
|
26
|
+
const CANONICAL_LOCALES = fs.readdirSync(__dirname + '/locales/')
|
|
27
|
+
.filter(basename => basename.endsWith('.json') && !basename.endsWith('.ctc.json'))
|
|
28
|
+
.map(locale => locale.replace('.json', ''))
|
|
29
|
+
.sort();
|
|
30
30
|
|
|
31
31
|
/** @typedef {import('intl-messageformat-parser').Element} MessageElement */
|
|
32
32
|
/** @typedef {import('intl-messageformat-parser').ArgumentElement} ArgumentElement */
|
|
@@ -95,7 +95,7 @@ function collectAllCustomElementsFromICU(icuElements, seenElementsById = new Map
|
|
|
95
95
|
* Returns a copy of the `values` object, with the values formatted based on how
|
|
96
96
|
* they will be used in their icuMessage, e.g. KB or milliseconds. The original
|
|
97
97
|
* object is unchanged.
|
|
98
|
-
* @param {MessageFormat} messageFormatter
|
|
98
|
+
* @param {MessageFormat.IntlMessageFormat} messageFormatter
|
|
99
99
|
* @param {Readonly<Record<string, string | number>>} values
|
|
100
100
|
* @param {string} lhlMessage Used for clear error logging.
|
|
101
101
|
* @return {Record<string, string | number>}
|
|
@@ -169,11 +169,14 @@ function _preformatValues(messageFormatter, values, lhlMessage) {
|
|
|
169
169
|
* @param {LH.Locale} locale
|
|
170
170
|
* @return {string}
|
|
171
171
|
*/
|
|
172
|
-
function
|
|
172
|
+
function formatMessage(message, values = {}, locale) {
|
|
173
173
|
// When using accented english, force the use of a different locale for number formatting.
|
|
174
174
|
const localeForMessageFormat = (locale === 'en-XA' || locale === 'en-XL') ? 'de-DE' : locale;
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
// This package is not correctly bundled by Rollup.
|
|
177
|
+
/** @type {typeof MessageFormat.IntlMessageFormat} */
|
|
178
|
+
const MessageFormatCtor = MessageFormat.IntlMessageFormat || MessageFormat;
|
|
179
|
+
const formatter = new MessageFormatCtor(message, localeForMessageFormat, formats);
|
|
177
180
|
|
|
178
181
|
// Preformat values for the message format like KB and milliseconds.
|
|
179
182
|
const valuesForMessageFormat = _preformatValues(formatter, values, message);
|
|
@@ -189,19 +192,21 @@ function _formatMessage(message, values = {}, locale) {
|
|
|
189
192
|
* @return {string}
|
|
190
193
|
*/
|
|
191
194
|
function _localizeIcuMessage(icuMessage, locale) {
|
|
192
|
-
const localeMessages =
|
|
193
|
-
if (!localeMessages) throw new Error(`Unsupported locale '${locale}'`);
|
|
195
|
+
const localeMessages = _getLocaleMessages(locale);
|
|
194
196
|
const localeMessage = localeMessages[icuMessage.i18nId];
|
|
195
197
|
|
|
196
|
-
//
|
|
197
|
-
// message in the specified locale.
|
|
198
|
-
//
|
|
199
|
-
//
|
|
198
|
+
// Use the DEFAULT_LOCALE fallback (usually the original english message) if we couldn't
|
|
199
|
+
// find a message in the specified locale. Possible reasons:
|
|
200
|
+
// - string drift between Lighthouse versions
|
|
201
|
+
// - in a bundle stripped of locale files but running in the DEFAULT_LOCALE
|
|
202
|
+
// - new strings haven't been updated yet in a local dev run
|
|
203
|
+
// Better to have an english message than no message at all; in some cases it
|
|
204
|
+
// won't even matter.
|
|
200
205
|
if (!localeMessage) {
|
|
201
206
|
return icuMessage.formattedDefault;
|
|
202
207
|
}
|
|
203
208
|
|
|
204
|
-
return
|
|
209
|
+
return formatMessage(localeMessage.message, icuMessage.values, locale);
|
|
205
210
|
}
|
|
206
211
|
|
|
207
212
|
/**
|
|
@@ -209,9 +214,10 @@ function _localizeIcuMessage(icuMessage, locale) {
|
|
|
209
214
|
* @return {Record<string, string>}
|
|
210
215
|
*/
|
|
211
216
|
function getRendererFormattedStrings(locale) {
|
|
212
|
-
const localeMessages =
|
|
213
|
-
if (!localeMessages) throw new Error(`Unsupported locale '${locale}'`);
|
|
217
|
+
const localeMessages = _getLocaleMessages(locale);
|
|
214
218
|
|
|
219
|
+
// If `localeMessages` is empty in the bundled and DEFAULT_LOCALE case, this
|
|
220
|
+
// will be empty and the report will fall back to the util UIStrings for these.
|
|
215
221
|
const icuMessageIds = Object.keys(localeMessages).filter(f => f.startsWith('report/'));
|
|
216
222
|
/** @type {Record<string, string>} */
|
|
217
223
|
const strings = {};
|
|
@@ -349,12 +355,38 @@ function replaceIcuMessages(inputObject, locale) {
|
|
|
349
355
|
return icuMessagePaths;
|
|
350
356
|
}
|
|
351
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Returns the locale messages for the given `locale`, if they exist.
|
|
360
|
+
* Throws if an unsupported locale.
|
|
361
|
+
*
|
|
362
|
+
* NOTE: If DEFAULT_LOCALE is requested and this is inside a bundle with locale
|
|
363
|
+
* messages stripped, an empty object will be returned. Default fallbacks will need to handle that case.
|
|
364
|
+
* @param {LH.Locale} locale
|
|
365
|
+
* @return {import('./locales').LhlMessages}
|
|
366
|
+
*/
|
|
367
|
+
function _getLocaleMessages(locale) {
|
|
368
|
+
const localeMessages = LOCALE_MESSAGES[locale];
|
|
369
|
+
if (!localeMessages) {
|
|
370
|
+
if (locale === DEFAULT_LOCALE) {
|
|
371
|
+
// If the default locale isn't in LOCALE_MESSAGES, this is likely executing
|
|
372
|
+
// in a bundle. Let the caller use the fallbacks available.
|
|
373
|
+
return {};
|
|
374
|
+
}
|
|
375
|
+
throw new Error(`Unsupported locale '${locale}'`);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return localeMessages;
|
|
379
|
+
}
|
|
380
|
+
|
|
352
381
|
/**
|
|
353
382
|
* Returns whether the `requestedLocale` can be used.
|
|
354
383
|
* @param {LH.Locale} requestedLocale
|
|
355
384
|
* @return {boolean}
|
|
356
385
|
*/
|
|
357
386
|
function hasLocale(requestedLocale) {
|
|
387
|
+
// The default locale is always supported through `IcuMessage.formattedDefault`.
|
|
388
|
+
if (requestedLocale === DEFAULT_LOCALE) return true;
|
|
389
|
+
|
|
358
390
|
const hasIntlSupport = Intl.NumberFormat.supportedLocalesOf([requestedLocale]).length > 0;
|
|
359
391
|
const hasMessages = Boolean(LOCALE_MESSAGES[requestedLocale]);
|
|
360
392
|
|
|
@@ -362,8 +394,9 @@ function hasLocale(requestedLocale) {
|
|
|
362
394
|
}
|
|
363
395
|
|
|
364
396
|
/**
|
|
365
|
-
* Returns a list of canonical locales
|
|
366
|
-
*
|
|
397
|
+
* Returns a list of canonical locales, as defined by the existent message files.
|
|
398
|
+
* In practice, each of these may have aliases in the full list returned by
|
|
399
|
+
* `getAvailableLocales()`.
|
|
367
400
|
* TODO: create a CanonicalLocale type
|
|
368
401
|
* @return {Array<string>}
|
|
369
402
|
*/
|
|
@@ -375,13 +408,13 @@ function getCanonicalLocales() {
|
|
|
375
408
|
* Returns a list of available locales.
|
|
376
409
|
* - if full build, this includes all canonical locales, aliases, and any locale added
|
|
377
410
|
* via `registerLocaleData`.
|
|
378
|
-
* - if bundled and locale messages have been stripped (locales.js shimmed), this includes
|
|
379
|
-
*
|
|
380
|
-
* from `registerLocaleData`.
|
|
411
|
+
* - if bundled and locale messages have been stripped (locales.js shimmed), this includes
|
|
412
|
+
* only DEFAULT_LOCALE and any locales from `registerLocaleData`.
|
|
381
413
|
* @return {Array<LH.Locale>}
|
|
382
414
|
*/
|
|
383
415
|
function getAvailableLocales() {
|
|
384
|
-
|
|
416
|
+
const localesWithMessages = new Set([...Object.keys(LOCALE_MESSAGES), DEFAULT_LOCALE]);
|
|
417
|
+
return /** @type {Array<LH.Locale>} */ ([...localesWithMessages].sort());
|
|
385
418
|
}
|
|
386
419
|
|
|
387
420
|
/**
|
|
@@ -407,6 +440,7 @@ function getIcuMessageIdParts(i18nMessageId) {
|
|
|
407
440
|
}
|
|
408
441
|
|
|
409
442
|
module.exports = {
|
|
443
|
+
DEFAULT_LOCALE,
|
|
410
444
|
_formatPathAsString,
|
|
411
445
|
collectAllCustomElementsFromICU,
|
|
412
446
|
isIcuMessage,
|
|
@@ -415,7 +449,7 @@ module.exports = {
|
|
|
415
449
|
replaceIcuMessages,
|
|
416
450
|
hasLocale,
|
|
417
451
|
registerLocaleData,
|
|
418
|
-
|
|
452
|
+
formatMessage,
|
|
419
453
|
getIcuMessageIdParts,
|
|
420
454
|
getAvailableLocales,
|
|
421
455
|
getCanonicalLocales,
|