lighthouse 10.3.0-dev.20230705 → 10.3.0-dev.20230707

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 (34) hide show
  1. package/core/audits/accessibility/empty-heading.d.ts +10 -0
  2. package/core/audits/accessibility/empty-heading.js +45 -0
  3. package/core/audits/accessibility/identical-links-same-purpose.d.ts +10 -0
  4. package/core/audits/accessibility/identical-links-same-purpose.js +45 -0
  5. package/core/audits/accessibility/landmark-one-main.d.ts +10 -0
  6. package/core/audits/accessibility/landmark-one-main.js +44 -0
  7. package/core/audits/accessibility/target-size.d.ts +10 -0
  8. package/core/audits/accessibility/target-size.js +45 -0
  9. package/core/audits/prioritize-lcp-image.js +2 -1
  10. package/core/audits/redirects.js +4 -0
  11. package/core/computed/js-bundles.js +1 -1
  12. package/core/config/default-config.js +9 -0
  13. package/core/config/filters.d.ts +9 -9
  14. package/core/config/filters.js +7 -7
  15. package/core/config/validation.js +12 -0
  16. package/core/gather/base-gatherer.d.ts +1 -3
  17. package/core/gather/base-gatherer.js +1 -3
  18. package/core/gather/gatherers/accessibility.js +4 -1
  19. package/core/gather/gatherers/seo/font-size.d.ts +0 -1
  20. package/core/gather/gatherers/seo/font-size.js +0 -1
  21. package/core/gather/gatherers/source-maps.js +3 -2
  22. package/core/lib/cdt/SDK.d.ts +1 -1
  23. package/core/lib/cdt/SDK.js +2 -2
  24. package/core/lib/navigation-error.d.ts +2 -2
  25. package/core/lib/navigation-error.js +1 -1
  26. package/core/lib/network-recorder.js +1 -0
  27. package/dist/report/bundle.esm.js +1 -0
  28. package/dist/report/flow.js +1 -1
  29. package/dist/report/standalone.js +1 -1
  30. package/package.json +3 -3
  31. package/report/renderer/category-renderer.js +1 -0
  32. package/shared/localization/locales/en-US.json +36 -0
  33. package/shared/localization/locales/en-XL.json +36 -0
  34. package/types/artifacts.d.ts +2 -2
@@ -0,0 +1,10 @@
1
+ export default EmptyHeading;
2
+ declare class EmptyHeading extends AxeAudit {
3
+ }
4
+ export namespace UIStrings {
5
+ const title: string;
6
+ const failureTitle: string;
7
+ const description: string;
8
+ }
9
+ import AxeAudit from './axe-audit.js';
10
+ //# sourceMappingURL=empty-heading.d.ts.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Ensures that headings are not empty.
9
+ * See base class in axe-audit.js for audit() implementation.
10
+ */
11
+
12
+ import AxeAudit from './axe-audit.js';
13
+ import * as i18n from '../../lib/i18n/i18n.js';
14
+
15
+ const UIStrings = {
16
+ /** Title of an accesibility audit that checks if all heading elements have content. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: 'All heading elements contain content.',
18
+ /** Title of an accesibility audit that checks if all heading elements have content. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: 'Heading elements do not contain content.',
20
+ /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
21
+ description: 'A heading with no content or inaccessible text prevent screen reader users from ' +
22
+ 'accessing information on the page\'s structure. ' +
23
+ '[Learn more about headings](https://dequeuniversity.com/rules/axe/4.7/empty-heading).',
24
+ };
25
+
26
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
27
+
28
+ class EmptyHeading extends AxeAudit {
29
+ /**
30
+ * @return {LH.Audit.Meta}
31
+ */
32
+ static get meta() {
33
+ return {
34
+ id: 'empty-heading',
35
+ title: str_(UIStrings.title),
36
+ failureTitle: str_(UIStrings.failureTitle),
37
+ description: str_(UIStrings.description),
38
+ scoreDisplayMode: AxeAudit.SCORING_MODES.INFORMATIVE,
39
+ requiredArtifacts: ['Accessibility'],
40
+ };
41
+ }
42
+ }
43
+
44
+ export default EmptyHeading;
45
+ export {UIStrings};
@@ -0,0 +1,10 @@
1
+ export default IdenticalLinksSamePurpose;
2
+ declare class IdenticalLinksSamePurpose extends AxeAudit {
3
+ }
4
+ export namespace UIStrings {
5
+ const title: string;
6
+ const failureTitle: string;
7
+ const description: string;
8
+ }
9
+ import AxeAudit from './axe-audit.js';
10
+ //# sourceMappingURL=identical-links-same-purpose.d.ts.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Ensures that identical links have the same purpose.
9
+ * See base class in axe-audit.js for audit() implementation.
10
+ */
11
+
12
+ import AxeAudit from './axe-audit.js';
13
+ import * as i18n from '../../lib/i18n/i18n.js';
14
+
15
+ const UIStrings = {
16
+ /** Title of an accesibility audit that checks if identical links have the same purpose. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: 'Identical links have the same purpose.',
18
+ /** Title of an accesibility audit that checks if identical links have the same purpose. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: 'Identical links do not have the same purpose.',
20
+ /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
21
+ description: 'Links with the same destination should have the same description, to help users ' +
22
+ 'understand the link\'s purpose and decide whether to follow it. ' +
23
+ '[Learn more about identical links](https://dequeuniversity.com/rules/axe/4.7/identical-links-same-purpose).',
24
+ };
25
+
26
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
27
+
28
+ class IdenticalLinksSamePurpose extends AxeAudit {
29
+ /**
30
+ * @return {LH.Audit.Meta}
31
+ */
32
+ static get meta() {
33
+ return {
34
+ id: 'identical-links-same-purpose',
35
+ title: str_(UIStrings.title),
36
+ failureTitle: str_(UIStrings.failureTitle),
37
+ description: str_(UIStrings.description),
38
+ scoreDisplayMode: AxeAudit.SCORING_MODES.INFORMATIVE,
39
+ requiredArtifacts: ['Accessibility'],
40
+ };
41
+ }
42
+ }
43
+
44
+ export default IdenticalLinksSamePurpose;
45
+ export {UIStrings};
@@ -0,0 +1,10 @@
1
+ export default LandmarkOneMain;
2
+ declare class LandmarkOneMain extends AxeAudit {
3
+ }
4
+ export namespace UIStrings {
5
+ const title: string;
6
+ const failureTitle: string;
7
+ const description: string;
8
+ }
9
+ import AxeAudit from './axe-audit.js';
10
+ //# sourceMappingURL=landmark-one-main.d.ts.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Ensures that the document has a main landmark.
9
+ * See base class in axe-audit.js for audit() implementation.
10
+ */
11
+
12
+ import AxeAudit from './axe-audit.js';
13
+ import * as i18n from '../../lib/i18n/i18n.js';
14
+
15
+ const UIStrings = {
16
+ /** Title of an accesibility audit that checks if the document has a main landmark. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: 'Document has a main landmark.',
18
+ /** Title of an accesibility audit that checks if the document has a main landmark. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: 'Document does not have a main landmark.',
20
+ /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
21
+ description: 'One main landmark helps screen reader users navigate a web page. ' +
22
+ '[Learn more about landmarks](https://dequeuniversity.com/rules/axe/4.7/landmark-one-main).',
23
+ };
24
+
25
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
26
+
27
+ class LandmarkOneMain extends AxeAudit {
28
+ /**
29
+ * @return {LH.Audit.Meta}
30
+ */
31
+ static get meta() {
32
+ return {
33
+ id: 'landmark-one-main',
34
+ title: str_(UIStrings.title),
35
+ failureTitle: str_(UIStrings.failureTitle),
36
+ description: str_(UIStrings.description),
37
+ scoreDisplayMode: AxeAudit.SCORING_MODES.INFORMATIVE,
38
+ requiredArtifacts: ['Accessibility'],
39
+ };
40
+ }
41
+ }
42
+
43
+ export default LandmarkOneMain;
44
+ export {UIStrings};
@@ -0,0 +1,10 @@
1
+ export default TargetSize;
2
+ declare class TargetSize extends AxeAudit {
3
+ }
4
+ export namespace UIStrings {
5
+ const title: string;
6
+ const failureTitle: string;
7
+ const description: string;
8
+ }
9
+ import AxeAudit from './axe-audit.js';
10
+ //# sourceMappingURL=target-size.d.ts.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
+ */
6
+
7
+ /**
8
+ * @fileoverview Ensures that touch targets have sufficient size and spacing.
9
+ * See base class in axe-audit.js for audit() implementation.
10
+ */
11
+
12
+ import AxeAudit from './axe-audit.js';
13
+ import * as i18n from '../../lib/i18n/i18n.js';
14
+
15
+ const UIStrings = {
16
+ /** Title of an accesibility audit that checks if all touch targets have sufficient size and spacing. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: 'Touch targets have sufficient size and spacing.',
18
+ /** Title of an accesibility audit that checks if all touch targets have sufficient size and spacing. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: 'Touch targets do not have sufficient size or spacing.',
20
+ /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
21
+ description: 'Touch targets with sufficient size and spacing help users who may have ' +
22
+ 'difficulty targeting small controls activate the targets. ' +
23
+ '[Learn more about touch targets](https://dequeuniversity.com/rules/axe/4.7/target-size).',
24
+ };
25
+
26
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
27
+
28
+ class TargetSize extends AxeAudit {
29
+ /**
30
+ * @return {LH.Audit.Meta}
31
+ */
32
+ static get meta() {
33
+ return {
34
+ id: 'target-size',
35
+ title: str_(UIStrings.title),
36
+ failureTitle: str_(UIStrings.failureTitle),
37
+ description: str_(UIStrings.description),
38
+ scoreDisplayMode: AxeAudit.SCORING_MODES.INFORMATIVE,
39
+ requiredArtifacts: ['Accessibility'],
40
+ };
41
+ }
42
+ }
43
+
44
+ export default TargetSize;
45
+ export {UIStrings};
@@ -244,7 +244,7 @@ class PrioritizeLcpImage extends Audit {
244
244
  .find(element => element.traceEventType === 'largest-contentful-paint');
245
245
 
246
246
  if (!lcpElement || lcpElement.type !== 'image') {
247
- return {score: null, notApplicable: true};
247
+ return {score: null, notApplicable: true, metricSavings: {LCP: 0}};
248
248
  }
249
249
 
250
250
  const mainResource = await MainResource.request({devtoolsLog, URL}, context);
@@ -286,6 +286,7 @@ class PrioritizeLcpImage extends Audit {
286
286
  numericUnit: 'millisecond',
287
287
  displayValue: wastedMs ? str_(i18n.UIStrings.displayValueMsSavings, {wastedMs}) : '',
288
288
  details,
289
+ metricSavings: {LCP: wastedMs},
289
290
  };
290
291
  }
291
292
  }
