lighthouse 9.5.0-dev.20230123 → 9.5.0-dev.20230125

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 (167) hide show
  1. package/.codecov.yml +0 -5
  2. package/core/audits/accessibility/accesskeys.js +1 -1
  3. package/core/audits/accessibility/aria-allowed-attr.js +1 -1
  4. package/core/audits/accessibility/aria-command-name.js +1 -1
  5. package/core/audits/accessibility/aria-hidden-body.js +1 -1
  6. package/core/audits/accessibility/aria-hidden-focus.js +1 -1
  7. package/core/audits/accessibility/aria-input-field-name.js +1 -1
  8. package/core/audits/accessibility/aria-meter-name.js +1 -1
  9. package/core/audits/accessibility/aria-progressbar-name.js +1 -1
  10. package/core/audits/accessibility/aria-required-attr.js +1 -1
  11. package/core/audits/accessibility/aria-required-children.js +1 -1
  12. package/core/audits/accessibility/aria-required-parent.js +1 -1
  13. package/core/audits/accessibility/aria-roles.js +1 -1
  14. package/core/audits/accessibility/aria-toggle-field-name.js +1 -1
  15. package/core/audits/accessibility/aria-tooltip-name.js +1 -1
  16. package/core/audits/accessibility/aria-treeitem-name.js +1 -1
  17. package/core/audits/accessibility/aria-valid-attr-value.js +1 -1
  18. package/core/audits/accessibility/aria-valid-attr.js +1 -1
  19. package/core/audits/accessibility/button-name.js +1 -1
  20. package/core/audits/accessibility/bypass.js +1 -1
  21. package/core/audits/accessibility/color-contrast.js +1 -1
  22. package/core/audits/accessibility/definition-list.js +1 -1
  23. package/core/audits/accessibility/dlitem.js +1 -1
  24. package/core/audits/accessibility/document-title.js +1 -1
  25. package/core/audits/accessibility/duplicate-id-active.js +1 -1
  26. package/core/audits/accessibility/duplicate-id-aria.js +1 -1
  27. package/core/audits/accessibility/form-field-multiple-labels.js +1 -1
  28. package/core/audits/accessibility/frame-title.js +1 -1
  29. package/core/audits/accessibility/heading-order.js +1 -1
  30. package/core/audits/accessibility/html-has-lang.js +1 -1
  31. package/core/audits/accessibility/html-lang-valid.js +1 -1
  32. package/core/audits/accessibility/image-alt.js +1 -1
  33. package/core/audits/accessibility/input-image-alt.js +1 -1
  34. package/core/audits/accessibility/label.js +1 -1
  35. package/core/audits/accessibility/link-name.js +1 -1
  36. package/core/audits/accessibility/list.js +1 -1
  37. package/core/audits/accessibility/listitem.js +1 -1
  38. package/core/audits/accessibility/meta-refresh.js +1 -1
  39. package/core/audits/accessibility/meta-viewport.js +1 -1
  40. package/core/audits/accessibility/object-alt.js +1 -1
  41. package/core/audits/accessibility/tabindex.js +1 -1
  42. package/core/audits/accessibility/td-headers-attr.js +1 -1
  43. package/core/audits/accessibility/th-has-data-cells.js +1 -1
  44. package/core/audits/accessibility/valid-lang.js +1 -1
  45. package/core/audits/accessibility/video-caption.js +1 -1
  46. package/core/audits/audit.js +1 -1
  47. package/core/audits/byte-efficiency/legacy-javascript.d.ts +1 -0
  48. package/core/audits/byte-efficiency/legacy-javascript.js +7 -3
  49. package/core/audits/dobetterweb/uses-http2.d.ts +5 -2
  50. package/core/audits/dobetterweb/uses-http2.js +12 -7
  51. package/core/audits/network-requests.js +7 -6
  52. package/core/audits/third-party-facades.d.ts +3 -2
  53. package/core/audits/third-party-facades.js +12 -9
  54. package/core/audits/third-party-summary.d.ts +7 -6
  55. package/core/audits/third-party-summary.js +16 -14
  56. package/core/audits/valid-source-maps.d.ts +5 -3
  57. package/core/audits/valid-source-maps.js +11 -9
  58. package/core/computed/entity-classification.d.ts +29 -0
  59. package/core/computed/entity-classification.js +102 -0
  60. package/core/computed/metrics/responsiveness.js +5 -2
  61. package/core/computed/page-dependency-graph.js +1 -1
  62. package/core/computed/resource-summary.d.ts +4 -2
  63. package/core/computed/resource-summary.js +8 -5
  64. package/core/gather/gatherers/accessibility.js +3 -1
  65. package/core/lib/network-request.d.ts +2 -0
  66. package/core/lib/network-request.js +3 -0
  67. package/core/lib/stack-packs.js +4 -0
  68. package/core/lib/tracehouse/trace-processor.d.ts +14 -5
  69. package/core/lib/tracehouse/trace-processor.js +85 -30
  70. package/core/lib/traces/metric-trace-events.js +1 -1
  71. package/core/lib/url-utils.js +1 -1
  72. package/core/runner.d.ts +10 -0
  73. package/core/runner.js +48 -0
  74. package/dist/report/bundle.esm.js +724 -687
  75. package/dist/report/flow.js +25 -15
  76. package/dist/report/standalone.js +25 -15
  77. package/flow-report/src/common.tsx +1 -1
  78. package/flow-report/src/i18n/i18n.tsx +17 -16
  79. package/flow-report/src/sidebar/sidebar.tsx +2 -2
  80. package/flow-report/src/summary/category.tsx +6 -6
  81. package/flow-report/src/summary/summary.tsx +2 -2
  82. package/package.json +7 -8
  83. package/report/renderer/category-renderer.js +19 -17
  84. package/report/renderer/crc-details-renderer.js +6 -6
  85. package/report/renderer/details-renderer.js +7 -6
  86. package/report/renderer/dom.js +1 -1
  87. package/report/renderer/element-screenshot-renderer.js +3 -3
  88. package/report/renderer/performance-category-renderer.js +17 -15
  89. package/report/renderer/pwa-category-renderer.js +5 -4
  90. package/report/renderer/report-globals.d.ts +21 -0
  91. package/report/renderer/report-globals.js +49 -0
  92. package/report/renderer/report-renderer.js +22 -20
  93. package/report/renderer/report-ui-features.js +9 -8
  94. package/report/renderer/report-utils.d.ts +116 -0
  95. package/report/renderer/{util.js → report-utils.js} +81 -429
  96. package/report/renderer/snippet-renderer.js +3 -2
  97. package/report/test/renderer/category-renderer-test.js +9 -4
  98. package/report/test/renderer/crc-details-renderer-test.js +7 -3
  99. package/report/test/renderer/details-renderer-test.js +7 -3
  100. package/report/test/renderer/dom-test.js +7 -3
  101. package/report/test/renderer/element-screenshot-renderer-test.js +8 -4
  102. package/report/test/renderer/performance-category-renderer-test.js +14 -9
  103. package/report/test/renderer/pwa-category-renderer-test.js +10 -5
  104. package/report/test/renderer/report-renderer-test.js +2 -2
  105. package/report/test/renderer/report-ui-features-test.js +3 -3
  106. package/report/test/renderer/{util-test.js → report-utils-test.js} +36 -234
  107. package/report/test/renderer/snippet-renderer-test.js +7 -3
  108. package/shared/localization/format.js +5 -2
  109. package/shared/localization/locales/ar-XB.json +50 -50
  110. package/shared/localization/locales/ar.json +50 -50
  111. package/shared/localization/locales/bg.json +50 -50
  112. package/shared/localization/locales/ca.json +50 -50
  113. package/shared/localization/locales/cs.json +50 -50
  114. package/shared/localization/locales/da.json +50 -50
  115. package/shared/localization/locales/de.json +50 -50
  116. package/shared/localization/locales/el.json +50 -50
  117. package/shared/localization/locales/en-GB.json +50 -50
  118. package/shared/localization/locales/en-US.json +128 -98
  119. package/shared/localization/locales/en-XA.json +50 -50
  120. package/shared/localization/locales/en-XL.json +128 -98
  121. package/shared/localization/locales/es-419.json +50 -50
  122. package/shared/localization/locales/es.json +50 -50
  123. package/shared/localization/locales/fi.json +50 -50
  124. package/shared/localization/locales/fil.json +50 -50
  125. package/shared/localization/locales/fr.json +50 -50
  126. package/shared/localization/locales/he.json +50 -50
  127. package/shared/localization/locales/hi.json +50 -50
  128. package/shared/localization/locales/hr.json +50 -50
  129. package/shared/localization/locales/hu.json +50 -50
  130. package/shared/localization/locales/id.json +50 -50
  131. package/shared/localization/locales/it.json +50 -50
  132. package/shared/localization/locales/ja.json +50 -50
  133. package/shared/localization/locales/ko.json +50 -50
  134. package/shared/localization/locales/lt.json +50 -50
  135. package/shared/localization/locales/lv.json +50 -50
  136. package/shared/localization/locales/nl.json +50 -50
  137. package/shared/localization/locales/no.json +50 -50
  138. package/shared/localization/locales/pl.json +50 -50
  139. package/shared/localization/locales/pt-PT.json +50 -50
  140. package/shared/localization/locales/pt.json +50 -50
  141. package/shared/localization/locales/ro.json +50 -50
  142. package/shared/localization/locales/ru.json +50 -50
  143. package/shared/localization/locales/sk.json +50 -50
  144. package/shared/localization/locales/sl.json +50 -50
  145. package/shared/localization/locales/sr-Latn.json +50 -50
  146. package/shared/localization/locales/sr.json +50 -50
  147. package/shared/localization/locales/sv.json +50 -50
  148. package/shared/localization/locales/ta.json +50 -50
  149. package/shared/localization/locales/te.json +50 -50
  150. package/shared/localization/locales/th.json +50 -50
  151. package/shared/localization/locales/tr.json +50 -50
  152. package/shared/localization/locales/uk.json +50 -50
  153. package/shared/localization/locales/vi.json +50 -50
  154. package/shared/localization/locales/zh-HK.json +50 -50
  155. package/shared/localization/locales/zh-TW.json +50 -50
  156. package/shared/localization/locales/zh.json +50 -50
  157. package/shared/test/util-test.js +214 -0
  158. package/shared/util.d.ts +122 -0
  159. package/shared/util.js +332 -0
  160. package/tsconfig.json +0 -2
  161. package/types/artifacts.d.ts +21 -2
  162. package/types/lhr/lhr.d.ts +33 -0
  163. package/core/lib/minify-trace.d.ts +0 -6
  164. package/core/lib/minify-trace.js +0 -172
  165. package/core/util.cjs +0 -845
  166. package/core/util.d.cts +0 -342
  167. package/report/renderer/util.d.ts +0 -342
