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.
Files changed (209) hide show
  1. package/dist/report/bundle.esm.js +5994 -0
  2. package/dist/report/flow.js +30 -13
  3. package/dist/report/standalone.js +41 -35
  4. package/flow-report/.eslintrc.cjs +2 -0
  5. package/flow-report/assets/standalone-flow-template.html +3 -2
  6. package/flow-report/assets/styles.css +108 -31
  7. package/flow-report/src/app.tsx +18 -18
  8. package/flow-report/src/common.tsx +28 -15
  9. package/flow-report/src/header.tsx +12 -13
  10. package/flow-report/src/help-dialog.tsx +3 -4
  11. package/flow-report/src/i18n/i18n.tsx +57 -16
  12. package/flow-report/src/i18n/ui-strings.js +50 -0
  13. package/flow-report/src/icons.tsx +36 -8
  14. package/flow-report/src/sidebar/flow.tsx +3 -3
  15. package/flow-report/src/sidebar/sidebar.tsx +35 -14
  16. package/flow-report/src/summary/category.tsx +97 -24
  17. package/flow-report/src/summary/summary.tsx +21 -14
  18. package/flow-report/src/topbar.tsx +9 -5
  19. package/flow-report/src/util.ts +33 -26
  20. package/flow-report/src/wrappers/category-score.tsx +0 -3
  21. package/flow-report/src/wrappers/markdown.tsx +27 -0
  22. package/flow-report/src/wrappers/report-renderer.tsx +10 -3
  23. package/flow-report/src/wrappers/report.tsx +27 -6
  24. package/flow-report/standalone-flow.tsx +4 -3
  25. package/flow-report/test/common-test.tsx +32 -17
  26. package/flow-report/test/flow-report-pptr-test.ts +46 -0
  27. package/flow-report/test/header-test.tsx +6 -6
  28. package/flow-report/test/setup/env-setup.ts +1 -1
  29. package/flow-report/test/sidebar/sidebar-test.tsx +43 -1
  30. package/flow-report/test/summary/category-test.tsx +120 -24
  31. package/flow-report/test/summary/summary-test.tsx +1 -1
  32. package/flow-report/test/topbar-test.tsx +1 -0
  33. package/flow-report/test/util-test.tsx +32 -11
  34. package/flow-report/test/wrappers/category-score-test.tsx +87 -0
  35. package/flow-report/test/wrappers/markdown-test.tsx +29 -0
  36. package/flow-report/tsconfig.json +1 -0
  37. package/jest.config.js +4 -2
  38. package/lighthouse-cli/.eslintrc.cjs +2 -0
  39. package/lighthouse-cli/cli-flags.js +1 -1
  40. package/lighthouse-cli/run.js +1 -1
  41. package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +0 -0
  42. package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +4 -2
  43. package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +1 -1
  44. package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
  45. package/lighthouse-core/audits/accessibility/axe-audit.js +7 -1
  46. package/lighthouse-core/audits/audit.js +1 -1
  47. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +2 -0
  48. package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +4 -2
  49. package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +11 -10
  50. package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +5 -3
  51. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +2 -1
  52. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +2 -1
  53. package/lighthouse-core/audits/deprecations.js +33 -11
  54. package/lighthouse-core/audits/dobetterweb/uses-http2.js +27 -11
  55. package/lighthouse-core/audits/errors-in-console.js +0 -2
  56. package/lighthouse-core/audits/image-aspect-ratio.js +5 -5
  57. package/lighthouse-core/audits/image-size-responsive.js +6 -6
  58. package/lighthouse-core/audits/installable-manifest.js +5 -3
  59. package/lighthouse-core/audits/preload-lcp-image.js +7 -5
  60. package/lighthouse-core/audits/script-treemap-data.js +1 -1
  61. package/lighthouse-core/audits/unsized-images.js +2 -3
  62. package/lighthouse-core/computed/image-records.js +4 -3
  63. package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +3 -4
  64. package/lighthouse-core/computed/metrics/tbt-utils.js +57 -0
  65. package/lighthouse-core/computed/metrics/total-blocking-time.js +3 -53
  66. package/lighthouse-core/computed/resource-summary.js +1 -1
  67. package/lighthouse-core/config/config-helpers.js +21 -10
  68. package/lighthouse-core/config/constants.js +3 -4
  69. package/lighthouse-core/config/default-config.js +61 -71
  70. package/lighthouse-core/fraggle-rock/config/config.js +1 -1
  71. package/lighthouse-core/fraggle-rock/config/default-config.js +4 -5
  72. package/lighthouse-core/fraggle-rock/gather/base-gatherer.js +6 -1
  73. package/lighthouse-core/fraggle-rock/gather/session.js +3 -4
  74. package/lighthouse-core/gather/connections/cri.js +1 -1
  75. package/lighthouse-core/gather/driver/storage.js +0 -1
  76. package/lighthouse-core/gather/driver.js +3 -7
  77. package/lighthouse-core/gather/fetcher.js +4 -7
  78. package/lighthouse-core/gather/gather-runner.js +29 -6
  79. package/lighthouse-core/gather/gatherers/accessibility.js +27 -0
  80. package/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js +1 -0
  81. package/lighthouse-core/gather/gatherers/image-elements.js +0 -3
  82. package/lighthouse-core/gather/gatherers/inspector-issues.js +5 -0
  83. package/lighthouse-core/lib/asset-saver.js +7 -4
  84. package/lighthouse-core/lib/emulation.js +45 -1
  85. package/lighthouse-core/lib/i18n/i18n.js +19 -8
  86. package/lighthouse-core/lib/lh-env.js +2 -0
  87. package/lighthouse-core/lib/proto-preprocessor.js +14 -2
  88. package/lighthouse-core/lib/tappable-rects.js +8 -15
  89. package/lighthouse-core/lib/url-shim.js +1 -1
  90. package/lighthouse-core/runner.js +1 -1
  91. package/lighthouse-core/util-commonjs.js +65 -46
  92. package/package.json +27 -17
  93. package/readme.md +3 -3
  94. package/report/.eslintrc.cjs +2 -0
  95. package/report/README.md +1 -1
  96. package/report/assets/standalone-template.html +2 -3
  97. package/report/assets/styles.css +360 -254
  98. package/report/assets/templates.html +21 -76
  99. package/report/clients/bundle.js +1 -0
  100. package/report/clients/standalone.js +6 -15
  101. package/report/generator/README.md +1 -1
  102. package/report/renderer/api.js +32 -0
  103. package/report/renderer/category-renderer.js +59 -19
  104. package/report/renderer/components.js +59 -110
  105. package/report/renderer/crc-details-renderer.js +15 -12
  106. package/report/renderer/dom.js +16 -1
  107. package/report/renderer/drop-down-menu.js +2 -2
  108. package/report/renderer/element-screenshot-renderer.js +8 -8
  109. package/report/renderer/features-util.js +1 -1
  110. package/report/renderer/open-tab.js +9 -3
  111. package/report/renderer/performance-category-renderer.js +55 -34
  112. package/report/renderer/pwa-category-renderer.js +0 -10
  113. package/report/renderer/report-renderer.js +91 -44
  114. package/report/renderer/report-ui-features.js +36 -33
  115. package/report/renderer/swap-locale-feature.js +3 -3
  116. package/report/renderer/topbar-features.js +53 -48
  117. package/report/renderer/util.js +66 -46
  118. package/report/test/clients/bundle-test.js +70 -0
  119. package/report/test/renderer/category-renderer-test.js +48 -3
  120. package/report/test/renderer/i18n-test.js +0 -7
  121. package/report/test/renderer/performance-category-renderer-test.js +51 -14
  122. package/report/test/renderer/pwa-category-renderer-test.js +6 -6
  123. package/report/test/renderer/report-renderer-axe-test.js +10 -12
  124. package/report/test/renderer/report-renderer-test.js +23 -22
  125. package/report/test/renderer/report-ui-features-test.js +20 -10
  126. package/report/test/renderer/text-encoding-test.js +1 -1
  127. package/report/test/renderer/util-test.js +35 -31
  128. package/report/test-assets/faux-psi-template.html +3 -11
  129. package/report/test-assets/faux-psi.js +26 -22
  130. package/report/types/html-renderer.d.ts +2 -0
  131. package/report/types/report-renderer.d.ts +23 -0
  132. package/shared/localization/format.js +64 -30
  133. package/shared/localization/locales/ar-XB.json +72 -75
  134. package/shared/localization/locales/ar.json +72 -75
  135. package/shared/localization/locales/bg.json +72 -75
  136. package/shared/localization/locales/ca.json +72 -75
  137. package/shared/localization/locales/cs.json +89 -92
  138. package/shared/localization/locales/da.json +72 -75
  139. package/shared/localization/locales/de.json +89 -92
  140. package/shared/localization/locales/el.json +72 -75
  141. package/shared/localization/locales/en-GB.json +72 -75
  142. package/shared/localization/locales/en-US.json +75 -75
  143. package/shared/localization/locales/en-XA.json +72 -75
  144. package/shared/localization/locales/en-XL.json +75 -75
  145. package/shared/localization/locales/es-419.json +90 -93
  146. package/shared/localization/locales/es.json +90 -93
  147. package/shared/localization/locales/fi.json +72 -75
  148. package/shared/localization/locales/fil.json +72 -75
  149. package/shared/localization/locales/fr.json +89 -92
  150. package/shared/localization/locales/he.json +73 -76
  151. package/shared/localization/locales/hi.json +72 -75
  152. package/shared/localization/locales/hr.json +72 -75
  153. package/shared/localization/locales/hu.json +89 -92
  154. package/shared/localization/locales/id.json +89 -92
  155. package/shared/localization/locales/it.json +89 -92
  156. package/shared/localization/locales/ja.json +89 -92
  157. package/shared/localization/locales/ko.json +89 -92
  158. package/shared/localization/locales/lt.json +89 -92
  159. package/shared/localization/locales/lv.json +95 -98
  160. package/shared/localization/locales/nl.json +89 -92
  161. package/shared/localization/locales/no.json +72 -75
  162. package/shared/localization/locales/pl.json +72 -75
  163. package/shared/localization/locales/pt-PT.json +72 -75
  164. package/shared/localization/locales/pt.json +89 -92
  165. package/shared/localization/locales/ro.json +90 -93
  166. package/shared/localization/locales/ru.json +89 -92
  167. package/shared/localization/locales/sk.json +89 -92
  168. package/shared/localization/locales/sl.json +89 -92
  169. package/shared/localization/locales/sr-Latn.json +89 -92
  170. package/shared/localization/locales/sr.json +89 -92
  171. package/shared/localization/locales/sv.json +72 -75
  172. package/shared/localization/locales/ta.json +89 -92
  173. package/shared/localization/locales/te.json +89 -92
  174. package/shared/localization/locales/th.json +89 -92
  175. package/shared/localization/locales/tr.json +89 -92
  176. package/shared/localization/locales/uk.json +92 -95
  177. package/shared/localization/locales/vi.json +89 -92
  178. package/shared/localization/locales/zh-HK.json +89 -92
  179. package/shared/localization/locales/zh-TW.json +89 -92
  180. package/shared/localization/locales/zh.json +89 -92
  181. package/shared/localization/locales.js +6 -0
  182. package/shared/test/localization/format-test.js +45 -9
  183. package/shared/test/localization/swap-locale-test.js +0 -12
  184. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +19 -11
  185. package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
  186. package/third-party/download-content-shell/download-content-shell.js +2 -2
  187. package/third-party/download-content-shell/utils.js +0 -24
  188. package/tsconfig-all.json +2 -2
  189. package/tsconfig.json +0 -1
  190. package/types/artifacts.d.ts +7 -7
  191. package/types/enquirer.d.ts +3 -1
  192. package/types/lhr/audit-details.d.ts +6 -5
  193. package/types/lhr/flow.d.ts +3 -2
  194. package/types/lhr/lhr.d.ts +1 -1
  195. package/types/node.d.ts +5 -5
  196. package/types/rollup-plugin-postprocess.d.ts +10 -0
  197. package/changelog.md +0 -5490
  198. package/lighthouse-core/audits/dobetterweb/appcache-manifest.js +0 -67
  199. package/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js +0 -96
  200. package/lighthouse-core/audits/redirects-http.js +0 -59
  201. package/lighthouse-core/gather/gatherers/dobetterweb/appcache.js +0 -34
  202. package/lighthouse-core/gather/gatherers/http-redirect.js +0 -46
  203. package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +0 -6699
  204. package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +0 -6672
  205. package/lighthouse-core/scripts/package.json +0 -4
  206. package/report/clients/psi.js +0 -158
  207. package/report/test/clients/psi-test.js +0 -143
  208. package/shared/localization/locales/en-US.ctc.json +0 -6877
  209. package/shared/localization/locales/en-XL.ctc.json +0 -6852