@@ -154,6 +154,10 @@ class Redirects extends Audit {
154
154
  str_(i18n.UIStrings.displayValueMsSavings, {wastedMs: totalWastedMs}) :
155
155
  '',
156
156
  details,
157
+ metricSavings: {
158
+ LCP: totalWastedMs,
159
+ FCP: totalWastedMs,
160
+ },
157
161
  };
158
162
  }
159
163
  }
@@ -99,7 +99,7 @@ class JSBundles {
99
99
 
100
100
  const compiledUrl = SourceMap.scriptUrl || 'compiled.js';
101
101
  const mapUrl = SourceMap.sourceMapUrl || 'compiled.js.map';
102
- const map = new SDK.TextSourceMap(compiledUrl, mapUrl, rawMap);
102
+ const map = new SDK.SourceMap(compiledUrl, mapUrl, rawMap);
103
103
 
104
104
  const sizes = computeGeneratedFileSizes(map, script.length || 0, script.content || '');
105
105
 
@@ -260,16 +260,19 @@ const defaultConfig = {
260
260
  'accessibility/document-title',
261
261
  'accessibility/duplicate-id-active',
262
262
  'accessibility/duplicate-id-aria',
263
+ 'accessibility/empty-heading',
263
264
  'accessibility/form-field-multiple-labels',
264
265
  'accessibility/frame-title',
265
266
  'accessibility/heading-order',
266
267
  'accessibility/html-has-lang',
267
268
  'accessibility/html-lang-valid',
268
269
  'accessibility/html-xml-lang-mismatch',
270
+ 'accessibility/identical-links-same-purpose',
269
271
  'accessibility/image-alt',
270
272
  'accessibility/input-button-name',
271
273
  'accessibility/input-image-alt',
272
274
  'accessibility/label',
275
+ 'accessibility/landmark-one-main',
273
276
  'accessibility/link-name',
274
277
  'accessibility/link-in-text-block',
275
278
  'accessibility/list',
@@ -280,6 +283,7 @@ const defaultConfig = {
280
283
  'accessibility/select-name',
281
284
  'accessibility/tabindex',
282
285
  'accessibility/table-fake-caption',
286
+ 'accessibility/target-size',
283
287
  'accessibility/td-has-header',
284
288
  'accessibility/td-headers-attr',
285
289
  'accessibility/th-has-data-cells',
@@ -568,6 +572,11 @@ const defaultConfig = {
568
572
  {id: 'visual-order-follows-dom', weight: 0},
569
573
  {id: 'offscreen-content-hidden', weight: 0},
570
574
  {id: 'use-landmarks', weight: 0},
575
+ // Hidden audits
576
+ {id: 'empty-heading', weight: 0, group: 'hidden'},
577
+ {id: 'identical-links-same-purpose', weight: 0, group: 'hidden'},
578
+ {id: 'landmark-one-main', weight: 0, group: 'hidden'},
579
+ {id: 'target-size', weight: 0, group: 'hidden'},
571
580
  ],
572
581
  },
573
582
  'best-practices': {
@@ -59,25 +59,25 @@ export function filterAuditsByGatherMode(audits: LH.Config.ResolvedConfig['audit
59
59
  * Filters a categories object and their auditRefs down to the set that can be computed using
60
60
  * only the specified audits.
61
61
  *
62
- * @param {LH.Config.LegacyResolvedConfig['categories']} categories
62
+ * @param {LH.Config.ResolvedConfig['categories']} categories
63
63
  * @param {Array<LH.Config.AuditDefn>} availableAudits
64
- * @return {LH.Config.LegacyResolvedConfig['categories']}
64
+ * @return {LH.Config.ResolvedConfig['categories']}
65
65
  */
66
- export function filterCategoriesByAvailableAudits(categories: LH.Config.LegacyResolvedConfig['categories'], availableAudits: Array<LH.Config.AuditDefn>): LH.Config.LegacyResolvedConfig['categories'];
66
+ export function filterCategoriesByAvailableAudits(categories: LH.Config.ResolvedConfig['categories'], availableAudits: Array<LH.Config.AuditDefn>): LH.Config.ResolvedConfig['categories'];
67
67
  /**
68
68
  * Filters a categories object and their auditRefs down to the specified category ids.
69
69
  *
70
- * @param {LH.Config.LegacyResolvedConfig['categories']} categories
70
+ * @param {LH.Config.ResolvedConfig['categories']} categories
71
71
  * @param {string[] | null | undefined} onlyCategories
72
- * @return {LH.Config.LegacyResolvedConfig['categories']}
72
+ * @return {LH.Config.ResolvedConfig['categories']}
73
73
  */
74
- export function filterCategoriesByExplicitFilters(categories: LH.Config.LegacyResolvedConfig['categories'], onlyCategories: string[] | null | undefined): LH.Config.LegacyResolvedConfig['categories'];
74
+ export function filterCategoriesByExplicitFilters(categories: LH.Config.ResolvedConfig['categories'], onlyCategories: string[] | null | undefined): LH.Config.ResolvedConfig['categories'];
75
75
  /**
76
76
  * Optional `supportedModes` property can explicitly exclude a category even if some audits are available.
77
77
  *
78
- * @param {LH.Config.LegacyResolvedConfig['categories']} categories
78
+ * @param {LH.Config.ResolvedConfig['categories']} categories
79
79
  * @param {LH.Gatherer.GatherMode} mode
80
- * @return {LH.Config.LegacyResolvedConfig['categories']}
80
+ * @return {LH.Config.ResolvedConfig['categories']}
81
81
  */
82
- export function filterCategoriesByGatherMode(categories: LH.Config.LegacyResolvedConfig['categories'], mode: LH.Gatherer.GatherMode): LH.Config.LegacyResolvedConfig['categories'];
82
+ export function filterCategoriesByGatherMode(categories: LH.Config.ResolvedConfig['categories'], mode: LH.Gatherer.GatherMode): LH.Config.ResolvedConfig['categories'];
83
83
  //# sourceMappingURL=filters.d.ts.map
@@ -169,9 +169,9 @@ function filterAuditsByGatherMode(audits, mode) {
169
169
  /**
170
170
  * Optional `supportedModes` property can explicitly exclude a category even if some audits are available.
171
171
  *
172
- * @param {LH.Config.LegacyResolvedConfig['categories']} categories
172
+ * @param {LH.Config.ResolvedConfig['categories']} categories
173
173
  * @param {LH.Gatherer.GatherMode} mode
174
- * @return {LH.Config.LegacyResolvedConfig['categories']}
174
+ * @return {LH.Config.ResolvedConfig['categories']}
175
175
  */
176
176
  function filterCategoriesByGatherMode(categories, mode) {
177
177
  if (!categories) return null;
@@ -186,9 +186,9 @@ function filterCategoriesByGatherMode(categories, mode) {
186
186
  /**
187
187
  * Filters a categories object and their auditRefs down to the specified category ids.
188
188
  *
189
- * @param {LH.Config.LegacyResolvedConfig['categories']} categories
189
+ * @param {LH.Config.ResolvedConfig['categories']} categories
190
190
  * @param {string[] | null | undefined} onlyCategories
191
- * @return {LH.Config.LegacyResolvedConfig['categories']}
191
+ * @return {LH.Config.ResolvedConfig['categories']}
192
192
  */
193
193
  function filterCategoriesByExplicitFilters(categories, onlyCategories) {
194
194
  if (!categories || !onlyCategories) return categories;
@@ -202,7 +202,7 @@ function filterCategoriesByExplicitFilters(categories, onlyCategories) {
202
202
  * Logs a warning if any specified onlyCategory is not a known category that can
203
203
  * be included.
204
204
  *
205
- * @param {LH.Config.LegacyResolvedConfig['categories']} allCategories
205
+ * @param {LH.Config.ResolvedConfig['categories']} allCategories
206
206
  * @param {string[] | null} onlyCategories
207
207
  * @return {void}
208
208
  */
@@ -220,9 +220,9 @@ function warnOnUnknownOnlyCategories(allCategories, onlyCategories) {
220
220
  * Filters a categories object and their auditRefs down to the set that can be computed using
221
221
  * only the specified audits.
222
222
  *
223
- * @param {LH.Config.LegacyResolvedConfig['categories']} categories
223
+ * @param {LH.Config.ResolvedConfig['categories']} categories
224
224
  * @param {Array<LH.Config.AuditDefn>} availableAudits
225
- * @return {LH.Config.LegacyResolvedConfig['categories']}
225
+ * @return {LH.Config.ResolvedConfig['categories']}
226
226
  */
227
227
  function filterCategoriesByAvailableAudits(categories, availableAudits) {
228
228
  if (!categories) return categories;
@@ -223,6 +223,12 @@ function assertValidSettings(settings) {
223
223
  throw new Error(`Screen emulation mobile setting (${settings.screenEmulation.mobile}) does not match formFactor setting (${settings.formFactor}). See https://github.com/GoogleChrome/lighthouse/blob/main/docs/emulation.md`);
224
224
  }
225
225
  }
226
+
227
+ const skippedAndOnlyAuditId =
228
+ settings.skipAudits?.find(auditId => settings.onlyAudits?.includes(auditId));
229
+ if (skippedAndOnlyAuditId) {
230
+ throw new Error(`${skippedAndOnlyAuditId} appears in both skipAudits and onlyAudits`);
231
+ }
226
232
  }
227
233
 
228
234
  /**
@@ -253,7 +259,13 @@ function assertArtifactTopologicalOrder(navigations) {
253
259
  function assertValidConfig(resolvedConfig) {
254
260
  const {warnings} = assertValidFRNavigations(resolvedConfig.navigations);
255
261
 
262
+ /** @type {Set<string>} */
263
+ const artifactIds = new Set();
256
264
  for (const artifactDefn of resolvedConfig.artifacts || []) {
265
+ if (artifactIds.has(artifactDefn.id)) {
266
+ throw new Error(`Config defined multiple artifacts with id '${artifactDefn.id}'`);
267
+ }
268
+ artifactIds.add(artifactDefn.id);
257
269
  assertValidFRGatherer(artifactDefn.gatherer);
258
270
  }
259
271
 
@@ -1,8 +1,6 @@
1
1
  export default FRGatherer;
2
2
  /**
3
- * Base class for all gatherers supporting both Fraggle Rock and the legacy flow.
4
- * Most extending classes should implement the Fraggle Rock API and let this class handle translation.
5
- * See core/gather/gatherers/gatherer.js for legacy method explanations.
3
+ * Base class for all gatherers.
6
4
  *
7
5
  * @implements {LH.Gatherer.GathererInstance}
8
6
  * @implements {LH.Gatherer.FRGathererInstance}
@@ -9,9 +9,7 @@ import * as LH from '../../types/lh.js';
9
9
  /* eslint-disable no-unused-vars */
10
10
 
11
11
  /**
12
- * Base class for all gatherers supporting both Fraggle Rock and the legacy flow.
13
- * Most extending classes should implement the Fraggle Rock API and let this class handle translation.
14
- * See core/gather/gatherers/gatherer.js for legacy method explanations.
12
+ * Base class for all gatherers.
15
13
  *
16
14
  * @implements {LH.Gatherer.GathererInstance}
17
15
  * @implements {LH.Gatherer.FRGathererInstance}
@@ -48,12 +48,14 @@ async function runA11yChecks() {
48
48
  'audio-caption': {enabled: false},
49
49
  'blink': {enabled: false},
50
50
  'duplicate-id': {enabled: false},
51
+ 'empty-heading': {enabled: true},
51
52
  'frame-focusable-content': {enabled: false},
52
53
  'frame-title-unique': {enabled: false},
53
54
  'heading-order': {enabled: true},
54
55
  'html-xml-lang-mismatch': {enabled: true},
55
- 'identical-links-same-purpose': {enabled: false},
56
+ 'identical-links-same-purpose': {enabled: true},
56
57
  'input-button-name': {enabled: true},
58
+ 'landmark-one-main': {enabled: true},
57
59
  'link-in-text-block': {enabled: true},
58
60
  'marquee': {enabled: false},
59
61
  'meta-viewport': {enabled: true},
@@ -67,6 +69,7 @@ async function runA11yChecks() {
67
69
  'svg-img-alt': {enabled: false},
68
70
  'tabindex': {enabled: true},
69
71
  'table-fake-caption': {enabled: true},
72
+ 'target-size': {enabled: true},
70
73
  'td-has-header': {enabled: true},
71
74
  },
72
75
  });
@@ -1,5 +1,4 @@
1
1
  export default FontSize;
2
- export type Driver = typeof import("../../../legacy/gather/driver.js");
3
2
  export type NodeFontData = LH.Artifacts.FontSize['analyzedFailingNodesData'][0];
4
3
  export type BackendIdsToFontData = Map<number, {
5
4
  fontSize: number;
@@ -22,7 +22,6 @@ const MINIMAL_LEGIBLE_FONT_SIZE_PX = 12;
22
22
  // limit number of protocol calls to make sure that gatherer doesn't take more than 1-2s
23
23
  const MAX_NODES_SOURCE_RULE_FETCHED = 50; // number of nodes to fetch the source font-size rule
24
24
 
25
- /** @typedef {import('../../../legacy/gather/driver.js')} Driver */
26
25
  /** @typedef {LH.Artifacts.FontSize['analyzedFailingNodesData'][0]} NodeFontData */
27
26
  /** @typedef {Map<number, {fontSize: number, textLength: number}>} BackendIdsToFontData */
28
27
 
@@ -4,6 +4,7 @@
4
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
5
  */
6
6
 
7
+ import SDK from '../../lib/cdt/SDK.js';
7
8
  import FRGatherer from '../base-gatherer.js';
8
9
 
9
10
  /**
@@ -32,7 +33,7 @@ class SourceMaps extends FRGatherer {
32
33
  if (response.content === null) {
33
34
  throw new Error(`Failed fetching source map (${response.status})`);
34
35
  }
35
- return JSON.parse(response.content);
36
+ return SDK.SourceMap.parseSourceMap(response.content);
36
37
  }
37
38
 
38
39
  /**
@@ -41,7 +42,7 @@ class SourceMaps extends FRGatherer {
41
42
  */
42
43
  parseSourceMapFromDataUrl(sourceMapURL) {
43
44
  const buffer = Buffer.from(sourceMapURL.split(',')[1], 'base64');
44
- return JSON.parse(buffer.toString());
45
+ return SDK.SourceMap.parseSourceMap(buffer.toString());
45
46
  }
46
47
 
47
48
  /**
@@ -1,2 +1,2 @@
1
- export const TextSourceMap: typeof import("./generated/SourceMap.js");
1
+ export const SourceMap: typeof import("./generated/SourceMap.js");
2
2
  //# sourceMappingURL=SDK.d.ts.map
@@ -5,12 +5,12 @@
5
5
  */
6
6
 
7
7
  const SDK = {
8
- TextSourceMap: require('./generated/SourceMap.js'),
8
+ SourceMap: require('./generated/SourceMap.js'),
9
9
  };
10
10
 
11
11
  // Add `lastColumnNumber` to mappings. This will eventually be added to CDT.
12
12
  // @ts-expect-error
13
- SDK.TextSourceMap.prototype.computeLastGeneratedColumns = function() {
13
+ SDK.SourceMap.prototype.computeLastGeneratedColumns = function() {
14
14
  const mappings = this.mappings();
15
15
  if (mappings.length && mappings[0].lastColumnNumber !== undefined) return;
16
16
 
@@ -15,12 +15,12 @@ export function getInterstitialError(mainRecord: LH.Artifacts.NetworkRequest | u
15
15
  * Returns an error if the page load should be considered failed, e.g. from a
16
16
  * main document request failure, a security issue, etc.
17
17
  * @param {LH.LighthouseError|undefined} navigationError
18
- * @param {{url: string, loadFailureMode: LH.Gatherer.PassContext['passConfig']['loadFailureMode'], networkRecords: Array<LH.Artifacts.NetworkRequest>, warnings: Array<string | LH.IcuMessage>}} context
18
+ * @param {{url: string, loadFailureMode: LH.Config.SharedPassNavigationJson['loadFailureMode'], networkRecords: Array<LH.Artifacts.NetworkRequest>, warnings: Array<string | LH.IcuMessage>}} context
19
19
  * @return {LH.LighthouseError|undefined}
20
20
  */
21
21
  export function getPageLoadError(navigationError: LH.LighthouseError | undefined, context: {
22
22
  url: string;
23
- loadFailureMode: LH.Gatherer.PassContext['passConfig']['loadFailureMode'];
23
+ loadFailureMode: LH.Config.SharedPassNavigationJson['loadFailureMode'];
24
24
  networkRecords: Array<LH.Artifacts.NetworkRequest>;
25
25
  warnings: Array<string | LH.IcuMessage>;
26
26
  }): LH.LighthouseError | undefined;
@@ -110,7 +110,7 @@ function getNonHtmlError(finalRecord) {
110
110
  * Returns an error if the page load should be considered failed, e.g. from a
111
111
  * main document request failure, a security issue, etc.
112
112
  * @param {LH.LighthouseError|undefined} navigationError
113
- * @param {{url: string, loadFailureMode: LH.Gatherer.PassContext['passConfig']['loadFailureMode'], networkRecords: Array<LH.Artifacts.NetworkRequest>, warnings: Array<string | LH.IcuMessage>}} context
113
+ * @param {{url: string, loadFailureMode: LH.Config.SharedPassNavigationJson['loadFailureMode'], networkRecords: Array<LH.Artifacts.NetworkRequest>, warnings: Array<string | LH.IcuMessage>}} context
114
114
  * @return {LH.LighthouseError|undefined}
115
115
  */
116
116
  function getPageLoadError(navigationError, context) {
@@ -80,6 +80,7 @@ class NetworkRecorder extends RequestEventEmitter {
80
80
  const request = new NetworkRequest();
81
81
  request.onRequestWillBeSent(data);
82
82
  request.sessionId = event.sessionId;
83
+ request.sessionTargetType = event.targetType;
83
84
  this.onRequestStarted(request);
84
85
  log.verbose('network', `request will be sent to ${request.url}`);
85
86
  return;
@@ -2319,6 +2319,7 @@ class CategoryRenderer {
2319
2319
 
2320
2320
  for (const auditRef of auditRefs) {
2321
2321
  const groupId = auditRef.group || notAGroup;
2322
+ if (groupId === 'hidden') continue;
2322
2323
  const groupAuditRefs = grouped.get(groupId) || [];
2323
2324
  groupAuditRefs.push(auditRef);
2324
2325
  grouped.set(groupId, groupAuditRefs);
@@ -80,7 +80,7 @@ class ka{constructor(e,a){this._document=e,this._lighthouseChannel="unknown",thi
80
80
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81
81
  * See the License for the specific language governing permissions and
82
82
  * limitations under the License.
83
- */class wa{constructor(e,a){this.dom=e,this.detailsRenderer=a}get _clumpTitles(){return{warning:ue.strings.warningAuditsGroupTitle,manual:ue.strings.manualAuditsGroupTitle,passed:ue.strings.passedAuditsGroupTitle,notApplicable:ue.strings.notApplicableAuditsGroupTitle}}renderAudit(e){const a=this.dom.createComponent("audit");return this.populateAuditValues(e,a)}populateAuditValues(e,a){const n=ue.strings,t=this.dom.find(".lh-audit",a);t.id=e.result.id;const i=e.result.scoreDisplayMode;e.result.displayValue&&(this.dom.find(".lh-audit__display-text",t).textContent=e.result.displayValue);const o=this.dom.find(".lh-audit__title",t);o.append(this.dom.convertMarkdownCodeSnippets(e.result.title));const r=this.dom.find(".lh-audit__description",t);r.append(this.dom.convertMarkdownLinkSnippets(e.result.description));for(const a of e.relevantMetrics||[]){const e=this.dom.createChildOf(r,"span","lh-audit__adorn");e.title=`Relevant to ${a.result.title}`,e.textContent=a.acronym||a.id}e.stackPacks&&e.stackPacks.forEach((e=>{const a=this.dom.createElement("img","lh-audit__stackpack__img");a.src=e.iconDataURL,a.alt=e.title;const n=this.dom.convertMarkdownLinkSnippets(e.description,{alwaysAppendUtmSource:!0}),i=this.dom.createElement("div","lh-audit__stackpack");i.append(a,n),this.dom.find(".lh-audit__stackpacks",t).append(i)}));const s=this.dom.find("details",t);if(e.result.details){const a=this.detailsRenderer.render(e.result.details);a&&(a.classList.add("lh-details"),s.append(a))}if(this.dom.find(".lh-chevron-container",t).append(this._createChevron()),this._setRatingClass(t,e.result.score,i),"error"===e.result.scoreDisplayMode){t.classList.add("lh-audit--error");const a=this.dom.find(".lh-audit__display-text",t);a.textContent=n.errorLabel,a.classList.add("lh-tooltip-boundary");this.dom.createChildOf(a,"div","lh-tooltip lh-tooltip--error").textContent=e.result.errorMessage||n.errorMissingAuditInfo}else if(e.result.explanation){this.dom.createChildOf(o,"div","lh-audit-explanation").textContent=e.result.explanation}const l=e.result.warnings;if(!l||0===l.length)return t;const p=this.dom.find("summary",s),u=this.dom.createChildOf(p,"div","lh-warnings");if(this.dom.createChildOf(u,"span").textContent=n.warningHeader,1===l.length)u.append(this.dom.createTextNode(l.join("")));else{const e=this.dom.createChildOf(u,"ul");for(const a of l){this.dom.createChildOf(e,"li").textContent=a}}return t}injectFinalScreenshot(e,a,n){const t=a["final-screenshot"];if(!t||"error"===t.scoreDisplayMode)return null;if(!t.details||"screenshot"!==t.details.type)return null;const i=this.dom.createElement("img","lh-final-ss-image"),o=t.details.data;i.src=o,i.alt=t.title;const r=this.dom.find(".lh-category .lh-category-header",e),s=this.dom.createElement("div","lh-category-headercol"),l=this.dom.createElement("div","lh-category-headercol lh-category-headercol--separator"),p=this.dom.createElement("div","lh-category-headercol");s.append(...r.childNodes),s.append(n),p.append(i),r.append(s,l,p),r.classList.add("lh-category-header__finalscreenshot")}_createChevron(){const e=this.dom.createComponent("chevron");return this.dom.find("svg.lh-chevron",e)}_setRatingClass(e,a,n){const t=me.calculateRating(a,n);return e.classList.add(`lh-audit--${n.toLowerCase()}`),"informative"!==n&&e.classList.add(`lh-audit--${t}`),e}renderCategoryHeader(e,a,n){const t=this.dom.createComponent("categoryHeader"),i=this.dom.find(".lh-score__gauge",t),o=this.renderCategoryScore(e,a,n);if(i.append(o),e.description){const a=this.dom.convertMarkdownLinkSnippets(e.description);this.dom.find(".lh-category-header__description",t).append(a)}return t}renderAuditGroup(e){const a=this.dom.createElement("div","lh-audit-group"),n=this.dom.createElement("div","lh-audit-group__header");this.dom.createChildOf(n,"span","lh-audit-group__title").textContent=e.title,a.append(n);let t=null;return e.description&&(t=this.dom.convertMarkdownLinkSnippets(e.description),t.classList.add("lh-audit-group__description","lh-audit-group__footer"),a.append(t)),[a,t]}_renderGroupedAudits(e,a){const n=new Map,t="NotAGroup";n.set(t,[]);for(const a of e){const e=a.group||t,i=n.get(e)||[];i.push(a),n.set(e,i)}const i=[];for(const[e,o]of n){if(e===t){for(const e of o)i.push(this.renderAudit(e));continue}const n=a[e],[r,s]=this.renderAuditGroup(n);for(const e of o)r.insertBefore(this.renderAudit(e),s);r.classList.add(`lh-audit-group--${e}`),i.push(r)}return i}renderUnexpandableClump(e,a){const n=this.dom.createElement("div");return this._renderGroupedAudits(e,a).forEach((e=>n.append(e))),n}renderClump(e,{auditRefs:a,description:n}){const t=this.dom.createComponent("clump"),i=this.dom.find(".lh-clump",t);"warning"===e&&i.setAttribute("open","");const o=this.dom.find(".lh-audit-group__header",i),r=this._clumpTitles[e];this.dom.find(".lh-audit-group__title",o).textContent=r;this.dom.find(".lh-audit-group__itemcount",i).textContent=`(${a.length})`;const s=a.map(this.renderAudit.bind(this));i.append(...s);const l=this.dom.find(".lh-audit-group",t);if(n){const e=this.dom.convertMarkdownLinkSnippets(n);e.classList.add("lh-audit-group__description","lh-audit-group__footer"),l.append(e)}return this.dom.find(".lh-clump-toggletext--show",l).textContent=ue.strings.show,this.dom.find(".lh-clump-toggletext--hide",l).textContent=ue.strings.hide,i.classList.add(`lh-clump--${e.toLowerCase()}`),l}renderCategoryScore(e,a,n){let t;if(t=n&&me.shouldDisplayAsFraction(n.gatherMode)?this.renderCategoryFraction(e):this.renderScoreGauge(e,a),n?.omitLabel){this.dom.find(".lh-gauge__label,.lh-fraction__label",t).remove()}if(n?.onPageAnchorRendered){const e=this.dom.find("a",t);n.onPageAnchorRendered(e)}return t}renderScoreGauge(e,a){const n=this.dom.createComponent("gauge"),t=this.dom.find("a.lh-gauge__wrapper",n);me.isPluginCategory(e.id)&&t.classList.add("lh-gauge__wrapper--plugin");const i=Number(e.score),o=this.dom.find(".lh-gauge",n),r=this.dom.find("circle.lh-gauge-arc",o);r&&this._setGaugeArc(r,i);const s=Math.round(100*i),l=this.dom.find("div.lh-gauge__percentage",n);return l.textContent=s.toString(),null===e.score&&(l.classList.add("lh-gauge--error"),l.textContent="",l.title=ue.strings.errorLabel),0===e.auditRefs.length||this.hasApplicableAudits(e)?t.classList.add(`lh-gauge__wrapper--${me.calculateRating(e.score)}`):(t.classList.add("lh-gauge__wrapper--not-applicable"),l.textContent="-",l.title=ue.strings.notApplicableAuditsGroupTitle),this.dom.find(".lh-gauge__label",n).textContent=e.title,n}renderCategoryFraction(e){const a=this.dom.createComponent("fraction"),n=this.dom.find("a.lh-fraction__wrapper",a),{numPassed:t,numPassableAudits:i,totalWeight:o}=me.calculateCategoryFraction(e),r=t/i,s=this.dom.find(".lh-fraction__content",a),l=this.dom.createElement("span");l.textContent=`${t}/${i}`,s.append(l);let p=me.calculateRating(r);return 0===o&&(p="null"),n.classList.add(`lh-fraction__wrapper--${p}`),this.dom.find(".lh-fraction__label",a).textContent=e.title,a}hasApplicableAudits(e){return e.auditRefs.some((e=>"notApplicable"!==e.result.scoreDisplayMode))}_setGaugeArc(e,a){const n=2*Math.PI*Number(e.getAttribute("r")),t=Number(e.getAttribute("stroke-width")),i=.25*t/n;e.style.transform=`rotate(${360*i-90}deg)`;let o=a*n-t/2;0===a&&(e.style.opacity="0"),1===a&&(o=n),e.style.strokeDasharray=`${Math.max(o,0)} ${n}`}_auditHasWarning(e){return Boolean(e.result.warnings?.length)}_getClumpIdForAuditRef(e){const a=e.result.scoreDisplayMode;return"manual"===a||"notApplicable"===a?a:me.showAsPassed(e.result)?this._auditHasWarning(e)?"warning":"passed":"failed"}render(e,a={},n){const t=this.dom.createElement("div","lh-category");t.id=e.id,t.append(this.renderCategoryHeader(e,a,n));const i=new Map;i.set("failed",[]),i.set("warning",[]),i.set("manual",[]),i.set("passed",[]),i.set("notApplicable",[]);for(const a of e.auditRefs){const e=this._getClumpIdForAuditRef(a),n=i.get(e);n.push(a),i.set(e,n)}for(const e of i.values())e.sort(((e,a)=>a.weight-e.weight));for(const[n,o]of i){if(0===o.length)continue;if("failed"===n){const e=this.renderUnexpandableClump(o,a);e.classList.add("lh-clump--failed"),t.append(e);continue}const i="manual"===n?e.manualDescription:void 0,r=this.renderClump(n,{auditRefs:o,description:i});t.append(r)}return t}}
83
+ */class wa{constructor(e,a){this.dom=e,this.detailsRenderer=a}get _clumpTitles(){return{warning:ue.strings.warningAuditsGroupTitle,manual:ue.strings.manualAuditsGroupTitle,passed:ue.strings.passedAuditsGroupTitle,notApplicable:ue.strings.notApplicableAuditsGroupTitle}}renderAudit(e){const a=this.dom.createComponent("audit");return this.populateAuditValues(e,a)}populateAuditValues(e,a){const n=ue.strings,t=this.dom.find(".lh-audit",a);t.id=e.result.id;const i=e.result.scoreDisplayMode;e.result.displayValue&&(this.dom.find(".lh-audit__display-text",t).textContent=e.result.displayValue);const o=this.dom.find(".lh-audit__title",t);o.append(this.dom.convertMarkdownCodeSnippets(e.result.title));const r=this.dom.find(".lh-audit__description",t);r.append(this.dom.convertMarkdownLinkSnippets(e.result.description));for(const a of e.relevantMetrics||[]){const e=this.dom.createChildOf(r,"span","lh-audit__adorn");e.title=`Relevant to ${a.result.title}`,e.textContent=a.acronym||a.id}e.stackPacks&&e.stackPacks.forEach((e=>{const a=this.dom.createElement("img","lh-audit__stackpack__img");a.src=e.iconDataURL,a.alt=e.title;const n=this.dom.convertMarkdownLinkSnippets(e.description,{alwaysAppendUtmSource:!0}),i=this.dom.createElement("div","lh-audit__stackpack");i.append(a,n),this.dom.find(".lh-audit__stackpacks",t).append(i)}));const s=this.dom.find("details",t);if(e.result.details){const a=this.detailsRenderer.render(e.result.details);a&&(a.classList.add("lh-details"),s.append(a))}if(this.dom.find(".lh-chevron-container",t).append(this._createChevron()),this._setRatingClass(t,e.result.score,i),"error"===e.result.scoreDisplayMode){t.classList.add("lh-audit--error");const a=this.dom.find(".lh-audit__display-text",t);a.textContent=n.errorLabel,a.classList.add("lh-tooltip-boundary");this.dom.createChildOf(a,"div","lh-tooltip lh-tooltip--error").textContent=e.result.errorMessage||n.errorMissingAuditInfo}else if(e.result.explanation){this.dom.createChildOf(o,"div","lh-audit-explanation").textContent=e.result.explanation}const l=e.result.warnings;if(!l||0===l.length)return t;const p=this.dom.find("summary",s),u=this.dom.createChildOf(p,"div","lh-warnings");if(this.dom.createChildOf(u,"span").textContent=n.warningHeader,1===l.length)u.append(this.dom.createTextNode(l.join("")));else{const e=this.dom.createChildOf(u,"ul");for(const a of l){this.dom.createChildOf(e,"li").textContent=a}}return t}injectFinalScreenshot(e,a,n){const t=a["final-screenshot"];if(!t||"error"===t.scoreDisplayMode)return null;if(!t.details||"screenshot"!==t.details.type)return null;const i=this.dom.createElement("img","lh-final-ss-image"),o=t.details.data;i.src=o,i.alt=t.title;const r=this.dom.find(".lh-category .lh-category-header",e),s=this.dom.createElement("div","lh-category-headercol"),l=this.dom.createElement("div","lh-category-headercol lh-category-headercol--separator"),p=this.dom.createElement("div","lh-category-headercol");s.append(...r.childNodes),s.append(n),p.append(i),r.append(s,l,p),r.classList.add("lh-category-header__finalscreenshot")}_createChevron(){const e=this.dom.createComponent("chevron");return this.dom.find("svg.lh-chevron",e)}_setRatingClass(e,a,n){const t=me.calculateRating(a,n);return e.classList.add(`lh-audit--${n.toLowerCase()}`),"informative"!==n&&e.classList.add(`lh-audit--${t}`),e}renderCategoryHeader(e,a,n){const t=this.dom.createComponent("categoryHeader"),i=this.dom.find(".lh-score__gauge",t),o=this.renderCategoryScore(e,a,n);if(i.append(o),e.description){const a=this.dom.convertMarkdownLinkSnippets(e.description);this.dom.find(".lh-category-header__description",t).append(a)}return t}renderAuditGroup(e){const a=this.dom.createElement("div","lh-audit-group"),n=this.dom.createElement("div","lh-audit-group__header");this.dom.createChildOf(n,"span","lh-audit-group__title").textContent=e.title,a.append(n);let t=null;return e.description&&(t=this.dom.convertMarkdownLinkSnippets(e.description),t.classList.add("lh-audit-group__description","lh-audit-group__footer"),a.append(t)),[a,t]}_renderGroupedAudits(e,a){const n=new Map,t="NotAGroup";n.set(t,[]);for(const a of e){const e=a.group||t;if("hidden"===e)continue;const i=n.get(e)||[];i.push(a),n.set(e,i)}const i=[];for(const[e,o]of n){if(e===t){for(const e of o)i.push(this.renderAudit(e));continue}const n=a[e],[r,s]=this.renderAuditGroup(n);for(const e of o)r.insertBefore(this.renderAudit(e),s);r.classList.add(`lh-audit-group--${e}`),i.push(r)}return i}renderUnexpandableClump(e,a){const n=this.dom.createElement("div");return this._renderGroupedAudits(e,a).forEach((e=>n.append(e))),n}renderClump(e,{auditRefs:a,description:n}){const t=this.dom.createComponent("clump"),i=this.dom.find(".lh-clump",t);"warning"===e&&i.setAttribute("open","");const o=this.dom.find(".lh-audit-group__header",i),r=this._clumpTitles[e];this.dom.find(".lh-audit-group__title",o).textContent=r;this.dom.find(".lh-audit-group__itemcount",i).textContent=`(${a.length})`;const s=a.map(this.renderAudit.bind(this));i.append(...s);const l=this.dom.find(".lh-audit-group",t);if(n){const e=this.dom.convertMarkdownLinkSnippets(n);e.classList.add("lh-audit-group__description","lh-audit-group__footer"),l.append(e)}return this.dom.find(".lh-clump-toggletext--show",l).textContent=ue.strings.show,this.dom.find(".lh-clump-toggletext--hide",l).textContent=ue.strings.hide,i.classList.add(`lh-clump--${e.toLowerCase()}`),l}renderCategoryScore(e,a,n){let t;if(t=n&&me.shouldDisplayAsFraction(n.gatherMode)?this.renderCategoryFraction(e):this.renderScoreGauge(e,a),n?.omitLabel){this.dom.find(".lh-gauge__label,.lh-fraction__label",t).remove()}if(n?.onPageAnchorRendered){const e=this.dom.find("a",t);n.onPageAnchorRendered(e)}return t}renderScoreGauge(e,a){const n=this.dom.createComponent("gauge"),t=this.dom.find("a.lh-gauge__wrapper",n);me.isPluginCategory(e.id)&&t.classList.add("lh-gauge__wrapper--plugin");const i=Number(e.score),o=this.dom.find(".lh-gauge",n),r=this.dom.find("circle.lh-gauge-arc",o);r&&this._setGaugeArc(r,i);const s=Math.round(100*i),l=this.dom.find("div.lh-gauge__percentage",n);return l.textContent=s.toString(),null===e.score&&(l.classList.add("lh-gauge--error"),l.textContent="",l.title=ue.strings.errorLabel),0===e.auditRefs.length||this.hasApplicableAudits(e)?t.classList.add(`lh-gauge__wrapper--${me.calculateRating(e.score)}`):(t.classList.add("lh-gauge__wrapper--not-applicable"),l.textContent="-",l.title=ue.strings.notApplicableAuditsGroupTitle),this.dom.find(".lh-gauge__label",n).textContent=e.title,n}renderCategoryFraction(e){const a=this.dom.createComponent("fraction"),n=this.dom.find("a.lh-fraction__wrapper",a),{numPassed:t,numPassableAudits:i,totalWeight:o}=me.calculateCategoryFraction(e),r=t/i,s=this.dom.find(".lh-fraction__content",a),l=this.dom.createElement("span");l.textContent=`${t}/${i}`,s.append(l);let p=me.calculateRating(r);return 0===o&&(p="null"),n.classList.add(`lh-fraction__wrapper--${p}`),this.dom.find(".lh-fraction__label",a).textContent=e.title,a}hasApplicableAudits(e){return e.auditRefs.some((e=>"notApplicable"!==e.result.scoreDisplayMode))}_setGaugeArc(e,a){const n=2*Math.PI*Number(e.getAttribute("r")),t=Number(e.getAttribute("stroke-width")),i=.25*t/n;e.style.transform=`rotate(${360*i-90}deg)`;let o=a*n-t/2;0===a&&(e.style.opacity="0"),1===a&&(o=n),e.style.strokeDasharray=`${Math.max(o,0)} ${n}`}_auditHasWarning(e){return Boolean(e.result.warnings?.length)}_getClumpIdForAuditRef(e){const a=e.result.scoreDisplayMode;return"manual"===a||"notApplicable"===a?a:me.showAsPassed(e.result)?this._auditHasWarning(e)?"warning":"passed":"failed"}render(e,a={},n){const t=this.dom.createElement("div","lh-category");t.id=e.id,t.append(this.renderCategoryHeader(e,a,n));const i=new Map;i.set("failed",[]),i.set("warning",[]),i.set("manual",[]),i.set("passed",[]),i.set("notApplicable",[]);for(const a of e.auditRefs){const e=this._getClumpIdForAuditRef(a),n=i.get(e);n.push(a),i.set(e,n)}for(const e of i.values())e.sort(((e,a)=>a.weight-e.weight));for(const[n,o]of i){if(0===o.length)continue;if("failed"===n){const e=this.renderUnexpandableClump(o,a);e.classList.add("lh-clump--failed"),t.append(e);continue}const i="manual"===n?e.manualDescription:void 0,r=this.renderClump(n,{auditRefs:o,description:i});t.append(r)}return t}}
84
84
  /**
85
85
  * @license
86
86
  * Copyright 2017 The Lighthouse Authors. All Rights Reserved.
@@ -63,7 +63,7 @@ const s=r.RATINGS;class c{static prepareReportResult(e){const t=JSON.parse(JSON.
63
63
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64
64
  * See the License for the specific language governing permissions and
65
65
  * limitations under the License.
66
- */class h{constructor(e,t){this.dom=e,this.detailsRenderer=t}get _clumpTitles(){return{warning:a.strings.warningAuditsGroupTitle,manual:a.strings.manualAuditsGroupTitle,passed:a.strings.passedAuditsGroupTitle,notApplicable:a.strings.notApplicableAuditsGroupTitle}}renderAudit(e){const t=this.dom.createComponent("audit");return this.populateAuditValues(e,t)}populateAuditValues(e,t){const n=a.strings,r=this.dom.find(".lh-audit",t);r.id=e.result.id;const o=e.result.scoreDisplayMode;e.result.displayValue&&(this.dom.find(".lh-audit__display-text",r).textContent=e.result.displayValue);const i=this.dom.find(".lh-audit__title",r);i.append(this.dom.convertMarkdownCodeSnippets(e.result.title));const l=this.dom.find(".lh-audit__description",r);l.append(this.dom.convertMarkdownLinkSnippets(e.result.description));for(const t of e.relevantMetrics||[]){const e=this.dom.createChildOf(l,"span","lh-audit__adorn");e.title=`Relevant to ${t.result.title}`,e.textContent=t.acronym||t.id}e.stackPacks&&e.stackPacks.forEach((e=>{const t=this.dom.createElement("img","lh-audit__stackpack__img");t.src=e.iconDataURL,t.alt=e.title;const n=this.dom.convertMarkdownLinkSnippets(e.description,{alwaysAppendUtmSource:!0}),o=this.dom.createElement("div","lh-audit__stackpack");o.append(t,n),this.dom.find(".lh-audit__stackpacks",r).append(o)}));const s=this.dom.find("details",r);if(e.result.details){const t=this.detailsRenderer.render(e.result.details);t&&(t.classList.add("lh-details"),s.append(t))}if(this.dom.find(".lh-chevron-container",r).append(this._createChevron()),this._setRatingClass(r,e.result.score,o),"error"===e.result.scoreDisplayMode){r.classList.add("lh-audit--error");const t=this.dom.find(".lh-audit__display-text",r);t.textContent=n.errorLabel,t.classList.add("lh-tooltip-boundary");this.dom.createChildOf(t,"div","lh-tooltip lh-tooltip--error").textContent=e.result.errorMessage||n.errorMissingAuditInfo}else if(e.result.explanation){this.dom.createChildOf(i,"div","lh-audit-explanation").textContent=e.result.explanation}const c=e.result.warnings;if(!c||0===c.length)return r;const d=this.dom.find("summary",s),h=this.dom.createChildOf(d,"div","lh-warnings");if(this.dom.createChildOf(h,"span").textContent=n.warningHeader,1===c.length)h.append(this.dom.createTextNode(c.join("")));else{const e=this.dom.createChildOf(h,"ul");for(const t of c){this.dom.createChildOf(e,"li").textContent=t}}return r}injectFinalScreenshot(e,t,n){const r=t["final-screenshot"];if(!r||"error"===r.scoreDisplayMode)return null;if(!r.details||"screenshot"!==r.details.type)return null;const o=this.dom.createElement("img","lh-final-ss-image"),i=r.details.data;o.src=i,o.alt=r.title;const a=this.dom.find(".lh-category .lh-category-header",e),l=this.dom.createElement("div","lh-category-headercol"),s=this.dom.createElement("div","lh-category-headercol lh-category-headercol--separator"),c=this.dom.createElement("div","lh-category-headercol");l.append(...a.childNodes),l.append(n),c.append(o),a.append(l,s,c),a.classList.add("lh-category-header__finalscreenshot")}_createChevron(){const e=this.dom.createComponent("chevron");return this.dom.find("svg.lh-chevron",e)}_setRatingClass(e,t,n){const r=c.calculateRating(t,n);return e.classList.add(`lh-audit--${n.toLowerCase()}`),"informative"!==n&&e.classList.add(`lh-audit--${r}`),e}renderCategoryHeader(e,t,n){const r=this.dom.createComponent("categoryHeader"),o=this.dom.find(".lh-score__gauge",r),i=this.renderCategoryScore(e,t,n);if(o.append(i),e.description){const t=this.dom.convertMarkdownLinkSnippets(e.description);this.dom.find(".lh-category-header__description",r).append(t)}return r}renderAuditGroup(e){const t=this.dom.createElement("div","lh-audit-group"),n=this.dom.createElement("div","lh-audit-group__header");this.dom.createChildOf(n,"span","lh-audit-group__title").textContent=e.title,t.append(n);let r=null;return e.description&&(r=this.dom.convertMarkdownLinkSnippets(e.description),r.classList.add("lh-audit-group__description","lh-audit-group__footer"),t.append(r)),[t,r]}_renderGroupedAudits(e,t){const n=new Map,r="NotAGroup";n.set(r,[]);for(const t of e){const e=t.group||r,o=n.get(e)||[];o.push(t),n.set(e,o)}const o=[];for(const[e,i]of n){if(e===r){for(const e of i)o.push(this.renderAudit(e));continue}const n=t[e],[a,l]=this.renderAuditGroup(n);for(const e of i)a.insertBefore(this.renderAudit(e),l);a.classList.add(`lh-audit-group--${e}`),o.push(a)}return o}renderUnexpandableClump(e,t){const n=this.dom.createElement("div");return this._renderGroupedAudits(e,t).forEach((e=>n.append(e))),n}renderClump(e,{auditRefs:t,description:n}){const r=this.dom.createComponent("clump"),o=this.dom.find(".lh-clump",r);"warning"===e&&o.setAttribute("open","");const i=this.dom.find(".lh-audit-group__header",o),l=this._clumpTitles[e];this.dom.find(".lh-audit-group__title",i).textContent=l;this.dom.find(".lh-audit-group__itemcount",o).textContent=`(${t.length})`;const s=t.map(this.renderAudit.bind(this));o.append(...s);const c=this.dom.find(".lh-audit-group",r);if(n){const e=this.dom.convertMarkdownLinkSnippets(n);e.classList.add("lh-audit-group__description","lh-audit-group__footer"),c.append(e)}return this.dom.find(".lh-clump-toggletext--show",c).textContent=a.strings.show,this.dom.find(".lh-clump-toggletext--hide",c).textContent=a.strings.hide,o.classList.add(`lh-clump--${e.toLowerCase()}`),c}renderCategoryScore(e,t,n){let r;if(r=n&&c.shouldDisplayAsFraction(n.gatherMode)?this.renderCategoryFraction(e):this.renderScoreGauge(e,t),n?.omitLabel){this.dom.find(".lh-gauge__label,.lh-fraction__label",r).remove()}if(n?.onPageAnchorRendered){const e=this.dom.find("a",r);n.onPageAnchorRendered(e)}return r}renderScoreGauge(e,t){const n=this.dom.createComponent("gauge"),r=this.dom.find("a.lh-gauge__wrapper",n);c.isPluginCategory(e.id)&&r.classList.add("lh-gauge__wrapper--plugin");const o=Number(e.score),i=this.dom.find(".lh-gauge",n),l=this.dom.find("circle.lh-gauge-arc",i);l&&this._setGaugeArc(l,o);const s=Math.round(100*o),d=this.dom.find("div.lh-gauge__percentage",n);return d.textContent=s.toString(),null===e.score&&(d.classList.add("lh-gauge--error"),d.textContent="",d.title=a.strings.errorLabel),0===e.auditRefs.length||this.hasApplicableAudits(e)?r.classList.add(`lh-gauge__wrapper--${c.calculateRating(e.score)}`):(r.classList.add("lh-gauge__wrapper--not-applicable"),d.textContent="-",d.title=a.strings.notApplicableAuditsGroupTitle),this.dom.find(".lh-gauge__label",n).textContent=e.title,n}renderCategoryFraction(e){const t=this.dom.createComponent("fraction"),n=this.dom.find("a.lh-fraction__wrapper",t),{numPassed:r,numPassableAudits:o,totalWeight:i}=c.calculateCategoryFraction(e),a=r/o,l=this.dom.find(".lh-fraction__content",t),s=this.dom.createElement("span");s.textContent=`${r}/${o}`,l.append(s);let d=c.calculateRating(a);return 0===i&&(d="null"),n.classList.add(`lh-fraction__wrapper--${d}`),this.dom.find(".lh-fraction__label",t).textContent=e.title,t}hasApplicableAudits(e){return e.auditRefs.some((e=>"notApplicable"!==e.result.scoreDisplayMode))}_setGaugeArc(e,t){const n=2*Math.PI*Number(e.getAttribute("r")),r=Number(e.getAttribute("stroke-width")),o=.25*r/n;e.style.transform=`rotate(${360*o-90}deg)`;let i=t*n-r/2;0===t&&(e.style.opacity="0"),1===t&&(i=n),e.style.strokeDasharray=`${Math.max(i,0)} ${n}`}_auditHasWarning(e){return Boolean(e.result.warnings?.length)}_getClumpIdForAuditRef(e){const t=e.result.scoreDisplayMode;return"manual"===t||"notApplicable"===t?t:c.showAsPassed(e.result)?this._auditHasWarning(e)?"warning":"passed":"failed"}render(e,t={},n){const r=this.dom.createElement("div","lh-category");r.id=e.id,r.append(this.renderCategoryHeader(e,t,n));const o=new Map;o.set("failed",[]),o.set("warning",[]),o.set("manual",[]),o.set("passed",[]),o.set("notApplicable",[]);for(const t of e.auditRefs){const e=this._getClumpIdForAuditRef(t),n=o.get(e);n.push(t),o.set(e,n)}for(const e of o.values())e.sort(((e,t)=>t.weight-e.weight));for(const[n,i]of o){if(0===i.length)continue;if("failed"===n){const e=this.renderUnexpandableClump(i,t);e.classList.add("lh-clump--failed"),r.append(e);continue}const o="manual"===n?e.manualDescription:void 0,a=this.renderClump(n,{auditRefs:i,description:o});r.append(a)}return r}}
66
+ */class h{constructor(e,t){this.dom=e,this.detailsRenderer=t}get _clumpTitles(){return{warning:a.strings.warningAuditsGroupTitle,manual:a.strings.manualAuditsGroupTitle,passed:a.strings.passedAuditsGroupTitle,notApplicable:a.strings.notApplicableAuditsGroupTitle}}renderAudit(e){const t=this.dom.createComponent("audit");return this.populateAuditValues(e,t)}populateAuditValues(e,t){const n=a.strings,r=this.dom.find(".lh-audit",t);r.id=e.result.id;const o=e.result.scoreDisplayMode;e.result.displayValue&&(this.dom.find(".lh-audit__display-text",r).textContent=e.result.displayValue);const i=this.dom.find(".lh-audit__title",r);i.append(this.dom.convertMarkdownCodeSnippets(e.result.title));const l=this.dom.find(".lh-audit__description",r);l.append(this.dom.convertMarkdownLinkSnippets(e.result.description));for(const t of e.relevantMetrics||[]){const e=this.dom.createChildOf(l,"span","lh-audit__adorn");e.title=`Relevant to ${t.result.title}`,e.textContent=t.acronym||t.id}e.stackPacks&&e.stackPacks.forEach((e=>{const t=this.dom.createElement("img","lh-audit__stackpack__img");t.src=e.iconDataURL,t.alt=e.title;const n=this.dom.convertMarkdownLinkSnippets(e.description,{alwaysAppendUtmSource:!0}),o=this.dom.createElement("div","lh-audit__stackpack");o.append(t,n),this.dom.find(".lh-audit__stackpacks",r).append(o)}));const s=this.dom.find("details",r);if(e.result.details){const t=this.detailsRenderer.render(e.result.details);t&&(t.classList.add("lh-details"),s.append(t))}if(this.dom.find(".lh-chevron-container",r).append(this._createChevron()),this._setRatingClass(r,e.result.score,o),"error"===e.result.scoreDisplayMode){r.classList.add("lh-audit--error");const t=this.dom.find(".lh-audit__display-text",r);t.textContent=n.errorLabel,t.classList.add("lh-tooltip-boundary");this.dom.createChildOf(t,"div","lh-tooltip lh-tooltip--error").textContent=e.result.errorMessage||n.errorMissingAuditInfo}else if(e.result.explanation){this.dom.createChildOf(i,"div","lh-audit-explanation").textContent=e.result.explanation}const c=e.result.warnings;if(!c||0===c.length)return r;const d=this.dom.find("summary",s),h=this.dom.createChildOf(d,"div","lh-warnings");if(this.dom.createChildOf(h,"span").textContent=n.warningHeader,1===c.length)h.append(this.dom.createTextNode(c.join("")));else{const e=this.dom.createChildOf(h,"ul");for(const t of c){this.dom.createChildOf(e,"li").textContent=t}}return r}injectFinalScreenshot(e,t,n){const r=t["final-screenshot"];if(!r||"error"===r.scoreDisplayMode)return null;if(!r.details||"screenshot"!==r.details.type)return null;const o=this.dom.createElement("img","lh-final-ss-image"),i=r.details.data;o.src=i,o.alt=r.title;const a=this.dom.find(".lh-category .lh-category-header",e),l=this.dom.createElement("div","lh-category-headercol"),s=this.dom.createElement("div","lh-category-headercol lh-category-headercol--separator"),c=this.dom.createElement("div","lh-category-headercol");l.append(...a.childNodes),l.append(n),c.append(o),a.append(l,s,c),a.classList.add("lh-category-header__finalscreenshot")}_createChevron(){const e=this.dom.createComponent("chevron");return this.dom.find("svg.lh-chevron",e)}_setRatingClass(e,t,n){const r=c.calculateRating(t,n);return e.classList.add(`lh-audit--${n.toLowerCase()}`),"informative"!==n&&e.classList.add(`lh-audit--${r}`),e}renderCategoryHeader(e,t,n){const r=this.dom.createComponent("categoryHeader"),o=this.dom.find(".lh-score__gauge",r),i=this.renderCategoryScore(e,t,n);if(o.append(i),e.description){const t=this.dom.convertMarkdownLinkSnippets(e.description);this.dom.find(".lh-category-header__description",r).append(t)}return r}renderAuditGroup(e){const t=this.dom.createElement("div","lh-audit-group"),n=this.dom.createElement("div","lh-audit-group__header");this.dom.createChildOf(n,"span","lh-audit-group__title").textContent=e.title,t.append(n);let r=null;return e.description&&(r=this.dom.convertMarkdownLinkSnippets(e.description),r.classList.add("lh-audit-group__description","lh-audit-group__footer"),t.append(r)),[t,r]}_renderGroupedAudits(e,t){const n=new Map,r="NotAGroup";n.set(r,[]);for(const t of e){const e=t.group||r;if("hidden"===e)continue;const o=n.get(e)||[];o.push(t),n.set(e,o)}const o=[];for(const[e,i]of n){if(e===r){for(const e of i)o.push(this.renderAudit(e));continue}const n=t[e],[a,l]=this.renderAuditGroup(n);for(const e of i)a.insertBefore(this.renderAudit(e),l);a.classList.add(`lh-audit-group--${e}`),o.push(a)}return o}renderUnexpandableClump(e,t){const n=this.dom.createElement("div");return this._renderGroupedAudits(e,t).forEach((e=>n.append(e))),n}renderClump(e,{auditRefs:t,description:n}){const r=this.dom.createComponent("clump"),o=this.dom.find(".lh-clump",r);"warning"===e&&o.setAttribute("open","");const i=this.dom.find(".lh-audit-group__header",o),l=this._clumpTitles[e];this.dom.find(".lh-audit-group__title",i).textContent=l;this.dom.find(".lh-audit-group__itemcount",o).textContent=`(${t.length})`;const s=t.map(this.renderAudit.bind(this));o.append(...s);const c=this.dom.find(".lh-audit-group",r);if(n){const e=this.dom.convertMarkdownLinkSnippets(n);e.classList.add("lh-audit-group__description","lh-audit-group__footer"),c.append(e)}return this.dom.find(".lh-clump-toggletext--show",c).textContent=a.strings.show,this.dom.find(".lh-clump-toggletext--hide",c).textContent=a.strings.hide,o.classList.add(`lh-clump--${e.toLowerCase()}`),c}renderCategoryScore(e,t,n){let r;if(r=n&&c.shouldDisplayAsFraction(n.gatherMode)?this.renderCategoryFraction(e):this.renderScoreGauge(e,t),n?.omitLabel){this.dom.find(".lh-gauge__label,.lh-fraction__label",r).remove()}if(n?.onPageAnchorRendered){const e=this.dom.find("a",r);n.onPageAnchorRendered(e)}return r}renderScoreGauge(e,t){const n=this.dom.createComponent("gauge"),r=this.dom.find("a.lh-gauge__wrapper",n);c.isPluginCategory(e.id)&&r.classList.add("lh-gauge__wrapper--plugin");const o=Number(e.score),i=this.dom.find(".lh-gauge",n),l=this.dom.find("circle.lh-gauge-arc",i);l&&this._setGaugeArc(l,o);const s=Math.round(100*o),d=this.dom.find("div.lh-gauge__percentage",n);return d.textContent=s.toString(),null===e.score&&(d.classList.add("lh-gauge--error"),d.textContent="",d.title=a.strings.errorLabel),0===e.auditRefs.length||this.hasApplicableAudits(e)?r.classList.add(`lh-gauge__wrapper--${c.calculateRating(e.score)}`):(r.classList.add("lh-gauge__wrapper--not-applicable"),d.textContent="-",d.title=a.strings.notApplicableAuditsGroupTitle),this.dom.find(".lh-gauge__label",n).textContent=e.title,n}renderCategoryFraction(e){const t=this.dom.createComponent("fraction"),n=this.dom.find("a.lh-fraction__wrapper",t),{numPassed:r,numPassableAudits:o,totalWeight:i}=c.calculateCategoryFraction(e),a=r/o,l=this.dom.find(".lh-fraction__content",t),s=this.dom.createElement("span");s.textContent=`${r}/${o}`,l.append(s);let d=c.calculateRating(a);return 0===i&&(d="null"),n.classList.add(`lh-fraction__wrapper--${d}`),this.dom.find(".lh-fraction__label",t).textContent=e.title,t}hasApplicableAudits(e){return e.auditRefs.some((e=>"notApplicable"!==e.result.scoreDisplayMode))}_setGaugeArc(e,t){const n=2*Math.PI*Number(e.getAttribute("r")),r=Number(e.getAttribute("stroke-width")),o=.25*r/n;e.style.transform=`rotate(${360*o-90}deg)`;let i=t*n-r/2;0===t&&(e.style.opacity="0"),1===t&&(i=n),e.style.strokeDasharray=`${Math.max(i,0)} ${n}`}_auditHasWarning(e){return Boolean(e.result.warnings?.length)}_getClumpIdForAuditRef(e){const t=e.result.scoreDisplayMode;return"manual"===t||"notApplicable"===t?t:c.showAsPassed(e.result)?this._auditHasWarning(e)?"warning":"passed":"failed"}render(e,t={},n){const r=this.dom.createElement("div","lh-category");r.id=e.id,r.append(this.renderCategoryHeader(e,t,n));const o=new Map;o.set("failed",[]),o.set("warning",[]),o.set("manual",[]),o.set("passed",[]),o.set("notApplicable",[]);for(const t of e.auditRefs){const e=this._getClumpIdForAuditRef(t),n=o.get(e);n.push(t),o.set(e,n)}for(const e of o.values())e.sort(((e,t)=>t.weight-e.weight));for(const[n,i]of o){if(0===i.length)continue;if("failed"===n){const e=this.renderUnexpandableClump(i,t);e.classList.add("lh-clump--failed"),r.append(e);continue}const o="manual"===n?e.manualDescription:void 0,a=this.renderClump(n,{auditRefs:i,description:o});r.append(a)}return r}}
67
67
  /**
68
68
  * @license
69
69
  * Copyright 2017 The Lighthouse Authors. All Rights Reserved.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "10.3.0-dev.20230705",
4
+ "version": "10.3.0-dev.20230707",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
@@ -169,7 +169,7 @@
169
169
  "pako": "^2.0.3",
170
170
  "preact": "^10.7.2",
171
171
  "pretty-json-stringify": "^0.0.2",
172
- "puppeteer": "^20.7.1",
172
+ "puppeteer": "^20.8.0",
173
173
  "resolve": "^1.20.0",
174
174
  "rollup": "^2.52.7",
175
175
  "rollup-plugin-node-resolve": "^5.2.0",
@@ -205,7 +205,7 @@
205
205
  "open": "^8.4.0",
206
206
  "parse-cache-control": "1.0.1",
207
207
  "ps-list": "^8.0.0",
208
- "puppeteer-core": "^20.7.1",
208
+ "puppeteer-core": "^20.8.0",
209
209
  "robots-parser": "^3.0.0",
210
210
  "semver": "^5.3.0",
211
211
  "speedline-core": "^1.4.3",
@@ -260,6 +260,7 @@ export class CategoryRenderer {
260
260
 
261
261
  for (const auditRef of auditRefs) {
262
262
  const groupId = auditRef.group || notAGroup;
263
+ if (groupId === 'hidden') continue;
263
264
  const groupAuditRefs = grouped.get(groupId) || [];
264
265
  groupAuditRefs.push(auditRef);
265
266
  grouped.set(groupId, groupAuditRefs);
@@ -245,6 +245,15 @@
245
245
  "core/audits/accessibility/duplicate-id-aria.js | title": {
246
246
  "message": "ARIA IDs are unique"
247
247
  },
248
+ "core/audits/accessibility/empty-heading.js | description": {
249
+ "message": "A heading with no content or inaccessible text prevent screen reader users from accessing information on the page's structure. [Learn more about headings](https://dequeuniversity.com/rules/axe/4.7/empty-heading)."
250
+ },
251
+ "core/audits/accessibility/empty-heading.js | failureTitle": {
252
+ "message": "Heading elements do not contain content."
253
+ },
254
+ "core/audits/accessibility/empty-heading.js | title": {
255
+ "message": "All heading elements contain content."
256
+ },
248
257
  "core/audits/accessibility/form-field-multiple-labels.js | description": {
249
258
  "message": "Form fields with multiple labels can be confusingly announced by assistive technologies like screen readers which use either the first, the last, or all of the labels. [Learn how to use form labels](https://dequeuniversity.com/rules/axe/4.7/form-field-multiple-labels)."
250
259
  },
@@ -299,6 +308,15 @@
299
308
  "core/audits/accessibility/html-xml-lang-mismatch.js | title": {
300
309
  "message": "`<html>` element has an `[xml:lang]` attribute with the same base language as the `[lang]` attribute."
301
310
  },
311
+ "core/audits/accessibility/identical-links-same-purpose.js | description": {
312
+ "message": "Links with the same destination should have the same description, to help users understand the link's purpose and decide whether to follow it. [Learn more about identical links](https://dequeuniversity.com/rules/axe/4.7/identical-links-same-purpose)."
313
+ },
314
+ "core/audits/accessibility/identical-links-same-purpose.js | failureTitle": {
315
+ "message": "Identical links do not have the same purpose."
316
+ },
317
+ "core/audits/accessibility/identical-links-same-purpose.js | title": {
318
+ "message": "Identical links have the same purpose."
319
+ },
302
320
  "core/audits/accessibility/image-alt.js | description": {
303
321
  "message": "Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute. [Learn more about the `alt` attribute](https://dequeuniversity.com/rules/axe/4.7/image-alt)."
304
322
  },
@@ -335,6 +353,15 @@
335
353
  "core/audits/accessibility/label.js | title": {
336
354
  "message": "Form elements have associated labels"
337
355
  },
356
+ "core/audits/accessibility/landmark-one-main.js | description": {
357
+ "message": "One main landmark helps screen reader users navigate a web page. [Learn more about landmarks](https://dequeuniversity.com/rules/axe/4.7/landmark-one-main)."
358
+ },
359
+ "core/audits/accessibility/landmark-one-main.js | failureTitle": {
360
+ "message": "Document does not have a main landmark."
361
+ },
362
+ "core/audits/accessibility/landmark-one-main.js | title": {
363
+ "message": "Document has a main landmark."
364
+ },
338
365
  "core/audits/accessibility/link-in-text-block.js | description": {
339
366
  "message": "Low-contrast text is difficult or impossible for many users to read. Link text that is discernible improves the experience for users with low vision. [Learn how to make links distinguishable](https://dequeuniversity.com/rules/axe/4.7/link-in-text-block)."
340
367
  },
@@ -425,6 +452,15 @@
425
452
  "core/audits/accessibility/table-fake-caption.js | title": {
426
453
  "message": "Tables use `<caption>` instead of cells with the `[colspan]` attribute to indicate a caption."
427
454
  },
455
+ "core/audits/accessibility/target-size.js | description": {
456
+ "message": "Touch targets with sufficient size and spacing help users who may have difficulty targeting small controls activate the targets. [Learn more about touch targets](https://dequeuniversity.com/rules/axe/4.7/target-size)."
457
+ },
458
+ "core/audits/accessibility/target-size.js | failureTitle": {
459
+ "message": "Touch targets do not have sufficient size or spacing."
460
+ },
461
+ "core/audits/accessibility/target-size.js | title": {
462
+ "message": "Touch targets have sufficient size and spacing."
463
+ },
428
464
  "core/audits/accessibility/td-has-header.js | description": {
429
465
  "message": "Screen readers have features to make navigating tables easier. Ensuring that `<td>` elements in a large table (3 or more cells in width and height) have an associated table header may improve the experience for screen reader users. [Learn more about table headers](https://dequeuniversity.com/rules/axe/4.7/td-has-header)."
430
466
  },
@@ -245,6 +245,15 @@
245
245
  "core/audits/accessibility/duplicate-id-aria.js | title": {
246
246
  "message": "ÂŔÎÁ ÎD́ŝ ár̂é ûńîq́ûé"
247
247
  },
248
+ "core/audits/accessibility/empty-heading.js | description": {
249
+ "message": "Â h́êád̂ín̂ǵ ŵít̂h́ n̂ó ĉón̂t́êńt̂ ór̂ ín̂áĉćêśŝíb̂ĺê t́êx́t̂ ṕr̂év̂én̂t́ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ f́r̂óm̂ áĉćêśŝín̂ǵ îńf̂ór̂ḿât́îón̂ ón̂ t́ĥé p̂áĝé'ŝ śt̂ŕûćt̂úr̂é. [L̂éâŕn̂ ḿôŕê áb̂óût́ ĥéâd́îńĝś](https://dequeuniversity.com/rules/axe/4.7/empty-heading)."
250
+ },
251
+ "core/audits/accessibility/empty-heading.js | failureTitle": {
252
+ "message": "Ĥéâd́îńĝ él̂ém̂én̂t́ŝ d́ô ńôt́ ĉón̂t́âín̂ ćôńt̂én̂t́."
253
+ },
254
+ "core/audits/accessibility/empty-heading.js | title": {
255
+ "message": "Âĺl̂ h́êád̂ín̂ǵ êĺêḿêńt̂ś ĉón̂t́âín̂ ćôńt̂én̂t́."
256
+ },
248
257
  "core/audits/accessibility/form-field-multiple-labels.js | description": {
249
258
  "message": "F̂ór̂ḿ f̂íêĺd̂ś ŵít̂h́ m̂úl̂t́îṕl̂é l̂áb̂él̂ś ĉán̂ b́ê ćôńf̂úŝín̂ǵl̂ý âńn̂óûńĉéd̂ b́ŷ áŝśîśt̂ív̂é t̂éĉh́n̂ól̂óĝíêś l̂ík̂é ŝćr̂éêń r̂éâd́êŕŝ ẃĥíĉh́ ûśê éît́ĥér̂ t́ĥé f̂ír̂śt̂, t́ĥé l̂áŝt́, ôŕ âĺl̂ óf̂ t́ĥé l̂áb̂él̂ś. [L̂éâŕn̂ h́ôẃ t̂ó ûśê f́ôŕm̂ ĺâb́êĺŝ](https://dequeuniversity.com/rules/axe/4.7/form-field-multiple-labels)."
250
259
  },
@@ -299,6 +308,15 @@
299
308
  "core/audits/accessibility/html-xml-lang-mismatch.js | title": {
300
309
  "message": "`<html>` êĺêḿêńt̂ h́âś âń `[xml:lang]` ât́t̂ŕîb́ût́ê ẃît́ĥ t́ĥé ŝám̂é b̂áŝé l̂án̂ǵûáĝé âś t̂h́ê `[lang]` át̂t́r̂íb̂út̂é."
301
310
  },
311
+ "core/audits/accessibility/identical-links-same-purpose.js | description": {
312
+ "message": "L̂ín̂ḱŝ ẃît́ĥ t́ĥé ŝám̂é d̂éŝt́îńât́îón̂ śĥóûĺd̂ h́âv́ê t́ĥé ŝám̂é d̂éŝćr̂íp̂t́îón̂, t́ô h́êĺp̂ úŝér̂ś ûńd̂ér̂śt̂án̂d́ t̂h́ê ĺîńk̂'ś p̂úr̂ṕôśê án̂d́ d̂éĉíd̂é ŵh́êt́ĥér̂ t́ô f́ôĺl̂óŵ ít̂. [Ĺêár̂ń m̂ór̂é âb́ôút̂ íd̂én̂t́îćâĺ l̂ín̂ḱŝ](https://dequeuniversity.com/rules/axe/4.7/identical-links-same-purpose)."
313
+ },
314
+ "core/audits/accessibility/identical-links-same-purpose.js | failureTitle": {
315
+ "message": "Îd́êńt̂íĉál̂ ĺîńk̂ś d̂ó n̂ót̂ h́âv́ê t́ĥé ŝám̂é p̂úr̂ṕôśê."
316
+ },
317
+ "core/audits/accessibility/identical-links-same-purpose.js | title": {
318
+ "message": "Îd́êńt̂íĉál̂ ĺîńk̂ś ĥáv̂é t̂h́ê śâḿê ṕûŕp̂óŝé."
319
+ },
302
320
  "core/audits/accessibility/image-alt.js | description": {
303
321
  "message": "Îńf̂ór̂ḿât́îv́ê él̂ém̂én̂t́ŝ śĥóûĺd̂ áîḿ f̂ór̂ śĥór̂t́, d̂éŝćr̂íp̂t́îv́ê ál̂t́êŕn̂át̂é t̂éx̂t́. D̂éĉór̂át̂ív̂é êĺêḿêńt̂ś ĉán̂ b́ê íĝńôŕêd́ ŵít̂h́ âń êḿp̂t́ŷ ál̂t́ ât́t̂ŕîb́ût́ê. [Ĺêár̂ń m̂ór̂é âb́ôút̂ t́ĥé `alt` ât́t̂ŕîb́ût́ê](https://dequeuniversity.com/rules/axe/4.7/image-alt)."
304
322
  },
@@ -335,6 +353,15 @@
335
353
  "core/audits/accessibility/label.js | title": {
336
354
  "message": "F̂ór̂ḿ êĺêḿêńt̂ś ĥáv̂é âśŝóĉíât́êd́ l̂áb̂él̂ś"
337
355
  },
356
+ "core/audits/accessibility/landmark-one-main.js | description": {
357
+ "message": "Ôńê ḿâín̂ ĺâńd̂ḿâŕk̂ h́êĺp̂ś ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ ńâv́îǵât́ê á ŵéb̂ ṕâǵê. [Ĺêár̂ń m̂ór̂é âb́ôút̂ ĺâńd̂ḿâŕk̂ś](https://dequeuniversity.com/rules/axe/4.7/landmark-one-main)."
358
+ },
359
+ "core/audits/accessibility/landmark-one-main.js | failureTitle": {
360
+ "message": "D̂óĉúm̂én̂t́ d̂óêś n̂ót̂ h́âv́ê á m̂áîń l̂án̂d́m̂ár̂ḱ."
361
+ },
362
+ "core/audits/accessibility/landmark-one-main.js | title": {
363
+ "message": "D̂óĉúm̂én̂t́ ĥáŝ á m̂áîń l̂án̂d́m̂ár̂ḱ."
364
+ },
338
365
  "core/audits/accessibility/link-in-text-block.js | description": {
339
366
  "message": "L̂óŵ-ćôńt̂ŕâśt̂ t́êx́t̂ íŝ d́îf́f̂íĉúl̂t́ ôŕ îḿp̂óŝśîb́l̂é f̂ór̂ ḿâńŷ úŝér̂ś t̂ó r̂éâd́. L̂ín̂ḱ t̂éx̂t́ t̂h́ât́ îś d̂íŝćêŕn̂íb̂ĺê ím̂ṕr̂óv̂éŝ t́ĥé êx́p̂ér̂íêńĉé f̂ór̂ úŝér̂ś ŵít̂h́ l̂óŵ v́îśîón̂. [Ĺêár̂ń ĥóŵ t́ô ḿâḱê ĺîńk̂ś d̂íŝt́îńĝúîśĥáb̂ĺê](https://dequeuniversity.com/rules/axe/4.7/link-in-text-block)."
340
367
  },
@@ -425,6 +452,15 @@
425
452
  "core/audits/accessibility/table-fake-caption.js | title": {
426
453
  "message": "T̂áb̂ĺêś ûśê `<caption>` ín̂śt̂éâd́ ôf́ ĉél̂ĺŝ ẃît́ĥ t́ĥé `[colspan]` ât́t̂ŕîb́ût́ê t́ô ín̂d́îćât́ê á ĉáp̂t́îón̂."
427
454
  },
455
+ "core/audits/accessibility/target-size.js | description": {
456
+ "message": "T̂óûćĥ t́âŕĝét̂ś ŵít̂h́ ŝúf̂f́îćîén̂t́ ŝíẑé âńd̂ śp̂áĉín̂ǵ ĥél̂ṕ ûśêŕŝ ẃĥó m̂áŷ h́âv́ê d́îf́f̂íĉúl̂t́ŷ t́âŕĝét̂ín̂ǵ ŝḿâĺl̂ ćôńt̂ŕôĺŝ áĉt́îv́ât́ê t́ĥé t̂ár̂ǵêt́ŝ. [Ĺêár̂ń m̂ór̂é âb́ôút̂ t́ôúĉh́ t̂ár̂ǵêt́ŝ](https://dequeuniversity.com/rules/axe/4.7/target-size)."
457
+ },
458
+ "core/audits/accessibility/target-size.js | failureTitle": {
459
+ "message": "T̂óûćĥ t́âŕĝét̂ś d̂ó n̂ót̂ h́âv́ê śûf́f̂íĉíêńt̂ śîźê ór̂ śp̂áĉín̂ǵ."
460
+ },
461
+ "core/audits/accessibility/target-size.js | title": {
462
+ "message": "T̂óûćĥ t́âŕĝét̂ś ĥáv̂é ŝúf̂f́îćîén̂t́ ŝíẑé âńd̂ śp̂áĉín̂ǵ."
463
+ },
428
464
  "core/audits/accessibility/td-has-header.js | description": {
429
465
  "message": "Ŝćr̂éêń r̂éâd́êŕŝ h́âv́ê f́êát̂úr̂éŝ t́ô ḿâḱê ńâv́îǵât́îńĝ t́âb́l̂éŝ éâśîér̂. Én̂śûŕîńĝ t́ĥát̂ `<td>` él̂ém̂én̂t́ŝ ín̂ á l̂ár̂ǵê t́âb́l̂é (3 ôŕ m̂ór̂é ĉél̂ĺŝ ín̂ ẃîd́t̂h́ âńd̂ h́êíĝh́t̂) h́âv́ê án̂ áŝśôćîát̂éd̂ t́âb́l̂é ĥéâd́êŕ m̂áŷ ím̂ṕr̂óv̂é t̂h́ê éx̂ṕêŕîén̂ćê f́ôŕ ŝćr̂éêń r̂éâd́êŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é âb́ôút̂ t́âb́l̂é ĥéâd́êŕŝ](https://dequeuniversity.com/rules/axe/4.7/td-has-header)."
430
466
  },
@@ -11,7 +11,7 @@ import {Simulator} from '../core/lib/dependency-graph/simulator/simulator.js';
11
11
  import {LighthouseError} from '../core/lib/lh-error.js';
12
12
  import {NetworkRequest as _NetworkRequest} from '../core/lib/network-request.js';
13
13
  import speedline from 'speedline-core';
14
- import * as TextSourceMap from '../core/lib/cdt/generated/SourceMap.js';
14
+ import * as CDTSourceMap from '../core/lib/cdt/generated/SourceMap.js';
15
15
  import {ArbitraryEqualityMap} from '../core/lib/arbitrary-equality-map.js';
16
16
  import type { TaskNode as _TaskNode } from '../core/lib/tracehouse/main-thread-tasks.js';
17
17
  import AuditDetails from './lhr/audit-details.js'
@@ -388,7 +388,7 @@ declare module Artifacts {
388
388
  interface Bundle {
389
389
  rawMap: RawSourceMap;
390
390
  script: Artifacts.Script;
391
- map: TextSourceMap;
391
+ map: CDTSourceMap;
392
392
  sizes: {
393
393
  // TODO(cjamcl): Rename to `sources`.
394
394
  files: Record<string, number>;