@@ -9,7 +9,7 @@ import {useEffect, useState} from 'preact/hooks';
9
9
 
10
10
  import {NavigationIcon, SnapshotIcon, TimespanIcon} from './icons';
11
11
  import {getFilmstripFrames, getScreenDimensions} from './util';
12
- import {Util} from '../../report/renderer/util.js';
12
+ import {Util} from '../../shared/util.js';
13
13
 
14
14
  const ANIMATION_FRAME_DURATION_MS = 500;
15
15
 
@@ -12,11 +12,12 @@ import {I18nFormatter} from '../../../report/renderer/i18n-formatter';
12
12
  import {UIStrings} from './ui-strings';
13
13
  import {useFlowResult} from '../util';
14
14
  import strings from './localized-strings.js';
15
- import {Util} from '../../../report/renderer/util';
15
+ import {UIStrings as ReportUIStrings} from '../../../report/renderer/report-utils.js';
16
+ import {Globals} from '../../../report/renderer/report-globals.js';
16
17
 
17
18
  const I18nContext = createContext({
18
19
  formatter: new I18nFormatter('en-US'),
19
- strings: {...Util.UIStrings, ...UIStrings},
20
+ strings: {...ReportUIStrings, ...UIStrings},
20
21
  });
21
22
 
22
23
  function useLhrLocale() {
@@ -54,23 +55,23 @@ const I18nProvider: FunctionComponent = ({children}) => {
54
55
  const {locale, lhrStrings} = useLhrLocale();
55
56
 
56
57
  const i18n = useMemo(() => {
57
- Util.applyStrings({
58
- // Preload with strings from the first lhr.
59
- // Used for legacy report components imported into the flow report.
60
- ...lhrStrings,
61
- // Set any missing flow strings to default (english) values.
62
- ...UIStrings,
63
- // `strings` is generated in build/build-report.js
64
- ...strings[locale],
58
+ Globals.apply({
59
+ providedStrings: {
60
+ // Preload with strings from the first lhr.
61
+ // Used for legacy report components imported into the flow report.
62
+ ...lhrStrings,
63
+ // Set any missing flow strings to default (english) values.
64
+ ...UIStrings,
65
+ // `strings` is generated in build/build-report.js
66
+ ...strings[locale],
67
+ },
68
+ i18n: new I18nFormatter(locale),
69
+ reportJson: null,
65
70
  });
66
71
 
67
- // Initialize renderer util i18n for strings rendered in wrapped components.
68
- // TODO: Don't attach global formatter to `Util`.
69
- Util.i18n = new I18nFormatter(locale);
70
-
71
72
  return {
72
- formatter: Util.i18n,
73
- strings: Util.strings as typeof UIStrings & typeof Util.UIStrings,
73
+ formatter: Globals.i18n,
74
+ strings: Globals.strings as typeof UIStrings & typeof ReportUIStrings,
74
75
  };
75
76
  }, [locale, lhrStrings]);
76
77
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  import {FunctionComponent} from 'preact';
8
8
 
9
- import {Util} from '../../../report/renderer/util';
9
+ import {ReportUtils} from '../../../report/renderer/report-utils.js';
10
10
  import {Separator} from '../common';
11
11
  import {useI18n, useLocalizedStrings} from '../i18n/i18n';
12
12
  import {CpuIcon, EnvIcon, NetworkIcon, SummaryIcon} from '../icons';
@@ -34,7 +34,7 @@ const SidebarSummary: FunctionComponent = () => {
34
34
  const SidebarRuntimeSettings: FunctionComponent<{settings: LH.ConfigSettings}> =
35
35
  ({settings}) => {
36
36
  const strings = useLocalizedStrings();
37
- const env = Util.getEmulationDescriptions(settings);
37
+ const env = ReportUtils.getEmulationDescriptions(settings);
38
38
  const deviceEmulationString = env.screenEmulation ?
39
39
  `${env.deviceEmulation} - ${env.screenEmulation}` :
40
40
  env.deviceEmulation;
@@ -6,7 +6,7 @@
6
6
 
7
7
  import {FunctionComponent} from 'preact';
8
8
 
9
- import {Util} from '../../../report/renderer/util';
9
+ import {ReportUtils} from '../../../report/renderer/report-utils.js';
10
10
  import {Separator} from '../common';
11
11
  import {CategoryScore} from '../wrappers/category-score';
12
12
  import {useI18n, useStringFormatter, useLocalizedStrings} from '../i18n/i18n';
@@ -48,7 +48,7 @@ function getOverallSavings(audit: LH.ReportResult.AuditRef): number {
48
48
  }
49
49
 
50
50
  const SummaryTooltipAudit: FunctionComponent<{audit: LH.ReportResult.AuditRef}> = ({audit}) => {
51
- const rating = Util.calculateRating(audit.result.score, audit.result.scoreDisplayMode);
51
+ const rating = ReportUtils.calculateRating(audit.result.score, audit.result.scoreDisplayMode);
52
52
  return (
53
53
  <div className={`SummaryTooltipAudit SummaryTooltipAudit--${rating}`}>
54
54
  <Markdown text={audit.result.title}/>
@@ -69,7 +69,7 @@ const SummaryTooltipAudits: FunctionComponent<{category: LH.ReportResult.Categor
69
69
  // We don't want unweighted audits except for opportunities with potential savings.
70
70
  (audit.weight > 0 || getOverallSavings(audit) > 0) &&
71
71
  // Passing audits should never be high impact.
72
- !Util.showAsPassed(audit.result);
72
+ !ReportUtils.showAsPassed(audit.result);
73
73
  }
74
74
 
75
75
  const audits = category.auditRefs
@@ -107,14 +107,14 @@ const SummaryTooltip: FunctionComponent<{
107
107
  numPassableAudits,
108
108
  numInformative,
109
109
  totalWeight,
110
- } = Util.calculateCategoryFraction(category);
110
+ } = ReportUtils.calculateCategoryFraction(category);
111
111
 
112
112
  const i18n = useI18n();
113
- const displayAsFraction = Util.shouldDisplayAsFraction(gatherMode);
113
+ const displayAsFraction = ReportUtils.shouldDisplayAsFraction(gatherMode);
114
114
  const score = displayAsFraction ?
115
115
  numPassed / numPassableAudits :
116
116
  category.score;
117
- const rating = score === null ? 'error' : Util.calculateRating(score);
117
+ const rating = score === null ? 'error' : ReportUtils.calculateRating(score);
118
118
 
119
119
  return (
120
120
  <div className="SummaryTooltip">
@@ -9,7 +9,7 @@ import {useMemo} from 'preact/hooks';
9
9
 
10
10
  import {FlowSegment, FlowStepThumbnail, Separator} from '../common';
11
11
  import {getModeDescription, useFlowResult} from '../util';
12
- import {Util} from '../../../report/renderer/util';
12
+ import {ReportUtils} from '../../../report/renderer/report-utils.js';
13
13
  import {SummaryCategory} from './category';
14
14
  import {useStringFormatter, useLocalizedStrings} from '../i18n/i18n';
15
15
 
@@ -49,7 +49,7 @@ const SummaryFlowStep: FunctionComponent<{
49
49
  label: string,
50
50
  hashIndex: number,
51
51
  }> = ({lhr, label, hashIndex}) => {
52
- const reportResult = useMemo(() => Util.prepareReportResult(lhr), [lhr]);
52
+ const reportResult = useMemo(() => ReportUtils.prepareReportResult(lhr), [lhr]);
53
53
  const strings = useLocalizedStrings();
54
54
  const modeDescription = getModeDescription(lhr.gatherMode, strings);
55
55
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "9.5.0-dev.20230123",
4
+ "version": "9.5.0-dev.20230125",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
@@ -26,7 +26,7 @@
26
26
  "build-smokehouse-bundle": "node ./build/build-smokehouse-bundle.js",
27
27
  "build-lr": "yarn reset-link && node ./build/build-lightrider-bundles.js",
28
28
  "build-pack": "bash build/build-pack.sh",
29
- "build-report": "node build/build-report-components.js && bash core/scripts/copy-util-commonjs.sh && node build/build-report.js",
29
+ "build-report": "node build/build-report-components.js && node build/build-report.js",
30
30
  "build-sample-reports": "yarn build-report && node build/build-sample-reports.js",
31
31
  "build-treemap": "node ./build/build-treemap.js",
32
32
  "build-viewer": "node ./build/build-viewer.js",
@@ -86,7 +86,6 @@
86
86
  "diff:sample-json": "yarn i18n:checks && bash core/scripts/assert-golden-lhr-unchanged.sh",
87
87
  "diff:flow-sample-json": "yarn i18n:collect-strings && bash core/scripts/assert-baseline-flow-result-unchanged.sh",
88
88
  "computeBenchmarkIndex": "./core/scripts/benchmark.js",
89
- "minify-latest-run": "./core/scripts/lantern/minify-trace.js ./latest-run/defaultPass.trace.json ./latest-run/defaultPass.trace.min.json && ./core/scripts/lantern/minify-devtoolslog.js ./latest-run/defaultPass.devtoolslog.json ./latest-run/defaultPass.devtoolslog.min.json",
90
89
  "save-latest-run": "./core/scripts/save-latest-run.sh",
91
90
  "compile-proto": "protoc --python_out=./ ./proto/lighthouse-result.proto && mv ./proto/*_pb2.py ./proto/scripts || (echo \"❌ Install protobuf = 3.20.x to compile the proto file.\" && false)",
92
91
  "build-proto-roundtrip": "mkdir -p .tmp && python3 proto/scripts/json_roundtrip_via_proto.py",
@@ -169,7 +168,7 @@
169
168
  "pako": "^2.0.3",
170
169
  "preact": "^10.7.2",
171
170
  "pretty-json-stringify": "^0.0.2",
172
- "puppeteer": "^18.0.5",
171
+ "puppeteer": "^19.6.0",
173
172
  "resolve": "^1.20.0",
174
173
  "rollup": "^2.52.7",
175
174
  "rollup-plugin-node-resolve": "^5.2.0",
@@ -187,7 +186,7 @@
187
186
  },
188
187
  "dependencies": {
189
188
  "@sentry/node": "^6.17.4",
190
- "axe-core": "4.4.1",
189
+ "axe-core": "4.6.3",
191
190
  "chrome-launcher": "^0.15.1",
192
191
  "configstore": "^5.0.1",
193
192
  "csp_evaluator": "1.1.1",
@@ -195,16 +194,16 @@
195
194
  "http-link-header": "^0.8.0",
196
195
  "intl-messageformat": "^4.4.0",
197
196
  "jpeg-js": "^0.4.4",
198
- "js-library-detector": "^6.5.0",
197
+ "js-library-detector": "^6.6.0",
199
198
  "lighthouse-logger": "^1.3.0",
200
- "lighthouse-stack-packs": "1.8.2",
199
+ "lighthouse-stack-packs": "1.9.0",
201
200
  "lodash": "^4.17.21",
202
201
  "lookup-closest-locale": "6.2.0",
203
202
  "metaviewport-parser": "0.3.0",
204
203
  "open": "^8.4.0",
205
204
  "parse-cache-control": "1.0.1",
206
205
  "ps-list": "^8.0.0",
207
- "puppeteer-core": "^18.0.5",
206
+ "puppeteer-core": "^19.6.0",
208
207
  "quibble": "connorjclark/quibble#fork",
209
208
  "robots-parser": "^3.0.0",
210
209
  "semver": "^5.3.0",
@@ -20,7 +20,8 @@
20
20
  /** @typedef {import('./details-renderer.js').DetailsRenderer} DetailsRenderer */
21
21
  /** @typedef {'failed'|'warning'|'manual'|'passed'|'notApplicable'} TopLevelClumpId */
22
22
 
23
- import {Util} from './util.js';
23
+ import {ReportUtils} from './report-utils.js';
24
+ import {Globals} from './report-globals.js';
24
25
 
25
26
  export class CategoryRenderer {
26
27
  /**
@@ -39,10 +40,10 @@ export class CategoryRenderer {
39
40
  */
40
41
  get _clumpTitles() {
41
42
  return {
42
- warning: Util.strings.warningAuditsGroupTitle,
43
- manual: Util.strings.manualAuditsGroupTitle,
44
- passed: Util.strings.passedAuditsGroupTitle,
45
- notApplicable: Util.strings.notApplicableAuditsGroupTitle,
43
+ warning: Globals.strings.warningAuditsGroupTitle,
44
+ manual: Globals.strings.manualAuditsGroupTitle,
45
+ passed: Globals.strings.passedAuditsGroupTitle,
46
+ notApplicable: Globals.strings.notApplicableAuditsGroupTitle,
46
47
  };
47
48
  }
48
49
 
@@ -62,7 +63,7 @@ export class CategoryRenderer {
62
63
  * @return {!Element}
63
64
  */
64
65
  populateAuditValues(audit, component) {
65
- const strings = Util.strings;
66
+ const strings = Globals.strings;
66
67
  const auditEl = this.dom.find('.lh-audit', component);
67
68
  auditEl.id = audit.result.id;
68
69
  const scoreDisplayMode = audit.result.scoreDisplayMode;
@@ -185,7 +186,7 @@ export class CategoryRenderer {
185
186
  * @return {!Element}
186
187
  */
187
188
  _setRatingClass(element, score, scoreDisplayMode) {
188
- const rating = Util.calculateRating(score, scoreDisplayMode);
189
+ const rating = ReportUtils.calculateRating(score, scoreDisplayMode);
189
190
  element.classList.add(`lh-audit--${scoreDisplayMode.toLowerCase()}`);
190
191
  if (scoreDisplayMode !== 'informative') {
191
192
  element.classList.add(`lh-audit--${rating}`);
@@ -334,8 +335,8 @@ export class CategoryRenderer {
334
335
  el.append(descriptionEl);
335
336
  }
336
337
 
337
- this.dom.find('.lh-clump-toggletext--show', el).textContent = Util.strings.show;
338
- this.dom.find('.lh-clump-toggletext--hide', el).textContent = Util.strings.hide;
338
+ this.dom.find('.lh-clump-toggletext--show', el).textContent = Globals.strings.show;
339
+ this.dom.find('.lh-clump-toggletext--hide', el).textContent = Globals.strings.hide;
339
340
 
340
341
  clumpElement.classList.add(`lh-clump--${clumpId.toLowerCase()}`);
341
342
  return el;
@@ -349,7 +350,7 @@ export class CategoryRenderer {
349
350
  */
350
351
  renderCategoryScore(category, groupDefinitions, options) {
351
352
  let categoryScore;
352
- if (options && Util.shouldDisplayAsFraction(options.gatherMode)) {
353
+ if (options && ReportUtils.shouldDisplayAsFraction(options.gatherMode)) {
353
354
  categoryScore = this.renderCategoryFraction(category);
354
355
  } else {
355
356
  categoryScore = this.renderScoreGauge(category, groupDefinitions);
@@ -377,7 +378,7 @@ export class CategoryRenderer {
377
378
  const tmpl = this.dom.createComponent('gauge');
378
379
  const wrapper = this.dom.find('a.lh-gauge__wrapper', tmpl);
379
380
 
380
- if (Util.isPluginCategory(category.id)) {
381
+ if (ReportUtils.isPluginCategory(category.id)) {
381
382
  wrapper.classList.add('lh-gauge__wrapper--plugin');
382
383
  }
383
384
 
@@ -393,16 +394,16 @@ export class CategoryRenderer {
393
394
  percentageEl.textContent = scoreOutOf100.toString();
394
395
  if (category.score === null) {
395
396
  percentageEl.textContent = '?';
396
- percentageEl.title = Util.strings.errorLabel;
397
+ percentageEl.title = Globals.strings.errorLabel;
397
398
  }
398
399
 
399
400
  // Render a numerical score if the category has applicable audits, or no audits whatsoever.
400
401
  if (category.auditRefs.length === 0 || this.hasApplicableAudits(category)) {
401
- wrapper.classList.add(`lh-gauge__wrapper--${Util.calculateRating(category.score)}`);
402
+ wrapper.classList.add(`lh-gauge__wrapper--${ReportUtils.calculateRating(category.score)}`);
402
403
  } else {
403
404
  wrapper.classList.add(`lh-gauge__wrapper--not-applicable`);
404
405
  percentageEl.textContent = '-';
405
- percentageEl.title = Util.strings.notApplicableAuditsGroupTitle;
406
+ percentageEl.title = Globals.strings.notApplicableAuditsGroupTitle;
406
407
  }
407
408
 
408
409
  this.dom.find('.lh-gauge__label', tmpl).textContent = category.title;
@@ -417,7 +418,8 @@ export class CategoryRenderer {
417
418
  const tmpl = this.dom.createComponent('fraction');
418
419
  const wrapper = this.dom.find('a.lh-fraction__wrapper', tmpl);
419
420
 
420
- const {numPassed, numPassableAudits, totalWeight} = Util.calculateCategoryFraction(category);
421
+ const {numPassed, numPassableAudits, totalWeight} =
422
+ ReportUtils.calculateCategoryFraction(category);
421
423
 
422
424
  const fraction = numPassed / numPassableAudits;
423
425
  const content = this.dom.find('.lh-fraction__content', tmpl);
@@ -425,7 +427,7 @@ export class CategoryRenderer {
425
427
  text.textContent = `${numPassed}/${numPassableAudits}`;
426
428
  content.append(text);
427
429
 
428
- let rating = Util.calculateRating(fraction);
430
+ let rating = ReportUtils.calculateRating(fraction);
429
431
 
430
432
  // If none of the available audits can affect the score, a rating isn't useful.
431
433
  // The flow report should display the fraction with neutral icon and coloring in this case.
@@ -490,7 +492,7 @@ export class CategoryRenderer {
490
492
  return scoreDisplayMode;
491
493
  }
492
494
 
493
- if (Util.showAsPassed(auditRef.result)) {
495
+ if (ReportUtils.showAsPassed(auditRef.result)) {
494
496
  if (this._auditHasWarning(auditRef)) {
495
497
  return 'warning';
496
498
  } else {
@@ -20,7 +20,7 @@
20
20
  * critical request chains network tree.
21
21
  */
22
22
 
23
- import {Util} from './util.js';
23
+ import {Globals} from './report-globals.js';
24
24
 
25
25
  /** @typedef {import('./dom.js').DOM} DOM */
26
26
  /** @typedef {import('./details-renderer.js').DetailsRenderer} DetailsRenderer */
@@ -137,9 +137,9 @@ class CriticalRequestChainRenderer {
137
137
  const {startTime, endTime, transferSize} = segment.node.request;
138
138
  const span = dom.createElement('span', 'lh-crc-node__chain-duration');
139
139
  span.textContent =
140
- ' - ' + Util.i18n.formatMilliseconds((endTime - startTime) * 1000) + ', ';
140
+ ' - ' + Globals.i18n.formatMilliseconds((endTime - startTime) * 1000) + ', ';
141
141
  const span2 = dom.createElement('span', 'lh-crc-node__chain-duration');
142
- span2.textContent = Util.i18n.formatBytesToKiB(transferSize, 0.01);
142
+ span2.textContent = Globals.i18n.formatBytesToKiB(transferSize, 0.01);
143
143
 
144
144
  treevalEl.append(span, span2);
145
145
  }
@@ -178,11 +178,11 @@ class CriticalRequestChainRenderer {
178
178
  const containerEl = dom.find('.lh-crc', tmpl);
179
179
 
180
180
  // Fill in top summary.
181
- dom.find('.lh-crc-initial-nav', tmpl).textContent = Util.strings.crcInitialNavigation;
181
+ dom.find('.lh-crc-initial-nav', tmpl).textContent = Globals.strings.crcInitialNavigation;
182
182
  dom.find('.lh-crc__longest_duration_label', tmpl).textContent =
183
- Util.strings.crcLongestDurationLabel;
183
+ Globals.strings.crcLongestDurationLabel;
184
184
  dom.find('.lh-crc__longest_duration', tmpl).textContent =
185
- Util.i18n.formatMilliseconds(details.longestChain.duration);
185
+ Globals.i18n.formatMilliseconds(details.longestChain.duration);
186
186
 
187
187
  // Construct visual tree.
188
188
  const root = CRCRenderer.initTree(details.chains);
@@ -25,9 +25,10 @@
25
25
  /** @typedef {LH.FormattedIcu<LH.Audit.Details.ItemValue>} TableItemValue */
26
26
  /** @typedef {LH.FormattedIcu<LH.Audit.Details.TableColumnHeading>} TableColumnHeading */
27
27
 
28
- import {Util} from './util.js';
28
+ import {Util} from '../../shared/util.js';
29
29
  import {CriticalRequestChainRenderer} from './crc-details-renderer.js';
30
30
  import {ElementScreenshotRenderer} from './element-screenshot-renderer.js';
31
+ import {Globals} from './report-globals.js';
31
32
 
32
33
  const URL_PREFIXES = ['http://', 'https://', 'data:'];
33
34
 
@@ -77,9 +78,9 @@ export class DetailsRenderer {
77
78
  */
78
79
  _renderBytes(details) {
79
80
  // TODO: handle displayUnit once we have something other than 'KiB'
80
- const value = Util.i18n.formatBytesToKiB(details.value, details.granularity || 0.1);
81
+ const value = Globals.i18n.formatBytesToKiB(details.value, details.granularity || 0.1);
81
82
  const textEl = this._renderText(value);
82
- textEl.title = Util.i18n.formatBytes(details.value);
83
+ textEl.title = Globals.i18n.formatBytes(details.value);
83
84
  return textEl;
84
85
  }
85
86
 
@@ -90,9 +91,9 @@ export class DetailsRenderer {
90
91
  _renderMilliseconds(details) {
91
92
  let value;
92
93
  if (details.displayUnit === 'duration') {
93
- value = Util.i18n.formatDuration(details.value);
94
+ value = Globals.i18n.formatDuration(details.value);
94
95
  } else {
95
- value = Util.i18n.formatMilliseconds(details.value, details.granularity || 10);
96
+ value = Globals.i18n.formatMilliseconds(details.value, details.granularity || 10);
96
97
  }
97
98
 
98
99
  return this._renderText(value);
@@ -171,7 +172,7 @@ export class DetailsRenderer {
171
172
  * @return {Element}
172
173
  */
173
174
  _renderNumeric(details) {
174
- const value = Util.i18n.formatNumber(details.value, details.granularity || 0.1);
175
+ const value = Globals.i18n.formatNumber(details.value, details.granularity || 0.1);
175
176
  const element = this._dom.createElement('div', 'lh-numeric');
176
177
  element.textContent = value;
177
178
  return element;
@@ -20,7 +20,7 @@
20
20
  /** @typedef {HTMLElementTagNameMap & {[id: string]: HTMLElement}} HTMLElementByTagName */
21
21
  /** @template {string} T @typedef {import('typed-query-selector/parser').ParseSelector<T, Element>} ParseSelector */
22
22
 
23
- import {Util} from './util.js';
23
+ import {Util} from '../../shared/util.js';
24
24
  import {createComponent} from './components.js';
25
25
 
26
26
  export class DOM {
@@ -10,6 +10,8 @@
10
10
  * 2. Display coords (DC suffix): that match the CSS pixel coordinate space of the LH report's page.
11
11
  */
12
12
 
13
+ import {Globals} from './report-globals.js';
14
+
13
15
  /** @typedef {import('./dom.js').DOM} DOM */
14
16
  /** @typedef {LH.Audit.Details.Rect} Rect */
15
17
  /** @typedef {{width: number, height: number}} Size */
@@ -22,8 +24,6 @@
22
24
  * @property {LH.Result.FullPageScreenshot} fullPageScreenshot
23
25
  */
24
26
 
25
- import {Util} from './util.js';
26
-
27
27
  /**
28
28
  * @param {LH.Result.FullPageScreenshot['screenshot']} screenshot
29
29
  * @param {LH.Audit.Details.Rect} rect
@@ -102,7 +102,7 @@ export class ElementScreenshotRenderer {
102
102
  */
103
103
  static renderClipPathInScreenshot(dom, maskEl, positionClip, elementRect, elementPreviewSize) {
104
104
  const clipPathEl = dom.find('clipPath', maskEl);
105
- const clipId = `clip-${Util.getUniqueSuffix()}`;
105
+ const clipId = `clip-${Globals.getUniqueSuffix()}`;
106
106
  clipPathEl.id = clipId;
107
107
  maskEl.style.clipPath = `url(#${clipId})`;
108
108
 
@@ -17,8 +17,9 @@
17
17
 
18
18
  /** @typedef {import('./dom.js').DOM} DOM */
19
19
 
20
- import {Util} from './util.js';
21
20
  import {CategoryRenderer} from './category-renderer.js';
21
+ import {ReportUtils} from './report-utils.js';
22
+ import {Globals} from './report-globals.js';
22
23
 
23
24
  export class PerformanceCategoryRenderer extends CategoryRenderer {
24
25
  /**
@@ -29,7 +30,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
29
30
  const tmpl = this.dom.createComponent('metric');
30
31
  const element = this.dom.find('.lh-metric', tmpl);
31
32
  element.id = audit.result.id;
32
- const rating = Util.calculateRating(audit.result.score, audit.result.scoreDisplayMode);
33
+ const rating = ReportUtils.calculateRating(audit.result.score, audit.result.scoreDisplayMode);
33
34
  element.classList.add(`lh-metric--${rating}`);
34
35
 
35
36
  const titleEl = this.dom.find('.lh-metric__title', tmpl);
@@ -77,7 +78,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
77
78
  this.dom.find('span.lh-audit__display-text, div.lh-audit__display-text', element);
78
79
  const sparklineWidthPct = `${details.overallSavingsMs / scale * 100}%`;
79
80
  this.dom.find('div.lh-sparkline__bar', element).style.width = sparklineWidthPct;
80
- displayEl.textContent = Util.i18n.formatSeconds(details.overallSavingsMs, 0.01);
81
+ displayEl.textContent = Globals.i18n.formatSeconds(details.overallSavingsMs, 0.01);
81
82
 
82
83
  // Set [title] tooltips
83
84
  if (audit.result.displayValue) {
@@ -144,9 +145,9 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
144
145
  });
145
146
  const paramPairs = [...metricPairs];
146
147
 
147
- if (Util.reportJson) {
148
- paramPairs.push(['device', Util.reportJson.configSettings.formFactor]);
149
- paramPairs.push(['version', Util.reportJson.lighthouseVersion]);
148
+ if (Globals.reportJson) {
149
+ paramPairs.push(['device', Globals.reportJson.configSettings.formFactor]);
150
+ paramPairs.push(['version', Globals.reportJson.lighthouseVersion]);
150
151
  }
151
152
 
152
153
  const params = new URLSearchParams(paramPairs);
@@ -178,7 +179,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
178
179
  * @override
179
180
  */
180
181
  render(category, groups, options) {
181
- const strings = Util.strings;
182
+ const strings = Globals.strings;
182
183
  const element = this.dom.createElement('div', 'lh-category');
183
184
  element.id = category.id;
184
185
  element.append(this.renderCategoryHeader(category, groups, options));
@@ -190,7 +191,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
190
191
 
191
192
  // Metric descriptions toggle.
192
193
  const checkboxEl = this.dom.createElement('input', 'lh-metrics-toggle__input');
193
- const checkboxId = `lh-metrics-toggle${Util.getUniqueSuffix()}`;
194
+ const checkboxId = `lh-metrics-toggle${Globals.getUniqueSuffix()}`;
194
195
  checkboxEl.setAttribute('aria-label', 'Toggle the display of metric descriptions');
195
196
  checkboxEl.type = 'checkbox';
196
197
  checkboxEl.id = checkboxId;
@@ -200,8 +201,8 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
200
201
  labelEl.htmlFor = checkboxId;
201
202
  const showEl = this.dom.createChildOf(labelEl, 'span', 'lh-metrics-toggle__labeltext--show');
202
203
  const hideEl = this.dom.createChildOf(labelEl, 'span', 'lh-metrics-toggle__labeltext--hide');
203
- showEl.textContent = Util.strings.expandView;
204
- hideEl.textContent = Util.strings.collapseView;
204
+ showEl.textContent = Globals.strings.expandView;
205
+ hideEl.textContent = Globals.strings.collapseView;
205
206
 
206
207
  const metricsBoxesEl = this.dom.createElement('div', 'lh-metrics-container');
207
208
  metricsGroupEl.insertBefore(metricsBoxesEl, metricsFooterEl);
@@ -240,7 +241,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
240
241
  // Opportunities
241
242
  const opportunityAudits = category.auditRefs
242
243
  .filter(audit => this._classifyPerformanceAudit(audit) === 'load-opportunity')
243
- .filter(audit => !Util.showAsPassed(audit.result))
244
+ .filter(audit => !ReportUtils.showAsPassed(audit.result))
244
245
  .sort((auditA, auditB) => this._getWastedMs(auditB) - this._getWastedMs(auditA));
245
246
 
246
247
  const filterableMetrics = metricAudits.filter(a => !!a.relevantAudits);
@@ -274,7 +275,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
274
275
  // Diagnostics
275
276
  const diagnosticAudits = category.auditRefs
276
277
  .filter(audit => this._classifyPerformanceAudit(audit) === 'diagnostic')
277
- .filter(audit => !Util.showAsPassed(audit.result))
278
+ .filter(audit => !ReportUtils.showAsPassed(audit.result))
278
279
  .sort((a, b) => {
279
280
  const scoreA = a.result.scoreDisplayMode === 'informative' ? 100 : Number(a.result.score);
280
281
  const scoreB = b.result.scoreDisplayMode === 'informative' ? 100 : Number(b.result.score);
@@ -290,7 +291,8 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
290
291
 
291
292
  // Passed audits
292
293
  const passedAudits = category.auditRefs
293
- .filter(audit => this._classifyPerformanceAudit(audit) && Util.showAsPassed(audit.result));
294
+ .filter(audit =>
295
+ this._classifyPerformanceAudit(audit) && ReportUtils.showAsPassed(audit.result));
294
296
 
295
297
  if (!passedAudits.length) return element;
296
298
 
@@ -333,7 +335,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
333
335
  renderMetricAuditFilter(filterableMetrics, categoryEl) {
334
336
  const metricFilterEl = this.dom.createElement('div', 'lh-metricfilter');
335
337
  const textEl = this.dom.createChildOf(metricFilterEl, 'span', 'lh-metricfilter__text');
336
- textEl.textContent = Util.strings.showRelevantAudits;
338
+ textEl.textContent = Globals.strings.showRelevantAudits;
337
339
 
338
340
  const filterChoices = /** @type {LH.ReportResult.AuditRef[]} */ ([
339
341
  ({acronym: 'All'}),
@@ -342,7 +344,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
342
344
 
343
345
  // Form labels need to reference unique IDs, but multiple reports rendered in the same DOM (eg PSI)
344
346
  // would mean ID conflict. To address this, we 'scope' these radio inputs with a unique suffix.
345
- const uniqSuffix = Util.getUniqueSuffix();
347
+ const uniqSuffix = Globals.getUniqueSuffix();
346
348
  for (const metric of filterChoices) {
347
349
  const elemId = `metric-${metric.acronym}-${uniqSuffix}`;
348
350
  const radioEl = this.dom.createChildOf(metricFilterEl, 'input', 'lh-metricfilter__radio');
@@ -15,8 +15,9 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- import {Util} from './util.js';
19
18
  import {CategoryRenderer} from './category-renderer.js';
19
+ import {ReportUtils} from './report-utils.js';
20
+ import {Globals} from './report-globals.js';
20
21
 
21
22
  export class PwaCategoryRenderer extends CategoryRenderer {
22
23
  /**
@@ -101,7 +102,7 @@ export class PwaCategoryRenderer extends CategoryRenderer {
101
102
 
102
103
  // Remove any that have a failing audit.
103
104
  for (const auditRef of auditRefs) {
104
- if (!Util.showAsPassed(auditRef.result) && auditRef.group) {
105
+ if (!ReportUtils.showAsPassed(auditRef.result) && auditRef.group) {
105
106
  uniqueGroupIds.delete(auditRef.group);
106
107
  }
107
108
  }
@@ -122,7 +123,7 @@ export class PwaCategoryRenderer extends CategoryRenderer {
122
123
  for (const groupId of groupIds) {
123
124
  const groupAuditRefs = auditRefs.filter(ref => ref.group === groupId);
124
125
  const auditCount = groupAuditRefs.length;
125
- const passedCount = groupAuditRefs.filter(ref => Util.showAsPassed(ref.result)).length;
126
+ const passedCount = groupAuditRefs.filter(ref => ReportUtils.showAsPassed(ref.result)).length;
126
127
 
127
128
  const title = groupDefinitions[groupId].title;
128
129
  tips.push(`${title}: ${passedCount}/${auditCount}`);
@@ -162,7 +163,7 @@ export class PwaCategoryRenderer extends CategoryRenderer {
162
163
  const defsEl = svgRoot.querySelector('defs');
163
164
  if (!defsEl) return;
164
165
 
165
- const idSuffix = Util.getUniqueSuffix();
166
+ const idSuffix = Globals.getUniqueSuffix();
166
167
  const elementsToUpdate = defsEl.querySelectorAll('[id]');
167
168
  for (const el of elementsToUpdate) {
168
169
  const oldId = el.id;
@@ -0,0 +1,21 @@
1
+ export type I18nFormatter = import('./i18n-formatter').I18nFormatter;
2
+ export class Globals {
3
+ /** @type {I18nFormatter} */
4
+ static i18n: I18nFormatter;
5
+ /** @type {typeof UIStrings} */
6
+ static strings: typeof UIStrings;
7
+ /** @type {LH.ReportResult | null} */
8
+ static reportJson: LH.ReportResult | null;
9
+ /**
10
+ * @param {{providedStrings: Record<string, string>; i18n: I18nFormatter; reportJson: LH.ReportResult | null}} options
11
+ */
12
+ static apply(options: {
13
+ providedStrings: Record<string, string>;
14
+ i18n: I18nFormatter;
15
+ reportJson: LH.ReportResult | null;
16
+ }): void;
17
+ static getUniqueSuffix(): number;
18
+ static resetUniqueSuffix(): void;
19
+ }
20
+ import { UIStrings } from "./report-utils.js";
21
+ //# sourceMappingURL=report-globals.d.ts.map