@@ -52,8 +52,9 @@ limitations under the License.
52
52
 
53
53
  <!-- Lighthouse clump -->
54
54
  <template id="clump">
55
+ <div class="lh-audit-group">
55
56
  <!-- TODO: group classes shouldn't be reused for clumps. -->
56
- <details class="lh-clump lh-audit-group">
57
+ <details class="lh-clump">
57
58
  <summary>
58
59
  <div class="lh-audit-group__summary">
59
60
  <div class="lh-audit-group__header">
@@ -62,27 +63,13 @@ limitations under the License.
62
63
  <!-- .lh-audit-group__description will be added here -->
63
64
  <!-- .lh-metrics-toggle will be added here -->
64
65
  </div>
66
+ <div class="lh-clump-toggle">
67
+ <span class="lh-clump-toggletext--show"></span>
68
+ <span class="lh-clump-toggletext--hide"></span>
69
+ </div>
65
70
  </div>
66
71
  </summary>
67
72
  </details>
68
- </template>
69
-
70
- <!-- Lighthouse metrics toggle -->
71
- <template id="metricsToggle">
72
- <div class="lh-metrics-toggle">
73
- <input class="lh-metrics-toggle__input" type="checkbox" id="toggle-metric-descriptions" aria-label="Toggle the display of metric descriptions">
74
- <label class="lh-metrics-toggle__label" for="toggle-metric-descriptions">
75
- <div class="lh-metrics-toggle__icon lh-metrics-toggle__icon--less" aria-hidden="true">
76
- <svg width="24" height="24" viewBox="0 0 24 24">
77
- <path class="lh-metrics-toggle__lines" d="M4 9h16v2H4zm0 4h10v2H4z" />
78
- </svg>
79
- </div>
80
- <div class="lh-metrics-toggle__icon lh-metrics-toggle__icon--more" aria-hidden="true">
81
- <svg width="24" height="24" viewBox="0 0 24 24">
82
- <path class="lh-metrics-toggle__lines" d="M3 18h12v-2H3v2zM3 6v2h18V6H3zm0 7h18v-2H3v2z" />
83
- </svg>
84
- </div>
85
- </label>
86
73
  </div>
