lighthouse 8.6.0-dev.20211021 → 8.6.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/flow.js +13 -30
- package/dist/report/standalone.js +17 -17
- package/flow-report/assets/styles.css +30 -51
- package/flow-report/src/common.tsx +1 -1
- package/flow-report/src/header.tsx +2 -2
- package/flow-report/src/help-dialog.tsx +3 -3
- package/flow-report/src/i18n/i18n.tsx +13 -50
- package/flow-report/src/i18n/ui-strings.js +0 -48
- package/flow-report/src/icons.tsx +0 -7
- package/flow-report/src/sidebar/sidebar.tsx +6 -8
- package/flow-report/src/summary/category.tsx +18 -17
- package/flow-report/src/summary/summary.tsx +10 -10
- package/flow-report/src/topbar.tsx +5 -9
- package/flow-report/src/util.ts +5 -0
- package/flow-report/src/wrappers/category-score.tsx +3 -0
- package/flow-report/test/common-test.tsx +1 -1
- package/flow-report/test/summary/category-test.tsx +5 -9
- package/flow-report/test/summary/summary-test.tsx +1 -1
- package/flow-report/test/topbar-test.tsx +0 -1
- package/flow-report/tsconfig.json +0 -1
- package/jest.config.js +0 -1
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +1 -1
- package/lighthouse-core/audits/accessibility/axe-audit.js +1 -7
- package/lighthouse-core/audits/redirects-http.js +59 -0
- package/lighthouse-core/config/config-helpers.js +0 -1
- package/lighthouse-core/config/default-config.js +11 -0
- package/lighthouse-core/fraggle-rock/config/config.js +1 -1
- package/lighthouse-core/gather/gatherers/accessibility.js +0 -27
- package/lighthouse-core/gather/gatherers/http-redirect.js +46 -0
- package/lighthouse-core/lib/asset-saver.js +3 -3
- package/lighthouse-core/lib/i18n/i18n.js +8 -19
- package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +6699 -0
- package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +6672 -0
- package/lighthouse-core/util-commonjs.js +37 -25
- package/package.json +4 -8
- package/readme.md +3 -3
- package/report/assets/styles.css +28 -157
- package/report/assets/templates.html +47 -2
- package/report/clients/psi.js +158 -0
- package/report/renderer/category-renderer.js +1 -30
- package/report/renderer/components.js +34 -16
- package/report/renderer/performance-category-renderer.js +10 -5
- package/report/renderer/report-renderer.js +33 -56
- package/report/renderer/util.js +37 -25
- package/report/test/clients/psi-test.js +143 -0
- package/report/test/renderer/category-renderer-test.js +1 -5
- package/report/test/renderer/i18n-test.js +7 -0
- package/report/test/renderer/performance-category-renderer-test.js +1 -1
- package/report/test/renderer/pwa-category-renderer-test.js +2 -2
- package/report/test/renderer/report-renderer-axe-test.js +10 -5
- package/report/test/renderer/report-renderer-test.js +11 -9
- package/report/test-assets/faux-psi-template.html +4 -1
- package/report/test-assets/faux-psi.js +16 -39
- package/shared/localization/format.js +17 -50
- package/shared/localization/locales/ar-XB.json +24 -0
- package/shared/localization/locales/ar.json +24 -0
- package/shared/localization/locales/bg.json +24 -0
- package/shared/localization/locales/ca.json +24 -0
- package/shared/localization/locales/cs.json +24 -0
- package/shared/localization/locales/da.json +24 -0
- package/shared/localization/locales/de.json +24 -0
- package/shared/localization/locales/el.json +24 -0
- package/shared/localization/locales/en-GB.json +24 -0
- package/shared/localization/locales/en-US.ctc.json +6877 -0
- package/shared/localization/locales/en-US.json +23 -26
- package/shared/localization/locales/en-XA.json +24 -0
- package/shared/localization/locales/en-XL.ctc.json +6852 -0
- package/shared/localization/locales/en-XL.json +23 -26
- package/shared/localization/locales/es-419.json +24 -0
- package/shared/localization/locales/es.json +24 -0
- package/shared/localization/locales/fi.json +24 -0
- package/shared/localization/locales/fil.json +24 -0
- package/shared/localization/locales/fr.json +24 -0
- package/shared/localization/locales/he.json +24 -0
- package/shared/localization/locales/hi.json +24 -0
- package/shared/localization/locales/hr.json +24 -0
- package/shared/localization/locales/hu.json +24 -0
- package/shared/localization/locales/id.json +24 -0
- package/shared/localization/locales/it.json +24 -0
- package/shared/localization/locales/ja.json +24 -0
- package/shared/localization/locales/ko.json +24 -0
- package/shared/localization/locales/lt.json +24 -0
- package/shared/localization/locales/lv.json +24 -0
- package/shared/localization/locales/nl.json +24 -0
- package/shared/localization/locales/no.json +24 -0
- package/shared/localization/locales/pl.json +24 -0
- package/shared/localization/locales/pt-PT.json +24 -0
- package/shared/localization/locales/pt.json +24 -0
- package/shared/localization/locales/ro.json +24 -0
- package/shared/localization/locales/ru.json +24 -0
- package/shared/localization/locales/sk.json +24 -0
- package/shared/localization/locales/sl.json +24 -0
- package/shared/localization/locales/sr-Latn.json +24 -0
- package/shared/localization/locales/sr.json +24 -0
- package/shared/localization/locales/sv.json +24 -0
- package/shared/localization/locales/ta.json +24 -0
- package/shared/localization/locales/te.json +24 -0
- package/shared/localization/locales/th.json +24 -0
- package/shared/localization/locales/tr.json +24 -0
- package/shared/localization/locales/uk.json +24 -0
- package/shared/localization/locales/vi.json +24 -0
- package/shared/localization/locales/zh-HK.json +24 -0
- package/shared/localization/locales/zh-TW.json +24 -0
- package/shared/localization/locales/zh.json +24 -0
- package/shared/localization/locales.js +0 -6
- package/shared/test/localization/format-test.js +9 -45
- package/shared/test/localization/swap-locale-test.js +12 -0
- package/third-party/download-content-shell/download-content-shell.js +2 -2
- package/third-party/download-content-shell/utils.js +24 -0
- package/tsconfig.json +1 -0
- package/types/artifacts.d.ts +3 -1
- package/types/enquirer.d.ts +1 -3
- package/types/node.d.ts +5 -5
- package/flow-report/test/wrappers/category-score-test.tsx +0 -87
- package/report/test/clients/bundle-test.js +0 -62
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
.flow-vars {
|
|
8
8
|
--app-font-size: 12px;
|
|
9
9
|
--base-spacing: 16px;
|
|
10
|
-
--bold-weight: 500;
|
|
11
10
|
--category-summary-font-size: 18px;
|
|
12
11
|
--double-base-spacing: calc(var(--base-spacing) * 2);
|
|
13
12
|
--gather-mode-icon-size: 16px;
|
|
@@ -24,12 +23,10 @@
|
|
|
24
23
|
--sidebar-selected-bg-color: #DDEEFF;
|
|
25
24
|
--sidebar-summary-font-size: 14px;
|
|
26
25
|
--sidebar-title-font-size: 16px;
|
|
27
|
-
--sidebar-width:
|
|
28
|
-
--summary-flow-step-
|
|
29
|
-
--summary-
|
|
30
|
-
--summary-
|
|
31
|
-
--summary-subtitle-font-size: 12px;
|
|
32
|
-
--summary-title-font-size: 20px;
|
|
26
|
+
--sidebar-max-width: 400px;
|
|
27
|
+
--summary-flow-step-label-font-size: 16px;
|
|
28
|
+
--summary-subtitle-font-size: 16px;
|
|
29
|
+
--summary-title-font-size: 32px;
|
|
33
30
|
--summary-tooltip-box-shadow-color: rgba(0, 0, 0, 0.25);
|
|
34
31
|
--topbar-button-font-size: 14px;
|
|
35
32
|
--topbar-button-size: 45px;
|
|
@@ -117,18 +114,10 @@
|
|
|
117
114
|
|
|
118
115
|
.Topbar__title {
|
|
119
116
|
font-size: var(--topbar-title-font-size);
|
|
120
|
-
font-weight:
|
|
117
|
+
font-weight: bold;
|
|
121
118
|
margin-right: var(--double-base-spacing);
|
|
122
119
|
}
|
|
123
120
|
|
|
124
|
-
.Topbar__help-label {
|
|
125
|
-
display: flex;
|
|
126
|
-
align-items: center;
|
|
127
|
-
}
|
|
128
|
-
.Topbar__help-label > :first-child {
|
|
129
|
-
margin-right: var(--half-base-spacing);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
121
|
.Content {
|
|
133
122
|
grid-area: content;
|
|
134
123
|
overflow-y: auto;
|
|
@@ -159,19 +148,19 @@
|
|
|
159
148
|
.Sidebar {
|
|
160
149
|
grid-area: sidebar;
|
|
161
150
|
border-right: 1px solid var(--separator-color);
|
|
162
|
-
width:
|
|
151
|
+
width: min-content;
|
|
152
|
+
max-width: var(--sidebar-max-width);
|
|
163
153
|
overflow-x: hidden;
|
|
164
154
|
overflow-y: auto;
|
|
165
155
|
}
|
|
166
156
|
.Sidebar a {
|
|
167
|
-
color: var(--color-gray-
|
|
157
|
+
color: var(--color-gray-800);
|
|
168
158
|
text-decoration: none;
|
|
169
159
|
}
|
|
170
160
|
|
|
171
161
|
.Sidebar--current {
|
|
172
162
|
background-color: var(--sidebar-selected-bg-color);
|
|
173
163
|
color: var(--color-blue-A700) !important;
|
|
174
|
-
font-weight: var(--bold-weight);
|
|
175
164
|
}
|
|
176
165
|
|
|
177
166
|
.SidebarHeader {
|
|
@@ -179,7 +168,7 @@
|
|
|
179
168
|
}
|
|
180
169
|
.SidebarHeader__title {
|
|
181
170
|
font-size: var(--sidebar-title-font-size);
|
|
182
|
-
font-weight:
|
|
171
|
+
font-weight: bold;
|
|
183
172
|
width: max-content;
|
|
184
173
|
}
|
|
185
174
|
.SidebarHeader__date {
|
|
@@ -191,7 +180,6 @@
|
|
|
191
180
|
margin: var(--base-spacing);
|
|
192
181
|
padding: var(--half-base-spacing);
|
|
193
182
|
background-color: var(--color-gray-50);
|
|
194
|
-
color: var(--color-gray-700);
|
|
195
183
|
border-radius: 3px;
|
|
196
184
|
}
|
|
197
185
|
|
|
@@ -270,23 +258,21 @@
|
|
|
270
258
|
}
|
|
271
259
|
|
|
272
260
|
.SummaryHeader {
|
|
273
|
-
margin: var(--
|
|
261
|
+
margin: calc(var(--base-spacing) * 3) 0px;
|
|
262
|
+
width: 100%;
|
|
274
263
|
}
|
|
275
264
|
|
|
276
265
|
.SummaryHeader__title {
|
|
266
|
+
margin: var(--base-spacing) 0;
|
|
277
267
|
font-size: var(--summary-title-font-size);
|
|
278
|
-
font-weight: var(--bold-weight);
|
|
279
|
-
line-height: 28px;
|
|
280
|
-
margin: 0 0 calc(0.25 * var(--base-spacing));
|
|
281
268
|
}
|
|
282
269
|
|
|
283
270
|
.SummaryHeader__subtitle {
|
|
284
271
|
font-size: var(--summary-subtitle-font-size);
|
|
285
|
-
line-height: 16px;
|
|
286
272
|
}
|
|
287
273
|
|
|
288
274
|
.SummarySectionHeader {
|
|
289
|
-
margin-top: var(--base-spacing);
|
|
275
|
+
margin-top: var(--double-base-spacing);
|
|
290
276
|
}
|
|
291
277
|
|
|
292
278
|
.SummarySectionHeader__content {
|
|
@@ -295,15 +281,15 @@
|
|
|
295
281
|
}
|
|
296
282
|
|
|
297
283
|
.SummaryFlow {
|
|
284
|
+
width: 100%;
|
|
298
285
|
display: grid;
|
|
299
|
-
max-width: var(--report-width);
|
|
300
286
|
grid-auto-rows: min-content;
|
|
301
|
-
grid-template-columns: min-content min-content minmax(var(--min-text-width),
|
|
287
|
+
grid-template-columns: min-content min-content minmax(var(--min-text-width), 4fr) 1fr 1fr 1fr 1fr;
|
|
302
288
|
align-items: center;
|
|
303
289
|
margin: var(--base-spacing) 0px;
|
|
304
|
-
--gauge-circle-size: 48px;
|
|
305
290
|
}
|
|
306
291
|
.SummaryFlow .lh-fraction__content {
|
|
292
|
+
padding: 0px;
|
|
307
293
|
min-width: unset;
|
|
308
294
|
}
|
|
309
295
|
|
|
@@ -335,7 +321,7 @@
|
|
|
335
321
|
grid-column: 2;
|
|
336
322
|
}
|
|
337
323
|
.SummaryFlowStep .FlowStepThumbnail {
|
|
338
|
-
margin: var(--half-base-spacing);
|
|
324
|
+
margin: var(--base-spacing) var(--half-base-spacing);
|
|
339
325
|
}
|
|
340
326
|
|
|
341
327
|
.FlowStepThumbnail {
|
|
@@ -343,10 +329,7 @@
|
|
|
343
329
|
justify-self: center;
|
|
344
330
|
object-fit: cover;
|
|
345
331
|
object-position: top left;
|
|
346
|
-
border: 1px solid var(--color-gray
|
|
347
|
-
border-radius: 3px;
|
|
348
|
-
padding: 2px;
|
|
349
|
-
box-sizing: content-box !important;
|
|
332
|
+
border: 1px solid var(--color-gray);
|
|
350
333
|
}
|
|
351
334
|
|
|
352
335
|
.SummaryFlowStep__label {
|
|
@@ -358,13 +341,11 @@
|
|
|
358
341
|
}
|
|
359
342
|
|
|
360
343
|
.SummaryFlowStep__mode {
|
|
361
|
-
color: var(--color-
|
|
362
|
-
font-weight: var(--bold-weight);
|
|
344
|
+
color: var(--color-gray-700);
|
|
363
345
|
}
|
|
364
346
|
|
|
365
347
|
.SummaryFlowStep__link {
|
|
366
|
-
font-size: var(--summary-flow-step-
|
|
367
|
-
line-height: 20px;
|
|
348
|
+
font-size: var(--summary-flow-step-label-font-size);
|
|
368
349
|
color: var(--color-gray-800);
|
|
369
350
|
text-decoration: underline;
|
|
370
351
|
width: 100%;
|
|
@@ -373,6 +354,7 @@
|
|
|
373
354
|
|
|
374
355
|
.SummaryCategory__content {
|
|
375
356
|
position: relative;
|
|
357
|
+
margin: var(--half-base-spacing);
|
|
376
358
|
}
|
|
377
359
|
.SummaryCategory__content:hover,
|
|
378
360
|
.SummaryCategory__content:focus-within {
|
|
@@ -399,12 +381,12 @@
|
|
|
399
381
|
}
|
|
400
382
|
|
|
401
383
|
.SummaryTooltip__title {
|
|
402
|
-
font-weight:
|
|
384
|
+
font-weight: bold;
|
|
403
385
|
margin-bottom: var(--half-base-spacing);
|
|
404
386
|
}
|
|
405
387
|
|
|
406
388
|
.SummaryTooltip__category {
|
|
407
|
-
font-weight:
|
|
389
|
+
font-weight: bold;
|
|
408
390
|
display: flex;
|
|
409
391
|
margin-top: var(--half-base-spacing);
|
|
410
392
|
}
|
|
@@ -425,8 +407,7 @@
|
|
|
425
407
|
}
|
|
426
408
|
|
|
427
409
|
.SummaryNavigationHeader {
|
|
428
|
-
font-size: var(--summary-
|
|
429
|
-
line-height: 16px;
|
|
410
|
+
font-size: var(--summary-flow-step-label-font-size);
|
|
430
411
|
display: contents;
|
|
431
412
|
}
|
|
432
413
|
|
|
@@ -549,7 +530,6 @@
|
|
|
549
530
|
.Header__prev-title {
|
|
550
531
|
grid-area: prev-title;
|
|
551
532
|
text-align: left;
|
|
552
|
-
justify-self: start;
|
|
553
533
|
}
|
|
554
534
|
|
|
555
535
|
.Header__next-title {
|
|
@@ -564,17 +544,16 @@
|
|
|
564
544
|
align-self: start;
|
|
565
545
|
overflow-x: hidden;
|
|
566
546
|
text-overflow: ellipsis;
|
|
567
|
-
|
|
547
|
+
width: 100%;
|
|
568
548
|
}
|
|
569
549
|
|
|
570
550
|
.Header__current-title {
|
|
571
551
|
grid-area: current-title;
|
|
572
552
|
text-align: center;
|
|
573
553
|
font-size: var(--header-current-title-font-size);
|
|
574
|
-
font-weight:
|
|
554
|
+
font-weight: bold;
|
|
575
555
|
overflow-x: hidden;
|
|
576
556
|
text-overflow: ellipsis;
|
|
577
|
-
margin: 0px var(--half-base-spacing);
|
|
578
557
|
}
|
|
579
558
|
|
|
580
559
|
.Header__current-description {
|
|
@@ -604,7 +583,7 @@
|
|
|
604
583
|
align-items: center;
|
|
605
584
|
|
|
606
585
|
font-size: var(--dialog-title-font-size);
|
|
607
|
-
font-weight:
|
|
586
|
+
font-weight: bold;
|
|
608
587
|
|
|
609
588
|
margin-bottom: calc(var(--base-spacing) * 2);
|
|
610
589
|
}
|
|
@@ -630,12 +609,12 @@
|
|
|
630
609
|
|
|
631
610
|
.HelpDialogColumn__header-title {
|
|
632
611
|
font-size: var(--category-summary-font-size);
|
|
633
|
-
font-weight:
|
|
612
|
+
font-weight: bold;
|
|
634
613
|
}
|
|
635
614
|
|
|
636
615
|
.HelpDialogColumn__legend-label {
|
|
637
616
|
color: var(--color-blue-A700);
|
|
638
|
-
font-weight:
|
|
617
|
+
font-weight: bold;
|
|
639
618
|
}
|
|
640
619
|
|
|
641
620
|
.HelpDialogColumn ul {
|
|
@@ -644,7 +623,7 @@
|
|
|
644
623
|
|
|
645
624
|
.HelpDialogColumn__use-cases p,
|
|
646
625
|
.HelpDialogColumn__categories p {
|
|
647
|
-
font-weight:
|
|
626
|
+
font-weight: bold;
|
|
648
627
|
color: var(--color-gray-700);
|
|
649
628
|
}
|
|
650
629
|
|
|
@@ -10,7 +10,7 @@ import {useEffect, useState} from 'preact/hooks';
|
|
|
10
10
|
import {NavigationIcon, SnapshotIcon, TimespanIcon} from './icons';
|
|
11
11
|
import {getFilmstripFrames, getScreenDimensions, getScreenshot} from './util';
|
|
12
12
|
|
|
13
|
-
const ANIMATION_FRAME_DURATION_MS =
|
|
13
|
+
const ANIMATION_FRAME_DURATION_MS = 250;
|
|
14
14
|
|
|
15
15
|
export const Separator: FunctionComponent = () => {
|
|
16
16
|
return <div className="Separator" role="separator"></div>;
|
|
@@ -8,7 +8,7 @@ import {FunctionComponent} from 'preact';
|
|
|
8
8
|
|
|
9
9
|
import {Util} from '../../report/renderer/util';
|
|
10
10
|
import {FlowStepIcon, FlowStepThumbnail} from './common';
|
|
11
|
-
import {
|
|
11
|
+
import {useUIStrings} from './i18n/i18n';
|
|
12
12
|
import {getModeDescription, useFlowResult} from './util';
|
|
13
13
|
|
|
14
14
|
const SIDE_THUMBNAIL_HEIGHT = 80;
|
|
@@ -39,7 +39,7 @@ export const Header: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
|
|
|
39
39
|
const prevStep = flowResult.steps[index - 1];
|
|
40
40
|
const nextStep = flowResult.steps[index + 1];
|
|
41
41
|
|
|
42
|
-
const strings =
|
|
42
|
+
const strings = useUIStrings();
|
|
43
43
|
const modeDescription = getModeDescription(step.lhr.gatherMode, strings);
|
|
44
44
|
|
|
45
45
|
return (
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import {FunctionComponent, JSX} from 'preact';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {useUIStrings} from './i18n/i18n';
|
|
10
10
|
import {CloseIcon, NavigationIcon, SnapshotIcon, TimespanIcon} from './icons';
|
|
11
11
|
|
|
12
12
|
const HelpDialogColumn: FunctionComponent<{
|
|
@@ -18,7 +18,7 @@ const HelpDialogColumn: FunctionComponent<{
|
|
|
18
18
|
useCases: string[];
|
|
19
19
|
availableCategories: string[];
|
|
20
20
|
}> = (props) => {
|
|
21
|
-
const strings =
|
|
21
|
+
const strings = useUIStrings();
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
24
|
<div className="HelpDialogColumn">
|
|
@@ -56,7 +56,7 @@ const HelpDialogColumn: FunctionComponent<{
|
|
|
56
56
|
export const HelpDialog: FunctionComponent<{onClose: () => void}> = ({
|
|
57
57
|
onClose,
|
|
58
58
|
}) => {
|
|
59
|
-
const strings =
|
|
59
|
+
const strings = useUIStrings();
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<div className="HelpDialog">
|
|
@@ -7,69 +7,32 @@
|
|
|
7
7
|
import {createContext, FunctionComponent} from 'preact';
|
|
8
8
|
import {useContext, useMemo} from 'preact/hooks';
|
|
9
9
|
|
|
10
|
-
import {formatMessage} from '../../../shared/localization/format';
|
|
11
10
|
import {I18n} from '../../../report/renderer/i18n';
|
|
12
11
|
import {UIStrings} from './ui-strings';
|
|
13
|
-
import {
|
|
12
|
+
import {useLocale} from '../util';
|
|
14
13
|
import strings from './localized-strings';
|
|
15
|
-
import {Util} from '../../../report/renderer/util';
|
|
16
14
|
|
|
17
|
-
const I18nContext = createContext
|
|
18
|
-
|
|
19
|
-
function useLhrLocale() {
|
|
20
|
-
const flowResult = useFlowResult();
|
|
21
|
-
const firstLhr = flowResult.steps[0].lhr;
|
|
22
|
-
const locale = firstLhr.configSettings.locale;
|
|
23
|
-
|
|
24
|
-
if (flowResult.steps.some(step => step.lhr.configSettings.locale !== locale)) {
|
|
25
|
-
console.warn('LHRs have inconsistent locales');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
locale,
|
|
30
|
-
lhrStrings: firstLhr.i18n.rendererFormattedStrings,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
15
|
+
const I18nContext = createContext<I18n<typeof UIStrings>|undefined>(undefined);
|
|
33
16
|
|
|
34
17
|
export function useI18n() {
|
|
35
|
-
|
|
18
|
+
const i18n = useContext(I18nContext);
|
|
19
|
+
if (!i18n) throw Error('i18n was not initialized');
|
|
20
|
+
return i18n;
|
|
36
21
|
}
|
|
37
22
|
|
|
38
|
-
export function
|
|
23
|
+
export function useUIStrings() {
|
|
39
24
|
const i18n = useI18n();
|
|
40
25
|
return i18n.strings;
|
|
41
26
|
}
|
|
42
27
|
|
|
43
|
-
export function useStringFormatter() {
|
|
44
|
-
const {locale} = useLhrLocale();
|
|
45
|
-
return (str: string, values?: Record<string, string|number>) => {
|
|
46
|
-
return formatMessage(str, values, locale);
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
28
|
export const I18nProvider: FunctionComponent = ({children}) => {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// Used for legacy report components imported into the flow report.
|
|
59
|
-
...lhrStrings,
|
|
60
|
-
// Set any missing flow strings to default (english) values.
|
|
61
|
-
...UIStrings,
|
|
62
|
-
// `strings` is generated in build/build-report.js
|
|
63
|
-
...strings[locale],
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Initialize renderer util i18n for strings rendered in wrapped components.
|
|
67
|
-
// TODO: Don't attach global i18n to `Util`.
|
|
68
|
-
// @ts-ignore TS reports as read-only.
|
|
69
|
-
Util.i18n = i18n;
|
|
70
|
-
|
|
71
|
-
return i18n;
|
|
72
|
-
}, [locale, lhrStrings]);
|
|
29
|
+
const locale = useLocale();
|
|
30
|
+
const i18n = useMemo(() => new I18n(locale, {
|
|
31
|
+
// Set missing renderer strings to default (english) values.
|
|
32
|
+
...UIStrings,
|
|
33
|
+
// `strings` is generated in build/build-report.js
|
|
34
|
+
...strings[locale],
|
|
35
|
+
}), [locale]);
|
|
73
36
|
|
|
74
37
|
return (
|
|
75
38
|
<I18nContext.Provider value={i18n}>
|
|
@@ -57,30 +57,6 @@ export const UIStrings = {
|
|
|
57
57
|
ratingFail: 'Poor',
|
|
58
58
|
/** Rating indicating that a report category rating could not be calculated because of an error. */
|
|
59
59
|
ratingError: 'Error',
|
|
60
|
-
/**
|
|
61
|
-
* @description Label indicating the number of Lighthouse reports that evaluate a web page as it loads.
|
|
62
|
-
* @example {2} numNavigation
|
|
63
|
-
*/
|
|
64
|
-
navigationReportCount: `{numNavigation, plural,
|
|
65
|
-
=1 {{numNavigation} navigation report}
|
|
66
|
-
other {{numNavigation} navigation reports}
|
|
67
|
-
}`,
|
|
68
|
-
/**
|
|
69
|
-
* @description Label indicating the number of Lighthouse reports that evaluate a web page over a period of time.
|
|
70
|
-
* @example {2} numTimespan
|
|
71
|
-
*/
|
|
72
|
-
timespanReportCount: `{numTimespan, plural,
|
|
73
|
-
=1 {{numTimespan} timespan report}
|
|
74
|
-
other {{numTimespan} timespan reports}
|
|
75
|
-
}`,
|
|
76
|
-
/**
|
|
77
|
-
* @description Label indicating the number of Lighthouse reports that evaluate a web page at a single point in time.
|
|
78
|
-
* @example {2} numSnapshot
|
|
79
|
-
*/
|
|
80
|
-
snapshotReportCount: `{numSnapshot, plural,
|
|
81
|
-
=1 {{numSnapshot} snapshot report}
|
|
82
|
-
other {{numSnapshot} snapshot reports}
|
|
83
|
-
}`,
|
|
84
60
|
/** Label for a button that saves a Lighthouse report to disk. */
|
|
85
61
|
save: 'Save',
|
|
86
62
|
/** Label for a button that toggles the help modal with explanations on how to interpret the Lighthouse flow report. */
|
|
@@ -107,28 +83,4 @@ export const UIStrings = {
|
|
|
107
83
|
helpUseCaseSnapshot1: 'Find accessibility issues in single page applications or complex forms.',
|
|
108
84
|
/** Example use case for how Lighthouse can be applied in practice. Appears in a list with other examples. */
|
|
109
85
|
helpUseCaseSnapshot2: 'Evaluate best practices of menus and UI elements hidden behind interaction.',
|
|
110
|
-
/**
|
|
111
|
-
* @description Label indicating the number of Lighthouse audits that passed.
|
|
112
|
-
* @example {2} numPassed
|
|
113
|
-
*/
|
|
114
|
-
passedAuditCount: `{numPassed, plural,
|
|
115
|
-
=1 {{numPassed} audit passed}
|
|
116
|
-
other {{numPassed} audits passed}
|
|
117
|
-
}`,
|
|
118
|
-
/**
|
|
119
|
-
* @description Label indicating the number of Lighthouse audits that are possible to pass for a page.
|
|
120
|
-
* @example {2} numPassableAudits
|
|
121
|
-
*/
|
|
122
|
-
passableAuditCount: `{numPassableAudits, plural,
|
|
123
|
-
=1 {{numPassableAudits} passable audit}
|
|
124
|
-
other {{numPassableAudits} passable audits}
|
|
125
|
-
}`,
|
|
126
|
-
/**
|
|
127
|
-
* @description Label indicating the number of Lighthouse audits that are informative.
|
|
128
|
-
* @example {2} numInformative
|
|
129
|
-
*/
|
|
130
|
-
informativeAuditCount: `{numInformative, plural,
|
|
131
|
-
=1 {{numInformative} informative audit}
|
|
132
|
-
other {{numInformative} informative audits}
|
|
133
|
-
}`,
|
|
134
86
|
};
|
|
@@ -122,10 +122,3 @@ export const HamburgerIcon: FunctionComponent = () => {
|
|
|
122
122
|
);
|
|
123
123
|
};
|
|
124
124
|
|
|
125
|
-
export const InfoIcon: FunctionComponent = () => {
|
|
126
|
-
return (
|
|
127
|
-
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
|
|
128
|
-
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 7C13 10.3137 10.3137 13 7 13C3.68629 13 1 10.3137 1 7C1 3.68629 3.68629 1 7 1C10.3137 1 13 3.68629 13 7ZM14 7C14 10.866 10.866 14 7 14C3.13401 14 0 10.866 0 7C0 3.13401 3.13401 0 7 0C10.866 0 14 3.13401 14 7ZM7.66658 11H6.33325V9.66667H7.66658V11ZM4.33325 5.66667C4.33325 4.19333 5.52659 3 6.99992 3C8.47325 3 9.66658 4.19333 9.66658 5.66667C9.66658 6.52194 9.1399 6.98221 8.62709 7.43036C8.1406 7.85551 7.66658 8.26975 7.66658 9H6.33325C6.33325 7.78582 6.96133 7.30439 7.51355 6.88112C7.94674 6.54907 8.33325 6.25281 8.33325 5.66667C8.33325 4.93333 7.73325 4.33333 6.99992 4.33333C6.26658 4.33333 5.66658 4.93333 5.66658 5.66667H4.33325Z" fill="currentColor"/>
|
|
129
|
-
</svg>
|
|
130
|
-
);
|
|
131
|
-
};
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
import {FunctionComponent} from 'preact';
|
|
8
8
|
|
|
9
9
|
import {Separator} from '../common';
|
|
10
|
-
import {useI18n,
|
|
10
|
+
import {useI18n, useUIStrings} from '../i18n/i18n';
|
|
11
11
|
import {CpuIcon, EnvIcon, SummaryIcon} from '../icons';
|
|
12
12
|
import {classNames, useCurrentLhr, useFlowResult} from '../util';
|
|
13
13
|
import {SidebarFlow} from './flow';
|
|
14
14
|
|
|
15
15
|
export const SidebarSummary: FunctionComponent = () => {
|
|
16
16
|
const currentLhr = useCurrentLhr();
|
|
17
|
-
const strings =
|
|
17
|
+
const strings = useUIStrings();
|
|
18
18
|
|
|
19
19
|
const url = new URL(location.href);
|
|
20
20
|
url.hash = '#';
|
|
@@ -33,21 +33,19 @@ export const SidebarSummary: FunctionComponent = () => {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
const SidebarRuntimeSettings: FunctionComponent<{settings: LH.ConfigSettings}> = ({settings}) => {
|
|
36
|
-
const strings =
|
|
36
|
+
const strings = useUIStrings();
|
|
37
37
|
|
|
38
38
|
return (
|
|
39
39
|
<div className="SidebarRuntimeSettings">
|
|
40
|
-
<div className="SidebarRuntimeSettings__item"
|
|
40
|
+
<div className="SidebarRuntimeSettings__item">
|
|
41
41
|
<div className="SidebarRuntimeSettings__item--icon">
|
|
42
42
|
<EnvIcon/>
|
|
43
43
|
</div>
|
|
44
44
|
{
|
|
45
|
-
settings.formFactor === 'desktop' ?
|
|
46
|
-
strings.runtimeDesktopEmulation :
|
|
47
|
-
strings.runtimeMobileEmulation
|
|
45
|
+
settings.formFactor === 'desktop' ? strings.desktop : strings.mobile
|
|
48
46
|
}
|
|
49
47
|
</div>
|
|
50
|
-
<div className="SidebarRuntimeSettings__item"
|
|
48
|
+
<div className="SidebarRuntimeSettings__item">
|
|
51
49
|
<div className="SidebarRuntimeSettings__item--icon">
|
|
52
50
|
<CpuIcon/>
|
|
53
51
|
</div>
|
|
@@ -9,7 +9,7 @@ import {FunctionComponent} from 'preact';
|
|
|
9
9
|
import {Util} from '../../../report/renderer/util';
|
|
10
10
|
import {Separator} from '../common';
|
|
11
11
|
import {CategoryScore} from '../wrappers/category-score';
|
|
12
|
-
import {
|
|
12
|
+
import {useUIStrings} from '../i18n/i18n';
|
|
13
13
|
|
|
14
14
|
import type {UIStringsType} from '../i18n/ui-strings';
|
|
15
15
|
|
|
@@ -34,8 +34,7 @@ export const SummaryTooltip: FunctionComponent<{
|
|
|
34
34
|
category: LH.ReportResult.Category,
|
|
35
35
|
gatherMode: LH.Result.GatherMode
|
|
36
36
|
}> = ({category, gatherMode}) => {
|
|
37
|
-
const strings =
|
|
38
|
-
const str_ = useStringFormatter();
|
|
37
|
+
const strings = useUIStrings();
|
|
39
38
|
const {
|
|
40
39
|
numPassed,
|
|
41
40
|
numPassableAudits,
|
|
@@ -43,12 +42,10 @@ export const SummaryTooltip: FunctionComponent<{
|
|
|
43
42
|
totalWeight,
|
|
44
43
|
} = Util.calculateCategoryFraction(category);
|
|
45
44
|
|
|
46
|
-
const i18n = useI18n();
|
|
47
45
|
const displayAsFraction = Util.shouldDisplayAsFraction(gatherMode);
|
|
48
|
-
const
|
|
49
|
-
numPassed / numPassableAudits :
|
|
50
|
-
category.score;
|
|
51
|
-
const rating = score === null ? 'error' : Util.calculateRating(score);
|
|
46
|
+
const rating = displayAsFraction ?
|
|
47
|
+
Util.calculateRating(numPassed / numPassableAudits) :
|
|
48
|
+
Util.calculateRating(category.score);
|
|
52
49
|
|
|
53
50
|
return (
|
|
54
51
|
<div className="SummaryTooltip">
|
|
@@ -63,23 +60,27 @@ export const SummaryTooltip: FunctionComponent<{
|
|
|
63
60
|
<div className={`SummaryTooltip__rating SummaryTooltip__rating--${rating}`}>
|
|
64
61
|
<span>{getCategoryRating(rating, strings)}</span>
|
|
65
62
|
{
|
|
66
|
-
!displayAsFraction && category.score
|
|
63
|
+
!displayAsFraction && category.score && <>
|
|
67
64
|
<span> · </span>
|
|
68
|
-
<span>{
|
|
65
|
+
<span>{category.score * 100}</span>
|
|
69
66
|
</>
|
|
70
67
|
}
|
|
71
68
|
</div>
|
|
72
69
|
}
|
|
73
70
|
</div>
|
|
74
71
|
<div className="SummaryTooltip__fraction">
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
{
|
|
73
|
+
// TODO(FLOW-I18N): Placeholder format.
|
|
74
|
+
`${numPassed} audits passed / ${numPassableAudits} passable audits`
|
|
75
|
+
}
|
|
78
76
|
</div>
|
|
79
|
-
{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
{
|
|
78
|
+
// TODO(FLOW-I18N): Placeholder format.
|
|
79
|
+
numInformative ?
|
|
80
|
+
<div className="SummaryTooltip__informative">
|
|
81
|
+
{`${numInformative} informative audits`}
|
|
82
|
+
</div> :
|
|
83
|
+
null
|
|
83
84
|
}
|
|
84
85
|
</div>
|
|
85
86
|
);
|
|
@@ -11,13 +11,13 @@ import {FlowSegment, FlowStepThumbnail, Separator} from '../common';
|
|
|
11
11
|
import {getModeDescription, useFlowResult} from '../util';
|
|
12
12
|
import {Util} from '../../../report/renderer/util';
|
|
13
13
|
import {SummaryCategory} from './category';
|
|
14
|
-
import {
|
|
14
|
+
import {useUIStrings} from '../i18n/i18n';
|
|
15
15
|
|
|
16
16
|
const DISPLAYED_CATEGORIES = ['performance', 'accessibility', 'best-practices', 'seo'];
|
|
17
|
-
const THUMBNAIL_WIDTH =
|
|
17
|
+
const THUMBNAIL_WIDTH = 50;
|
|
18
18
|
|
|
19
19
|
const SummaryNavigationHeader: FunctionComponent<{lhr: LH.Result}> = ({lhr}) => {
|
|
20
|
-
const strings =
|
|
20
|
+
const strings = useUIStrings();
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
23
|
<div className="SummaryNavigationHeader" data-testid="SummaryNavigationHeader">
|
|
@@ -50,7 +50,7 @@ export const SummaryFlowStep: FunctionComponent<{
|
|
|
50
50
|
hashIndex: number,
|
|
51
51
|
}> = ({lhr, label, hashIndex}) => {
|
|
52
52
|
const reportResult = useMemo(() => Util.prepareReportResult(lhr), [lhr]);
|
|
53
|
-
const strings =
|
|
53
|
+
const strings = useUIStrings();
|
|
54
54
|
const modeDescription = getModeDescription(lhr.gatherMode, strings);
|
|
55
55
|
|
|
56
56
|
return (
|
|
@@ -107,8 +107,7 @@ const SummaryFlow: FunctionComponent = () => {
|
|
|
107
107
|
|
|
108
108
|
export const SummaryHeader: FunctionComponent = () => {
|
|
109
109
|
const flowResult = useFlowResult();
|
|
110
|
-
const strings =
|
|
111
|
-
const str_ = useStringFormatter();
|
|
110
|
+
const strings = useUIStrings();
|
|
112
111
|
|
|
113
112
|
let numNavigation = 0;
|
|
114
113
|
let numTimespan = 0;
|
|
@@ -127,10 +126,11 @@ export const SummaryHeader: FunctionComponent = () => {
|
|
|
127
126
|
}
|
|
128
127
|
}
|
|
129
128
|
|
|
129
|
+
// TODO(FLOW-I18N): Placeholder format.
|
|
130
130
|
const subtitleCounts = [];
|
|
131
|
-
if (numNavigation) subtitleCounts.push(
|
|
132
|
-
if (numTimespan) subtitleCounts.push(
|
|
133
|
-
if (numSnapshot) subtitleCounts.push(
|
|
131
|
+
if (numNavigation) subtitleCounts.push(`${numNavigation} navigation reports`);
|
|
132
|
+
if (numTimespan) subtitleCounts.push(`${numTimespan} timespan reports`);
|
|
133
|
+
if (numSnapshot) subtitleCounts.push(`${numSnapshot} snapshot reports`);
|
|
134
134
|
const subtitle = subtitleCounts.join(' · ');
|
|
135
135
|
|
|
136
136
|
return (
|
|
@@ -151,7 +151,7 @@ const SummarySectionHeader: FunctionComponent = ({children}) => {
|
|
|
151
151
|
};
|
|
152
152
|
|
|
153
153
|
export const Summary: FunctionComponent = () => {
|
|
154
|
-
const strings =
|
|
154
|
+
const strings = useUIStrings();
|
|
155
155
|
|
|
156
156
|
return (
|
|
157
157
|
<div className="Summary" data-testid="Summary">
|
|
@@ -9,8 +9,8 @@ import {useState} from 'preact/hooks';
|
|
|
9
9
|
|
|
10
10
|
import {HelpDialog} from './help-dialog';
|
|
11
11
|
import {getFilenamePrefix} from '../../report/generator/file-namer';
|
|
12
|
-
import {
|
|
13
|
-
import {HamburgerIcon
|
|
12
|
+
import {useUIStrings} from './i18n/i18n';
|
|
13
|
+
import {HamburgerIcon} from './icons';
|
|
14
14
|
import {useFlowResult} from './util';
|
|
15
15
|
import {useReportRenderer} from './wrappers/report-renderer';
|
|
16
16
|
|
|
@@ -79,7 +79,7 @@ export const Topbar: FunctionComponent<{onMenuClick: JSX.MouseEventHandler<HTMLB
|
|
|
79
79
|
({onMenuClick}) => {
|
|
80
80
|
const flowResult = useFlowResult();
|
|
81
81
|
const {dom} = useReportRenderer();
|
|
82
|
-
const strings =
|
|
82
|
+
const strings = useUIStrings();
|
|
83
83
|
const [showHelpDialog, setShowHelpDialog] = useState(false);
|
|
84
84
|
|
|
85
85
|
return (
|
|
@@ -98,12 +98,8 @@ export const Topbar: FunctionComponent<{onMenuClick: JSX.MouseEventHandler<HTMLB
|
|
|
98
98
|
<div style={{flexGrow: 1}} />
|
|
99
99
|
<TopbarButton
|
|
100
100
|
onClick={() => setShowHelpDialog(previous => !previous)}
|
|
101
|
-
label="Button that toggles the help dialog"
|
|
102
|
-
|
|
103
|
-
<div className="Topbar__help-label">
|
|
104
|
-
<InfoIcon/>
|
|
105
|
-
{strings.helpLabel}
|
|
106
|
-
</div>
|
|
101
|
+
label="Button that toggles the help dialog">
|
|
102
|
+
{strings.helpLabel}
|
|
107
103
|
</TopbarButton>
|
|
108
104
|
{showHelpDialog ?
|
|
109
105
|
<HelpDialog onClose={() => setShowHelpDialog(false)} /> :
|