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
|
@@ -23,11 +23,12 @@ limitations under the License.
|
|
|
23
23
|
<title>Lighthouse Flow Report</title>
|
|
24
24
|
<style>/*%%LIGHTHOUSE_CSS%%*/</style>
|
|
25
25
|
<style>/*%%LIGHTHOUSE_FLOW_CSS%%*/</style>
|
|
26
|
+
<style>body {margin: 0}</style>
|
|
26
27
|
</head>
|
|
27
|
-
<body
|
|
28
|
+
<body>
|
|
28
29
|
<noscript>Lighthouse report requires JavaScript. Please enable.</noscript>
|
|
29
30
|
|
|
30
|
-
<main><!-- report populated here --></main>
|
|
31
|
+
<main class="flow-vars lh-root lh-vars"><!-- report populated here --></main>
|
|
31
32
|
|
|
32
33
|
<script>window.__LIGHTHOUSE_FLOW_JSON__ = %%LIGHTHOUSE_FLOW_JSON%%;</script>
|
|
33
34
|
<script>%%LIGHTHOUSE_FLOW_JAVASCRIPT%%
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
.flow-vars {
|
|
8
8
|
--app-font-size: 12px;
|
|
9
9
|
--base-spacing: 16px;
|
|
10
|
+
--bold-weight: 500;
|
|
10
11
|
--category-summary-font-size: 18px;
|
|
11
12
|
--double-base-spacing: calc(var(--base-spacing) * 2);
|
|
12
13
|
--gather-mode-icon-size: 16px;
|
|
@@ -23,11 +24,14 @@
|
|
|
23
24
|
--sidebar-selected-bg-color: #DDEEFF;
|
|
24
25
|
--sidebar-summary-font-size: 14px;
|
|
25
26
|
--sidebar-title-font-size: 16px;
|
|
26
|
-
--sidebar-
|
|
27
|
-
--summary-flow-step-
|
|
28
|
-
--summary-
|
|
29
|
-
--summary-
|
|
27
|
+
--sidebar-width: 320px;
|
|
28
|
+
--summary-flow-step-link-font-size: 14px;
|
|
29
|
+
--summary-navigation-header-font-size: 12px;
|
|
30
|
+
--summary-header-margin: 52px;
|
|
31
|
+
--summary-subtitle-font-size: 12px;
|
|
32
|
+
--summary-title-font-size: 20px;
|
|
30
33
|
--summary-tooltip-box-shadow-color: rgba(0, 0, 0, 0.25);
|
|
34
|
+
--summary-tooltip-line-height: 16px;
|
|
31
35
|
--topbar-button-font-size: 14px;
|
|
32
36
|
--topbar-button-size: 45px;
|
|
33
37
|
--topbar-title-font-size: 14px;
|
|
@@ -114,10 +118,18 @@
|
|
|
114
118
|
|
|
115
119
|
.Topbar__title {
|
|
116
120
|
font-size: var(--topbar-title-font-size);
|
|
117
|
-
font-weight: bold;
|
|
121
|
+
font-weight: var(--bold-weight);
|
|
118
122
|
margin-right: var(--double-base-spacing);
|
|
119
123
|
}
|
|
120
124
|
|
|
125
|
+
.Topbar__help-label {
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
}
|
|
129
|
+
.Topbar__help-label > :first-child {
|
|
130
|
+
margin-right: var(--half-base-spacing);
|
|
131
|
+
}
|
|
132
|
+
|
|
121
133
|
.Content {
|
|
122
134
|
grid-area: content;
|
|
123
135
|
overflow-y: auto;
|
|
@@ -148,19 +160,19 @@
|
|
|
148
160
|
.Sidebar {
|
|
149
161
|
grid-area: sidebar;
|
|
150
162
|
border-right: 1px solid var(--separator-color);
|
|
151
|
-
width:
|
|
152
|
-
max-width: var(--sidebar-max-width);
|
|
163
|
+
width: var(--sidebar-width);
|
|
153
164
|
overflow-x: hidden;
|
|
154
165
|
overflow-y: auto;
|
|
155
166
|
}
|
|
156
167
|
.Sidebar a {
|
|
157
|
-
color: var(--color-gray-
|
|
168
|
+
color: var(--color-gray-700);
|
|
158
169
|
text-decoration: none;
|
|
159
170
|
}
|
|
160
171
|
|
|
161
172
|
.Sidebar--current {
|
|
162
173
|
background-color: var(--sidebar-selected-bg-color);
|
|
163
174
|
color: var(--color-blue-A700) !important;
|
|
175
|
+
font-weight: var(--bold-weight);
|
|
164
176
|
}
|
|
165
177
|
|
|
166
178
|
.SidebarHeader {
|
|
@@ -168,7 +180,7 @@
|
|
|
168
180
|
}
|
|
169
181
|
.SidebarHeader__title {
|
|
170
182
|
font-size: var(--sidebar-title-font-size);
|
|
171
|
-
font-weight: bold;
|
|
183
|
+
font-weight: var(--bold-weight);
|
|
172
184
|
width: max-content;
|
|
173
185
|
}
|
|
174
186
|
.SidebarHeader__date {
|
|
@@ -180,6 +192,7 @@
|
|
|
180
192
|
margin: var(--base-spacing);
|
|
181
193
|
padding: var(--half-base-spacing);
|
|
182
194
|
background-color: var(--color-gray-50);
|
|
195
|
+
color: var(--color-gray-700);
|
|
183
196
|
border-radius: 3px;
|
|
184
197
|
}
|
|
185
198
|
|
|
@@ -258,21 +271,23 @@
|
|
|
258
271
|
}
|
|
259
272
|
|
|
260
273
|
.SummaryHeader {
|
|
261
|
-
margin:
|
|
262
|
-
width: 100%;
|
|
274
|
+
margin: var(--summary-header-margin) 0px;
|
|
263
275
|
}
|
|
264
276
|
|
|
265
277
|
.SummaryHeader__title {
|
|
266
|
-
margin: var(--base-spacing) 0;
|
|
267
278
|
font-size: var(--summary-title-font-size);
|
|
279
|
+
font-weight: var(--bold-weight);
|
|
280
|
+
line-height: 28px;
|
|
281
|
+
margin: 0 0 calc(0.25 * var(--base-spacing));
|
|
268
282
|
}
|
|
269
283
|
|
|
270
284
|
.SummaryHeader__subtitle {
|
|
271
285
|
font-size: var(--summary-subtitle-font-size);
|
|
286
|
+
line-height: 16px;
|
|
272
287
|
}
|
|
273
288
|
|
|
274
289
|
.SummarySectionHeader {
|
|
275
|
-
margin-top: var(--
|
|
290
|
+
margin-top: var(--base-spacing);
|
|
276
291
|
}
|
|
277
292
|
|
|
278
293
|
.SummarySectionHeader__content {
|
|
@@ -281,15 +296,15 @@
|
|
|
281
296
|
}
|
|
282
297
|
|
|
283
298
|
.SummaryFlow {
|
|
284
|
-
width: 100%;
|
|
285
299
|
display: grid;
|
|
300
|
+
max-width: var(--report-content-width);
|
|
286
301
|
grid-auto-rows: min-content;
|
|
287
|
-
grid-template-columns: min-content min-content minmax(var(--min-text-width),
|
|
302
|
+
grid-template-columns: min-content min-content minmax(var(--min-text-width), max-content) 1fr 1fr 1fr 1fr;
|
|
288
303
|
align-items: center;
|
|
289
304
|
margin: var(--base-spacing) 0px;
|
|
305
|
+
--gauge-circle-size: 48px;
|
|
290
306
|
}
|
|
291
307
|
.SummaryFlow .lh-fraction__content {
|
|
292
|
-
padding: 0px;
|
|
293
308
|
min-width: unset;
|
|
294
309
|
}
|
|
295
310
|
|
|
@@ -321,7 +336,7 @@
|
|
|
321
336
|
grid-column: 2;
|
|
322
337
|
}
|
|
323
338
|
.SummaryFlowStep .FlowStepThumbnail {
|
|
324
|
-
margin: var(--
|
|
339
|
+
margin: var(--half-base-spacing);
|
|
325
340
|
}
|
|
326
341
|
|
|
327
342
|
.FlowStepThumbnail {
|
|
@@ -329,7 +344,10 @@
|
|
|
329
344
|
justify-self: center;
|
|
330
345
|
object-fit: cover;
|
|
331
346
|
object-position: top left;
|
|
332
|
-
border: 1px solid var(--color-gray);
|
|
347
|
+
border: 1px solid var(--color-gray-700);
|
|
348
|
+
border-radius: 3px;
|
|
349
|
+
padding: 2px;
|
|
350
|
+
box-sizing: content-box !important;
|
|
333
351
|
}
|
|
334
352
|
|
|
335
353
|
.SummaryFlowStep__label {
|
|
@@ -341,11 +359,13 @@
|
|
|
341
359
|
}
|
|
342
360
|
|
|
343
361
|
.SummaryFlowStep__mode {
|
|
344
|
-
color: var(--color-
|
|
362
|
+
color: var(--color-blue-A700);
|
|
363
|
+
font-weight: var(--bold-weight);
|
|
345
364
|
}
|
|
346
365
|
|
|
347
366
|
.SummaryFlowStep__link {
|
|
348
|
-
font-size: var(--summary-flow-step-
|
|
367
|
+
font-size: var(--summary-flow-step-link-font-size);
|
|
368
|
+
line-height: 20px;
|
|
349
369
|
color: var(--color-gray-800);
|
|
350
370
|
text-decoration: underline;
|
|
351
371
|
width: 100%;
|
|
@@ -354,7 +374,6 @@
|
|
|
354
374
|
|
|
355
375
|
.SummaryCategory__content {
|
|
356
376
|
position: relative;
|
|
357
|
-
margin: var(--half-base-spacing);
|
|
358
377
|
}
|
|
359
378
|
.SummaryCategory__content:hover,
|
|
360
379
|
.SummaryCategory__content:focus-within {
|
|
@@ -376,22 +395,33 @@
|
|
|
376
395
|
border-radius: 3px;
|
|
377
396
|
padding: var(--base-spacing);
|
|
378
397
|
right: 0;
|
|
398
|
+
line-height: var(--summary-tooltip-line-height);
|
|
379
399
|
box-shadow: 0px 4px 4px var(--summary-tooltip-box-shadow-color);
|
|
380
400
|
z-index: 1;
|
|
381
401
|
}
|
|
382
402
|
|
|
383
403
|
.SummaryTooltip__title {
|
|
384
|
-
font-weight: bold;
|
|
385
|
-
|
|
404
|
+
font-weight: var(--bold-weight);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.SummaryTooltip__url {
|
|
408
|
+
overflow-x: hidden;
|
|
409
|
+
text-overflow: ellipsis;
|
|
410
|
+
white-space: nowrap;
|
|
411
|
+
margin-top: calc(0.25 * var(--base-spacing));
|
|
412
|
+
margin-bottom: calc(0.75 * var(--base-spacing));
|
|
413
|
+
color: var(--color-gray-700);
|
|
386
414
|
}
|
|
387
415
|
|
|
388
416
|
.SummaryTooltip__category {
|
|
389
|
-
font-weight: bold;
|
|
417
|
+
font-weight: var(--bold-weight);
|
|
390
418
|
display: flex;
|
|
419
|
+
align-items: center;
|
|
391
420
|
margin-top: var(--half-base-spacing);
|
|
392
421
|
}
|
|
393
422
|
|
|
394
423
|
.SummaryTooltip__category-title {
|
|
424
|
+
line-height: 24px;
|
|
395
425
|
flex-grow: 1;
|
|
396
426
|
}
|
|
397
427
|
|
|
@@ -406,8 +436,53 @@
|
|
|
406
436
|
color: var(--color-fail);
|
|
407
437
|
}
|
|
408
438
|
|
|
439
|
+
.SummaryTooltip__fraction {
|
|
440
|
+
color: var(--color-gray-700);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.SummaryTooltip__informative {
|
|
444
|
+
margin-top: calc(0.25 * var(--base-spacing));
|
|
445
|
+
color: var(--color-gray-700);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.SummaryTooltipAudits__title {
|
|
449
|
+
line-height: 24px;
|
|
450
|
+
margin-top: calc(0.75 * var(--base-spacing));
|
|
451
|
+
font-weight: var(--bold-weight);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.SummaryTooltipAudit {
|
|
455
|
+
display: flex;
|
|
456
|
+
margin: calc(0.25 * var(--base-spacing)) 0px;
|
|
457
|
+
color: var(--color-gray-700);
|
|
458
|
+
--score-icon-size: 10px;
|
|
459
|
+
}
|
|
460
|
+
.SummaryTooltipAudit code {
|
|
461
|
+
color: var(--snippet-color);
|
|
462
|
+
}
|
|
463
|
+
.SummaryTooltipAudit::before {
|
|
464
|
+
content: '';
|
|
465
|
+
height: var(--score-icon-size);
|
|
466
|
+
width: var(--score-icon-size);
|
|
467
|
+
margin-top: calc((var(--summary-tooltip-line-height) - var(--score-icon-size)) / 2);
|
|
468
|
+
margin-right: var(--half-base-spacing);
|
|
469
|
+
}
|
|
470
|
+
.SummaryTooltipAudit--pass::before {
|
|
471
|
+
background-color: var(--color-pass);
|
|
472
|
+
border-radius: 50%;
|
|
473
|
+
}
|
|
474
|
+
.SummaryTooltipAudit--average::before {
|
|
475
|
+
background-color: var(--color-average);
|
|
476
|
+
}
|
|
477
|
+
.SummaryTooltipAudit--fail::before {
|
|
478
|
+
border-left: calc(var(--score-icon-size) / 2) solid transparent;
|
|
479
|
+
border-right: calc(var(--score-icon-size) / 2) solid transparent;
|
|
480
|
+
border-bottom: var(--score-icon-size) solid var(--color-fail);
|
|
481
|
+
}
|
|
482
|
+
|
|
409
483
|
.SummaryNavigationHeader {
|
|
410
|
-
font-size: var(--summary-
|
|
484
|
+
font-size: var(--summary-navigation-header-font-size);
|
|
485
|
+
line-height: 16px;
|
|
411
486
|
display: contents;
|
|
412
487
|
}
|
|
413
488
|
|
|
@@ -530,6 +605,7 @@
|
|
|
530
605
|
.Header__prev-title {
|
|
531
606
|
grid-area: prev-title;
|
|
532
607
|
text-align: left;
|
|
608
|
+
justify-self: start;
|
|
533
609
|
}
|
|
534
610
|
|
|
535
611
|
.Header__next-title {
|
|
@@ -544,16 +620,17 @@
|
|
|
544
620
|
align-self: start;
|
|
545
621
|
overflow-x: hidden;
|
|
546
622
|
text-overflow: ellipsis;
|
|
547
|
-
width: 100%;
|
|
623
|
+
max-width: 100%;
|
|
548
624
|
}
|
|
549
625
|
|
|
550
626
|
.Header__current-title {
|
|
551
627
|
grid-area: current-title;
|
|
552
628
|
text-align: center;
|
|
553
629
|
font-size: var(--header-current-title-font-size);
|
|
554
|
-
font-weight: bold;
|
|
630
|
+
font-weight: var(--bold-weight);
|
|
555
631
|
overflow-x: hidden;
|
|
556
632
|
text-overflow: ellipsis;
|
|
633
|
+
margin: 0px var(--half-base-spacing);
|
|
557
634
|
}
|
|
558
635
|
|
|
559
636
|
.Header__current-description {
|
|
@@ -583,7 +660,7 @@
|
|
|
583
660
|
align-items: center;
|
|
584
661
|
|
|
585
662
|
font-size: var(--dialog-title-font-size);
|
|
586
|
-
font-weight: bold;
|
|
663
|
+
font-weight: var(--bold-weight);
|
|
587
664
|
|
|
588
665
|
margin-bottom: calc(var(--base-spacing) * 2);
|
|
589
666
|
}
|
|
@@ -609,12 +686,12 @@
|
|
|
609
686
|
|
|
610
687
|
.HelpDialogColumn__header-title {
|
|
611
688
|
font-size: var(--category-summary-font-size);
|
|
612
|
-
font-weight: bold;
|
|
689
|
+
font-weight: var(--bold-weight);
|
|
613
690
|
}
|
|
614
691
|
|
|
615
692
|
.HelpDialogColumn__legend-label {
|
|
616
693
|
color: var(--color-blue-A700);
|
|
617
|
-
font-weight: bold;
|
|
694
|
+
font-weight: var(--bold-weight);
|
|
618
695
|
}
|
|
619
696
|
|
|
620
697
|
.HelpDialogColumn ul {
|
|
@@ -623,7 +700,7 @@
|
|
|
623
700
|
|
|
624
701
|
.HelpDialogColumn__use-cases p,
|
|
625
702
|
.HelpDialogColumn__categories p {
|
|
626
|
-
font-weight: bold;
|
|
703
|
+
font-weight: var(--bold-weight);
|
|
627
704
|
color: var(--color-gray-700);
|
|
628
705
|
}
|
|
629
706
|
|
package/flow-report/src/app.tsx
CHANGED
|
@@ -5,42 +5,42 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {FunctionComponent} from 'preact';
|
|
8
|
-
import {
|
|
8
|
+
import {useLayoutEffect, useRef, useState} from 'preact/hooks';
|
|
9
9
|
|
|
10
10
|
import {ReportRendererProvider} from './wrappers/report-renderer';
|
|
11
11
|
import {Sidebar} from './sidebar/sidebar';
|
|
12
12
|
import {Summary} from './summary/summary';
|
|
13
|
-
import {classNames, FlowResultContext,
|
|
13
|
+
import {classNames, FlowResultContext, useHashState} from './util';
|
|
14
14
|
import {Report} from './wrappers/report';
|
|
15
15
|
import {Topbar} from './topbar';
|
|
16
16
|
import {Header} from './header';
|
|
17
17
|
import {I18nProvider} from './i18n/i18n';
|
|
18
18
|
|
|
19
|
+
function getAnchorElement(hashState: LH.FlowResult.HashState|null) {
|
|
20
|
+
if (!hashState || !hashState.anchor) return null;
|
|
21
|
+
return document.getElementById(hashState.anchor);
|
|
22
|
+
}
|
|
23
|
+
|
|
19
24
|
const Content: FunctionComponent = () => {
|
|
20
|
-
const
|
|
21
|
-
const anchor = useHashParam('anchor');
|
|
25
|
+
const hashState = useHashState();
|
|
22
26
|
const ref = useRef<HTMLDivElement>(null);
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
28
|
+
useLayoutEffect(() => {
|
|
29
|
+
const el = getAnchorElement(hashState);
|
|
30
|
+
if (el) {
|
|
31
|
+
el.scrollIntoView();
|
|
32
|
+
} else if (ref.current) {
|
|
33
|
+
ref.current.scrollTop = 0;
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
// Scroll to top no anchor is found.
|
|
34
|
-
if (ref.current) ref.current.scrollTop = 0;
|
|
35
|
-
}, [anchor, currentLhr]);
|
|
35
|
+
}, [hashState]);
|
|
36
36
|
|
|
37
37
|
return (
|
|
38
38
|
<div ref={ref} className="Content">
|
|
39
39
|
{
|
|
40
|
-
|
|
40
|
+
hashState ?
|
|
41
41
|
<>
|
|
42
|
-
<Header
|
|
43
|
-
<Report
|
|
42
|
+
<Header hashState={hashState}/>
|
|
43
|
+
<Report hashState={hashState}/>
|
|
44
44
|
</> :
|
|
45
45
|
<Summary/>
|
|
46
46
|
}
|
|
@@ -8,15 +8,15 @@ import {FunctionComponent} from 'preact';
|
|
|
8
8
|
import {useEffect, useState} from 'preact/hooks';
|
|
9
9
|
|
|
10
10
|
import {NavigationIcon, SnapshotIcon, TimespanIcon} from './icons';
|
|
11
|
-
import {getFilmstripFrames, getScreenDimensions,
|
|
11
|
+
import {getFilmstripFrames, getScreenDimensions, getFullPageScreenshot} from './util';
|
|
12
12
|
|
|
13
|
-
const ANIMATION_FRAME_DURATION_MS =
|
|
13
|
+
const ANIMATION_FRAME_DURATION_MS = 500;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const Separator: FunctionComponent = () => {
|
|
16
16
|
return <div className="Separator" role="separator"></div>;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const FlowStepIcon: FunctionComponent<{mode: LH.Result.GatherMode}> = ({mode}) => {
|
|
20
20
|
return <>
|
|
21
21
|
{
|
|
22
22
|
mode === 'navigation' && <NavigationIcon/>
|
|
@@ -30,7 +30,7 @@ export const FlowStepIcon: FunctionComponent<{mode: LH.Result.GatherMode}> = ({m
|
|
|
30
30
|
</>;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
const FlowSegment: FunctionComponent<{mode?: LH.Result.GatherMode}> = ({mode}) => {
|
|
34
34
|
return (
|
|
35
35
|
<div className="FlowSegment">
|
|
36
36
|
<div className="FlowSegment__top-line"/>
|
|
@@ -71,16 +71,16 @@ const FlowStepAnimatedThumbnail: FunctionComponent<{
|
|
|
71
71
|
);
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
const FlowStepThumbnail: FunctionComponent<{
|
|
75
|
+
lhr: LH.Result,
|
|
76
76
|
width?: number,
|
|
77
77
|
height?: number,
|
|
78
|
-
}> = ({
|
|
79
|
-
const
|
|
80
|
-
const frames = getFilmstripFrames(
|
|
78
|
+
}> = ({lhr, width, height}) => {
|
|
79
|
+
const fullPageScreenshot = getFullPageScreenshot(lhr);
|
|
80
|
+
const frames = getFilmstripFrames(lhr);
|
|
81
81
|
|
|
82
82
|
// Resize the image to fit the viewport aspect ratio.
|
|
83
|
-
const dimensions = getScreenDimensions(
|
|
83
|
+
const dimensions = getScreenDimensions(lhr);
|
|
84
84
|
if (width && height === undefined) {
|
|
85
85
|
height = dimensions.height * width / dimensions.width;
|
|
86
86
|
} else if (height && width === undefined) {
|
|
@@ -92,19 +92,32 @@ export const FlowStepThumbnail: FunctionComponent<{
|
|
|
92
92
|
return <></>;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
let thumbnail;
|
|
96
|
+
if (frames && frames.length) {
|
|
97
|
+
thumbnail = frames[frames.length - 1].data;
|
|
98
|
+
if (lhr.gatherMode === 'timespan') {
|
|
99
|
+
return <FlowStepAnimatedThumbnail frames={frames} width={width} height={height} />;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
thumbnail = fullPageScreenshot?.screenshot.data;
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
return <>
|
|
100
106
|
{
|
|
101
|
-
|
|
107
|
+
thumbnail &&
|
|
102
108
|
<img
|
|
103
109
|
className="FlowStepThumbnail"
|
|
104
|
-
src={
|
|
110
|
+
src={thumbnail}
|
|
105
111
|
style={{width, height}}
|
|
106
112
|
alt="Screenshot of a page tested by Lighthouse"
|
|
107
113
|
/>
|
|
108
114
|
}
|
|
109
115
|
</>;
|
|
110
116
|
};
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
Separator,
|
|
120
|
+
FlowStepIcon,
|
|
121
|
+
FlowSegment,
|
|
122
|
+
FlowStepThumbnail,
|
|
123
|
+
};
|
|
@@ -6,40 +6,39 @@
|
|
|
6
6
|
|
|
7
7
|
import {FunctionComponent} from 'preact';
|
|
8
8
|
|
|
9
|
-
import {Util} from '../../report/renderer/util';
|
|
10
9
|
import {FlowStepIcon, FlowStepThumbnail} from './common';
|
|
11
|
-
import {
|
|
10
|
+
import {useLocalizedStrings} from './i18n/i18n';
|
|
12
11
|
import {getModeDescription, useFlowResult} from './util';
|
|
13
12
|
|
|
14
13
|
const SIDE_THUMBNAIL_HEIGHT = 80;
|
|
15
14
|
const MAIN_THUMBNAIL_HEIGHT = 120;
|
|
16
15
|
|
|
17
16
|
const HeaderThumbnail: FunctionComponent<{
|
|
18
|
-
|
|
17
|
+
lhr: LH.Result,
|
|
19
18
|
position: 'prev'|'next'|'main'
|
|
20
19
|
}> =
|
|
21
|
-
({
|
|
20
|
+
({lhr, position}) => {
|
|
22
21
|
const height = position === 'main' ? MAIN_THUMBNAIL_HEIGHT : SIDE_THUMBNAIL_HEIGHT;
|
|
23
22
|
return (
|
|
24
23
|
<div className={`HeaderThumbnail HeaderThumbnail--${position}`}>
|
|
25
|
-
<FlowStepThumbnail
|
|
24
|
+
<FlowStepThumbnail lhr={lhr} height={height}/>
|
|
26
25
|
<div className="HeaderThumbnail__icon">
|
|
27
|
-
<FlowStepIcon mode={
|
|
26
|
+
<FlowStepIcon mode={lhr.gatherMode}/>
|
|
28
27
|
</div>
|
|
29
28
|
</div>
|
|
30
29
|
);
|
|
31
30
|
};
|
|
32
31
|
|
|
33
|
-
export const Header: FunctionComponent<{
|
|
34
|
-
({
|
|
32
|
+
export const Header: FunctionComponent<{hashState: LH.FlowResult.HashState}> =
|
|
33
|
+
({hashState}) => {
|
|
35
34
|
const flowResult = useFlowResult();
|
|
36
|
-
const {index} =
|
|
35
|
+
const {index} = hashState;
|
|
37
36
|
|
|
38
37
|
const step = flowResult.steps[index];
|
|
39
38
|
const prevStep = flowResult.steps[index - 1];
|
|
40
39
|
const nextStep = flowResult.steps[index + 1];
|
|
41
40
|
|
|
42
|
-
const strings =
|
|
41
|
+
const strings = useLocalizedStrings();
|
|
43
42
|
const modeDescription = getModeDescription(step.lhr.gatherMode, strings);
|
|
44
43
|
|
|
45
44
|
return (
|
|
@@ -50,7 +49,7 @@ export const Header: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
|
|
|
50
49
|
flowResult.steps[index - 2] && <div className="Header__segment"/>
|
|
51
50
|
}
|
|
52
51
|
<div className="Header__prev-thumbnail">
|
|
53
|
-
<HeaderThumbnail
|
|
52
|
+
<HeaderThumbnail lhr={prevStep.lhr} position="prev"/>
|
|
54
53
|
<div className="Header__segment"/>
|
|
55
54
|
</div>
|
|
56
55
|
<a
|
|
@@ -60,7 +59,7 @@ export const Header: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
|
|
|
60
59
|
</>
|
|
61
60
|
}
|
|
62
61
|
<div className="Header__current-thumbnail">
|
|
63
|
-
<HeaderThumbnail
|
|
62
|
+
<HeaderThumbnail lhr={step.lhr} position="main"/>
|
|
64
63
|
</div>
|
|
65
64
|
<div className="Header__current-title">
|
|
66
65
|
{step.name}
|
|
@@ -72,7 +71,7 @@ export const Header: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
|
|
|
72
71
|
nextStep && <>
|
|
73
72
|
<div className="Header__next-thumbnail">
|
|
74
73
|
<div className="Header__segment"/>
|
|
75
|
-
<HeaderThumbnail
|
|
74
|
+
<HeaderThumbnail lhr={nextStep.lhr} position="next"/>
|
|
76
75
|
</div>
|
|
77
76
|
<a
|
|
78
77
|
className="Header__next-title"
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import {FunctionComponent, JSX} from 'preact';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {useLocalizedStrings} 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 = useLocalizedStrings();
|
|
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 = useLocalizedStrings();
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<div className="HelpDialog">
|
|
@@ -97,7 +97,6 @@ export const HelpDialog: FunctionComponent<{onClose: () => void}> = ({
|
|
|
97
97
|
availableCategories={[
|
|
98
98
|
strings.categoryPerformance,
|
|
99
99
|
strings.categoryBestPractices,
|
|
100
|
-
strings.categorySeo,
|
|
101
100
|
]}
|
|
102
101
|
/>
|
|
103
102
|
<HelpDialogColumn
|