87
74
  </template>
88
75
 
@@ -123,7 +110,7 @@ limitations under the License.
123
110
  <div class="lh-audit lh-audit--load-opportunity">
124
111
  <details class="lh-expandable-details">
125
112
  <summary>
126
- <div class="lh-audit__header lh-expandable-details__summary">
113
+ <div class="lh-audit__header">
127
114
  <div class="lh-load-opportunity__cols">
128
115
  <div class="lh-load-opportunity__col lh-load-opportunity__col--one">
129
116
  <span class="lh-audit__score-icon"></span>
@@ -159,14 +146,14 @@ limitations under the License.
159
146
  .lh-scores-container {
160
147
  display: flex;
161
148
  flex-direction: column;
162
- padding: var(--scores-container-padding);
149
+ padding: var(--default-padding) 0;
163
150
  position: relative;
164
151
  width: 100%;
165
152
  }
166
153
 
167
154
  .lh-sticky-header {
168
155
  --gauge-circle-size: var(--gauge-circle-size-sm);
169
- --plugin-badge-size: 18px;
156
+ --plugin-badge-size: 16px;
170
157
  --plugin-icon-size: 75%;
171
158
  --gauge-wrapper-width: 60px;
172
159
  --gauge-percentage-font-size: 13px;
@@ -174,7 +161,7 @@ limitations under the License.
174
161
  left: 0;
175
162
  right: 0;
176
163
  top: var(--topbar-height);
177
- font-weight: 700;
164
+ font-weight: 500;
178
165
  display: none;
179
166
  justify-content: center;
180
167
  background-color: var(--sticky-header-background-color);
@@ -242,8 +229,10 @@ limitations under the License.
242
229
  display: flex;
243
230
  align-items: center;
244
231
  height: var(--topbar-height);
245
- background-color: var(--topbar-background-color);
246
232
  padding: var(--topbar-padding);
233
+ font-size: var(--report-font-size-secondary);
234
+ background-color: var(--topbar-background-color);
235
+ border-bottom: 1px solid var(--color-gray-200);
247
236
  }
248
237
 
249
238
  .lh-topbar__logo {
@@ -315,7 +304,7 @@ limitations under the License.
315
304
  color: currentColor;
316
305
  text-decoration: none;
317
306
  white-space: nowrap;
318
- padding: 0 12px;
307
+ padding: 0 6px;
319
308
  line-height: 2;
320
309
  }
321
310
  .lh-tools__dropdown a:hover,
@@ -345,13 +334,15 @@ limitations under the License.
345
334
  max-width: 200px;
346
335
  }
347
336
  .lh-button.lh-tool-locale__button {
348
- height: unset;
337
+ height: var(--topbar-height);
349
338
  color: var(--tools-icon-color);
339
+ padding: calc(var(--default-padding) / 2);
350
340
  }
351
341
  .lh-tool-locale__button.lh-active + .lh-tools-locale__selector-wrapper {
352
342
  opacity: 1;
353
343
  clip: rect(-1px, 194px, 242px, -3px);
354
344
  visibility: visible;
345
+ margin: 0 4px;
355
346
  }
356
347
 
357
348
  @media screen and (max-width: 964px) {
@@ -521,53 +512,16 @@ limitations under the License.
521
512
  <style>
522
513
  .lh-footer {
523
514
  padding: var(--footer-padding-vertical) calc(var(--default-padding) * 2);
524
- max-width: var(--report-width);
515
+ max-width: var(--report-content-width);
525
516
  margin: 0 auto;
526
517
  }
527
518
  .lh-footer .lh-generated {
528
519
  text-align: center;
529
520
  }
530
- .lh-env__title {
531
- font-size: var(--env-item-font-size-big);
532
- line-height: var(--env-item-line-height-big);
533
- text-align: center;
534
- padding: var(--score-container-padding);
535
- }
536
- .lh-env {
537
- padding: var(--default-padding) 0;
538
- }
539
- .lh-env__items {
540
- padding-left: 16px;
541
- margin: 0 0 var(--audits-margin-bottom);
542
- padding: 0;
543
- }
544
- .lh-env__items .lh-env__item:nth-child(2n) {
545
- background-color: var(--env-item-background-color);
546
- }
547
- .lh-env__item {
548
- display: flex;
549
- padding: var(--env-item-padding);
550
- position: relative;
551
- }
552
- span.lh-env__name {
553
- font-weight: bold;
554
- min-width: var(--env-name-min-width);
555
- flex: 0.5;
556
- padding: 0 8px;
557
- }
558
- span.lh-env__description {
559
- text-align: left;
560
- flex: 1;
561
- }
562
521
  </style>
563
522
  <footer class="lh-footer">
564
- <!-- TODO(i18n): localize runtime settings -->
565
- <div class="lh-env">
566
- <div class="lh-env__title">Runtime Settings</div>
567
- <ul class="lh-env__items">
568
- <!-- envItem -->
569
- </ul>
570
- </div>
523
+ <ul class="lh-meta__items">
524
+ </ul>
571
525
 
572
526
  <div class="lh-generated">
573
527
  <!-- TODO(i18n): use ICU replacement to replace version w/o concatenation. -->
@@ -577,14 +531,6 @@ limitations under the License.
577
531
  </footer>
578
532
  </template>
579
533
 
580
- <!-- Lighthouse footer env item -->
581
- <template id="envItem">
582
- <li class="lh-env__item">
583
- <span class="lh-env__name"></span>
584
- <span class="lh-env__description"></span>
585
- </li>
586
- </template>
587
-
588
534
  <!-- Lighthouse score gauge -->
589
535
  <template id="gauge">
590
536
  <a class="lh-gauge__wrapper">
@@ -784,10 +730,9 @@ limitations under the License.
784
730
  <template id="3pFilter">
785
731
  <style>
786
732
  .lh-3p-filter {
787
- background-color: var(--table-higlight-background-color);
788
733
  color: var(--color-gray-600);
789
734
  float: right;
790
- padding: 6px;
735
+ padding: 6px var(--stackpack-padding-horizontal);
791
736
  }
792
737
  .lh-3p-filter-label, .lh-3p-filter-input {
793
738
  vertical-align: middle;
@@ -15,3 +15,4 @@
15
15
  export {DOM} from '../renderer/dom.js';
16
16
  export {ReportRenderer} from '../renderer/report-renderer.js';
17
17
  export {ReportUIFeatures} from '../renderer/report-ui-features.js';
18
+ export {renderReport} from '../renderer/api.js';
@@ -13,26 +13,16 @@
13
13
 
14
14
  /* global ga */
15
15
 
16
- import {DOM} from '../renderer/dom.js';
16
+ import {renderReport} from '../renderer/api.js';
17
17
  import {Logger} from '../renderer/logger.js';
18
- import {ReportRenderer} from '../renderer/report-renderer.js';
19
- import {ReportUIFeatures} from '../renderer/report-ui-features.js';
20
18
 
21
- // Used by standalone.html
22
- // eslint-disable-next-line no-unused-vars
23
19
  function __initLighthouseReport__() {
24
- const dom = new DOM(document);
25
- const renderer = new ReportRenderer(dom);
26
- const container = dom.find('main', document);
27
- /** @type {LH.ReportResult} */
20
+ /** @type {LH.Result} */
28
21
  // @ts-expect-error
29
22
  const lhr = window.__LIGHTHOUSE_JSON__;
30
- renderer.renderReport(lhr, container);
31
23
 
32
- // Hook in JS features and page-level event listeners after the report
33
- // is in the document.
34
- const features = new ReportUIFeatures(dom);
35
- features.initFeatures(lhr);
24
+ const reportRootEl = renderReport(lhr);
25
+ document.body.append(reportRootEl);
36
26
 
37
27
  document.addEventListener('lh-analytics', /** @param {Event} e */ e => {
38
28
  // @ts-expect-error
@@ -40,7 +30,8 @@ function __initLighthouseReport__() {
40
30
  });
41
31
 
42
32
  document.addEventListener('lh-log', /** @param {Event} e */ e => {
43
- const el = dom.find('div#lh-log', document);
33
+ const el = document.querySelector('div#lh-log');
34
+ if (!el) return;
44
35
 
45
36
  const logger = new Logger(el);
46
37
  // @ts-expect-error
@@ -4,6 +4,6 @@
4
4
 
5
5
  Lighthouse's report generator is the entry point for creating reports from an **LHR** (Lighthouse Result object). It returns results as HTML, JSON, and CSV.
6
6
 
7
- It runs natively in Node.js but can run in the browser after a compile step is applied during our bundling pipeline. That compile step uses `brfs`, which takes any `fs.readFileSync()` calls and replaces them with the stringified file content.
7
+ It runs natively in Node.js but can run in the browser after a compile step is applied during our bundling pipeline. That compile step uses `inline-fs`, which takes any `fs.readFileSync()` calls and replaces them with the stringified file content.
8
8
 
9
9
  Because it's shared between core and the report, dependencies (both code and types) should be kept minimal.
@@ -0,0 +1,32 @@
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
+ 'use strict';
7
+
8
+
9
+ import {DOM} from '../renderer/dom.js';
10
+ import {ReportRenderer} from '../renderer/report-renderer.js';
11
+ import {ReportUIFeatures} from '../renderer/report-ui-features.js';
12
+
13
+ /**
14
+ * @param {LH.Result} lhr
15
+ * @param {LH.Renderer.Options} opts
16
+ * @return {HTMLElement}
17
+ */
18
+ export function renderReport(lhr, opts = {}) {
19
+ const rootEl = document.createElement('article');
20
+ rootEl.classList.add('lh-root', 'lh-vars');
21
+
22
+ const dom = new DOM(rootEl.ownerDocument, rootEl);
23
+ const renderer = new ReportRenderer(dom);
24
+
25
+ renderer.renderReport(lhr, rootEl, opts);
26
+
27
+ // Hook in JS features and page-level event listeners after the report
28
+ // is in the document.
29
+ const features = new ReportUIFeatures(dom, opts);
30
+ features.initFeatures(lhr);
31
+ return rootEl;
32
+ }
@@ -133,7 +133,7 @@ export class CategoryRenderer {
133
133
  const warningsEl = this.dom.createChildOf(summaryEl, 'div', 'lh-warnings');
134
134
  this.dom.createChildOf(warningsEl, 'span').textContent = strings.warningHeader;
135
135
  if (warnings.length === 1) {
136
- warningsEl.appendChild(this.dom.document().createTextNode(warnings.join('')));
136
+ warningsEl.appendChild(this.dom.createTextNode(warnings.join('')));
137
137
  } else {
138
138
  const warningsUl = this.dom.createChildOf(warningsEl, 'ul');
139
139
  for (const warning of warnings) {
@@ -144,6 +144,35 @@ export class CategoryRenderer {
144
144
  return auditEl;
145
145
  }
146
146
 
147
+ /**
148
+ * Inject the final screenshot next to the score gauge of the first category (likely Performance)
149
+ * @param {HTMLElement} categoriesEl
150
+ * @param {LH.ReportResult['audits']} audits
151
+ * @param {Element} scoreScaleEl
152
+ */
153
+ injectFinalScreenshot(categoriesEl, audits, scoreScaleEl) {
154
+ const audit = audits['final-screenshot'];
155
+ if (!audit || audit.scoreDisplayMode === 'error') return null;
156
+ if (!audit.details || audit.details.type !== 'screenshot') return null;
157
+
158
+ const imgEl = this.dom.createElement('img', 'lh-final-ss-image');
159
+ const finalScreenshotDataUri = audit.details.data;
160
+ imgEl.src = finalScreenshotDataUri;
161
+ imgEl.alt = audit.title;
162
+
163
+ const firstCatHeaderEl = this.dom.find('.lh-category .lh-category-header', categoriesEl);
164
+ const leftColEl = this.dom.createElement('div', 'lh-category-headercol');
165
+ const separatorEl = this.dom.createElement('div',
166
+ 'lh-category-headercol lh-category-headercol--separator');
167
+ const rightColEl = this.dom.createElement('div', 'lh-category-headercol');
168
+
169
+ leftColEl.append(...firstCatHeaderEl.childNodes);
170
+ leftColEl.append(scoreScaleEl);
171
+ rightColEl.append(imgEl);
172
+ firstCatHeaderEl.append(leftColEl, separatorEl, rightColEl);
173
+ firstCatHeaderEl.classList.add('lh-category-header__finalscreenshot');
174
+ }
175
+
147
176
  /**
148
177
  * @return {Element}
149
178
  */
@@ -193,7 +222,7 @@ export class CategoryRenderer {
193
222
  * Renders the group container for a group of audits. Individual audit elements can be added
194
223
  * directly to the returned element.
195
224
  * @param {LH.Result.ReportGroup} group
196
- * @return {Element}
225
+ * @return {[Element, Element | null]}
197
226
  */
198
227
  renderAuditGroup(group) {
199
228
  const groupEl = this.dom.createElement('div', 'lh-audit-group');
@@ -202,14 +231,16 @@ export class CategoryRenderer {
202
231
 
203
232
  this.dom.createChildOf(auditGroupHeader, 'span', 'lh-audit-group__title')
204
233
  .textContent = group.title;
234
+ groupEl.appendChild(auditGroupHeader);
235
+
236
+ let footerEl = null;
205
237
  if (group.description) {
206
- const descriptionEl = this.dom.convertMarkdownLinkSnippets(group.description);
207
- descriptionEl.classList.add('lh-audit-group__description');
208
- auditGroupHeader.appendChild(descriptionEl);
238
+ footerEl = this.dom.convertMarkdownLinkSnippets(group.description);
239
+ footerEl.classList.add('lh-audit-group__description', 'lh-audit-group__footer');
240
+ groupEl.appendChild(footerEl);
209
241
  }
210
- groupEl.appendChild(auditGroupHeader);
211
242
 
212
- return groupEl;
243
+ return [groupEl, footerEl];
213
244
  }
214
245
 
215
246
  /**
@@ -249,9 +280,9 @@ export class CategoryRenderer {
249
280
 
250
281
  // Push grouped audits as a group.
251
282
  const groupDef = groupDefinitions[groupId];
252
- const auditGroupElem = this.renderAuditGroup(groupDef);
283
+ const [auditGroupElem, auditGroupFooterEl] = this.renderAuditGroup(groupDef);
253
284
  for (const auditRef of groupAuditRefs) {
254
- auditGroupElem.appendChild(this.renderAudit(auditRef));
285
+ auditGroupElem.insertBefore(this.renderAudit(auditRef), auditGroupFooterEl);
255
286
  }
256
287
  auditGroupElem.classList.add(`lh-audit-group--${groupId}`);
257
288
  auditElements.push(auditGroupElem);
@@ -289,17 +320,9 @@ export class CategoryRenderer {
289
320
  clumpElement.setAttribute('open', '');
290
321
  }
291
322
 
292
- const summaryInnerEl = this.dom.find('div.lh-audit-group__summary', clumpElement);
293
- summaryInnerEl.appendChild(this._createChevron());
294
-
295
323
  const headerEl = this.dom.find('.lh-audit-group__header', clumpElement);
296
324
  const title = this._clumpTitles[clumpId];
297
325
  this.dom.find('.lh-audit-group__title', headerEl).textContent = title;
298
- if (description) {
299
- const descriptionEl = this.dom.convertMarkdownLinkSnippets(description);
300
- descriptionEl.classList.add('lh-audit-group__description');
301
- headerEl.appendChild(descriptionEl);
302
- }
303
326
 
304
327
  const itemCountEl = this.dom.find('.lh-audit-group__itemcount', clumpElement);
305
328
  itemCountEl.textContent = `(${auditRefs.length})`;
@@ -308,8 +331,18 @@ export class CategoryRenderer {
308
331
  const auditElements = auditRefs.map(this.renderAudit.bind(this));
309
332
  clumpElement.append(...auditElements);
310
333
 
334
+ const el = this.dom.find('.lh-audit-group', clumpComponent);
335
+ if (description) {
336
+ const descriptionEl = this.dom.convertMarkdownLinkSnippets(description);
337
+ descriptionEl.classList.add('lh-audit-group__description', 'lh-audit-group__footer');
338
+ el.appendChild(descriptionEl);
339
+ }
340
+
341
+ this.dom.find('.lh-clump-toggletext--show', el).textContent = Util.i18n.strings.show;
342
+ this.dom.find('.lh-clump-toggletext--hide', el).textContent = Util.i18n.strings.hide;
343
+
311
344
  clumpElement.classList.add(`lh-clump--${clumpId.toLowerCase()}`);
312
- return clumpElement;
345
+ return el;
313
346
  }
314
347
 
315
348
  /**
@@ -478,7 +511,7 @@ export class CategoryRenderer {
478
511
  * ⋮
479
512
  * @param {LH.ReportResult.Category} category
480
513
  * @param {Object<string, LH.Result.ReportGroup>=} groupDefinitions
481
- * @param {{environment?: 'PSI', gatherMode: LH.Result.GatherMode}=} options
514
+ * @param {{gatherMode: LH.Result.GatherMode}=} options
482
515
  * @return {Element}
483
516
  */
484
517
  render(category, groupDefinitions = {}, options) {
@@ -503,6 +536,13 @@ export class CategoryRenderer {
503
536
  clumps.set(clumpId, clump);
504
537
  }
505
538
 
539
+ // Sort audits by weight.
540
+ for (const auditRefs of clumps.values()) {
541
+ auditRefs.sort((a, b) => {
542
+ return b.weight - a.weight;
543
+ });
544
+ }
545
+
506
546
  // Render each clump.
507
547
  for (const [clumpId, auditRefs] of clumps) {
508
548
  if (auditRefs.length === 0) continue;