lighthouse 11.7.1 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +2 -2
- package/cli/bin.js +0 -7
- package/cli/cli-flags.d.ts +1 -5
- package/cli/cli-flags.js +4 -8
- package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +14 -14
- package/cli/test/smokehouse/config/exclusions.js +3 -0
- package/cli/test/smokehouse/core-tests.js +6 -20
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +2 -2
- package/core/audits/accessibility/aria-conditional-attr.d.ts +10 -0
- package/core/audits/accessibility/aria-conditional-attr.js +43 -0
- package/core/audits/accessibility/{duplicate-id-active.d.ts → aria-deprecated-role.d.ts} +3 -3
- package/core/audits/accessibility/aria-deprecated-role.js +43 -0
- package/core/audits/accessibility/aria-prohibited-attr.d.ts +10 -0
- package/core/audits/accessibility/aria-prohibited-attr.js +44 -0
- package/core/audits/accessibility/target-size.js +0 -1
- package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +0 -16
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +1 -38
- package/core/audits/byte-efficiency/offscreen-images.d.ts +0 -11
- package/core/audits/byte-efficiency/offscreen-images.js +0 -15
- package/core/audits/byte-efficiency/render-blocking-resources.js +27 -26
- package/core/audits/byte-efficiency/unminified-css.js +2 -2
- package/core/audits/byte-efficiency/unused-css-rules.js +3 -1
- package/core/audits/dobetterweb/uses-http2.d.ts +0 -13
- package/core/audits/dobetterweb/uses-http2.js +4 -38
- package/core/audits/font-display.js +2 -2
- package/core/audits/layout-shifts.js +1 -1
- package/core/audits/preload-fonts.d.ts +1 -5
- package/core/audits/preload-fonts.js +1 -10
- package/core/audits/prioritize-lcp-image.js +2 -2
- package/core/audits/redirects-http.d.ts +19 -0
- package/core/audits/redirects-http.js +75 -0
- package/core/audits/resource-summary.d.ts +2 -0
- package/core/audits/resource-summary.js +5 -4
- package/core/audits/seo/is-crawlable.d.ts +2 -1
- package/core/audits/seo/link-text.js +12 -0
- package/core/audits/uses-rel-preload.d.ts +1 -5
- package/core/audits/uses-rel-preload.js +5 -15
- package/core/audits/work-during-interaction.d.ts +2 -2
- package/core/audits/work-during-interaction.js +2 -2
- package/core/computed/js-bundles.d.ts +1 -1
- package/core/computed/metrics/lantern-first-contentful-paint.d.ts +13 -82
- package/core/computed/metrics/lantern-first-contentful-paint.js +16 -178
- package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +13 -12
- package/core/computed/metrics/lantern-first-meaningful-paint.js +11 -49
- package/core/computed/metrics/lantern-interactive.d.ts +13 -21
- package/core/computed/metrics/lantern-interactive.js +12 -84
- package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +13 -25
- package/core/computed/metrics/lantern-largest-contentful-paint.js +13 -80
- package/core/computed/metrics/lantern-max-potential-fid.d.ts +13 -24
- package/core/computed/metrics/lantern-max-potential-fid.js +12 -64
- package/core/computed/metrics/lantern-metric.d.ts +14 -18
- package/core/computed/metrics/lantern-metric.js +34 -30
- package/core/computed/metrics/lantern-speed-index.d.ts +13 -32
- package/core/computed/metrics/lantern-speed-index.js +13 -116
- package/core/computed/metrics/lantern-total-blocking-time.d.ts +13 -25
- package/core/computed/metrics/lantern-total-blocking-time.js +10 -94
- package/core/computed/metrics/metric.js +1 -3
- package/core/computed/module-duplication.d.ts +1 -1
- package/core/computed/navigation-insights.d.ts +36 -0
- package/core/computed/navigation-insights.js +35 -0
- package/core/computed/page-dependency-graph.js +3 -7
- package/core/computed/resource-summary.d.ts +10 -12
- package/core/computed/resource-summary.js +12 -19
- package/core/computed/trace-engine-result.d.ts +16 -3
- package/core/computed/trace-engine-result.js +19 -14
- package/core/computed/unused-css.d.ts +3 -1
- package/core/computed/unused-css.js +6 -5
- package/core/config/config-helpers.js +0 -4
- package/core/config/constants.js +0 -1
- package/core/config/default-config.js +63 -142
- package/core/config/experimental-config.js +11 -0
- package/core/config/filters.js +0 -1
- package/core/gather/driver/navigation.js +4 -1
- package/core/gather/driver/prepare.js +1 -1
- package/core/gather/driver/target-manager.js +4 -3
- package/core/gather/driver/wait-for-condition.js +2 -3
- package/core/gather/driver.d.ts +12 -0
- package/core/gather/driver.js +27 -0
- package/core/gather/gatherers/accessibility.js +4 -6
- package/core/gather/gatherers/css-usage.d.ts +0 -21
- package/core/gather/gatherers/css-usage.js +9 -119
- package/core/gather/gatherers/root-causes.d.ts +2 -2
- package/core/gather/gatherers/root-causes.js +6 -5
- package/core/gather/gatherers/stylesheets.d.ts +26 -0
- package/core/gather/gatherers/stylesheets.js +138 -0
- package/core/gather/gatherers/trace-elements.d.ts +2 -12
- package/core/gather/gatherers/trace-elements.js +2 -21
- package/core/gather/navigation-runner.js +3 -1
- package/core/gather/session.d.ts +8 -0
- package/core/gather/session.js +14 -1
- package/core/lib/emulation.js +2 -2
- package/core/lib/i18n/i18n.d.ts +0 -1
- package/core/lib/i18n/i18n.js +0 -2
- package/core/lib/lantern/cpu-node.d.ts +7 -1
- package/core/lib/lantern/cpu-node.js +12 -2
- package/core/lib/lantern/lantern-error.d.ts +8 -0
- package/core/lib/lantern/lantern-error.js +9 -0
- package/core/lib/lantern/metric.js +2 -6
- package/core/lib/lantern/metrics/first-contentful-paint.d.ts +79 -0
- package/core/lib/lantern/metrics/first-contentful-paint.js +200 -0
- package/core/lib/lantern/metrics/first-meaningful-paint.d.ts +6 -0
- package/core/lib/lantern/metrics/first-meaningful-paint.js +64 -0
- package/core/lib/lantern/metrics/interactive.d.ts +26 -0
- package/core/lib/lantern/metrics/interactive.js +112 -0
- package/core/lib/lantern/metrics/largest-contentful-paint.d.ts +19 -0
- package/core/lib/lantern/metrics/largest-contentful-paint.js +108 -0
- package/core/lib/lantern/metrics/max-potential-fid.d.ts +30 -0
- package/core/lib/lantern/metrics/max-potential-fid.js +92 -0
- package/core/lib/lantern/metrics/speed-index.d.ts +38 -0
- package/core/lib/lantern/metrics/speed-index.js +144 -0
- package/core/lib/lantern/metrics/total-blocking-time.d.ts +31 -0
- package/core/lib/lantern/metrics/total-blocking-time.js +128 -0
- package/core/lib/lantern/network-node.js +28 -4
- package/core/lib/lantern/page-dependency-graph.d.ts +4 -4
- package/core/lib/lantern/page-dependency-graph.js +19 -7
- package/core/lib/lantern/simulator/connection-pool.d.ts +2 -12
- package/core/lib/lantern/simulator/connection-pool.js +3 -22
- package/core/lib/lantern/simulator/network-analyzer.js +1 -12
- package/core/lib/lantern/simulator/simulator.d.ts +2 -4
- package/core/lib/lantern/simulator/simulator.js +7 -14
- package/core/lib/lantern/types/lantern.d.ts +5 -3
- package/core/lib/lantern-trace-saver.js +0 -1
- package/core/lib/lh-error.d.ts +9 -0
- package/core/lib/lh-error.js +13 -3
- package/core/lib/lighthouse-compatibility.js +53 -10
- package/core/lib/navigation-error.js +3 -0
- package/core/lib/network-request.d.ts +1 -0
- package/core/lib/network-request.js +28 -0
- package/core/runner.js +18 -25
- package/dist/report/bundle.esm.js +11 -112
- package/dist/report/flow.js +16 -117
- package/dist/report/standalone.js +12 -113
- package/flow-report/src/help-dialog.tsx +0 -1
- package/flow-report/src/i18n/i18n.d.ts +0 -4
- package/flow-report/src/i18n/ui-strings.d.ts +0 -1
- package/flow-report/src/i18n/ui-strings.js +0 -2
- package/flow-report/src/summary/category.tsx +10 -12
- package/package.json +5 -5
- package/readme.md +4 -4
- package/report/assets/styles.css +1 -60
- package/report/assets/templates.html +0 -95
- package/report/renderer/category-renderer.js +1 -1
- package/report/renderer/components.d.ts +2 -2
- package/report/renderer/components.js +2 -103
- package/report/renderer/dom.d.ts +1 -1
- package/report/renderer/dom.js +1 -1
- package/report/renderer/performance-category-renderer.d.ts +0 -7
- package/report/renderer/performance-category-renderer.js +1 -32
- package/report/renderer/report-renderer.js +3 -13
- package/report/renderer/report-ui-features.js +1 -1
- package/report/renderer/report-utils.d.ts +0 -1
- package/report/renderer/report-utils.js +13 -13
- package/shared/localization/locales/ar-XB.json +62 -329
- package/shared/localization/locales/ar.json +62 -329
- package/shared/localization/locales/bg.json +62 -329
- package/shared/localization/locales/ca.json +62 -329
- package/shared/localization/locales/cs.json +62 -329
- package/shared/localization/locales/da.json +62 -329
- package/shared/localization/locales/de.json +62 -329
- package/shared/localization/locales/el.json +62 -329
- package/shared/localization/locales/en-GB.json +62 -329
- package/shared/localization/locales/en-US.json +41 -272
- package/shared/localization/locales/en-XA.json +62 -329
- package/shared/localization/locales/en-XL.json +41 -272
- package/shared/localization/locales/es-419.json +62 -329
- package/shared/localization/locales/es.json +62 -329
- package/shared/localization/locales/fi.json +62 -329
- package/shared/localization/locales/fil.json +61 -328
- package/shared/localization/locales/fr.json +62 -329
- package/shared/localization/locales/he.json +62 -329
- package/shared/localization/locales/hi.json +62 -329
- package/shared/localization/locales/hr.json +63 -330
- package/shared/localization/locales/hu.json +62 -329
- package/shared/localization/locales/id.json +62 -329
- package/shared/localization/locales/it.json +62 -329
- package/shared/localization/locales/ja.json +62 -329
- package/shared/localization/locales/ko.json +62 -329
- package/shared/localization/locales/lt.json +62 -329
- package/shared/localization/locales/lv.json +62 -329
- package/shared/localization/locales/nl.json +62 -329
- package/shared/localization/locales/no.json +62 -329
- package/shared/localization/locales/pl.json +61 -328
- package/shared/localization/locales/pt-PT.json +62 -329
- package/shared/localization/locales/pt.json +64 -331
- package/shared/localization/locales/ro.json +62 -329
- package/shared/localization/locales/ru.json +62 -329
- package/shared/localization/locales/sk.json +62 -329
- package/shared/localization/locales/sl.json +62 -329
- package/shared/localization/locales/sr-Latn.json +62 -329
- package/shared/localization/locales/sr.json +62 -329
- package/shared/localization/locales/sv.json +62 -329
- package/shared/localization/locales/ta.json +61 -328
- package/shared/localization/locales/te.json +62 -329
- package/shared/localization/locales/th.json +62 -329
- package/shared/localization/locales/tr.json +62 -329
- package/shared/localization/locales/uk.json +62 -329
- package/shared/localization/locales/vi.json +61 -328
- package/shared/localization/locales/zh-HK.json +62 -329
- package/shared/localization/locales/zh-TW.json +61 -328
- package/shared/localization/locales/zh.json +62 -329
- package/tsconfig.json +1 -3
- package/types/artifacts.d.ts +21 -110
- package/types/audit.d.ts +0 -10
- package/types/config.d.ts +0 -1
- package/types/externs.d.ts +0 -2
- package/types/gatherer.d.ts +3 -0
- package/types/internal/smokehouse.d.ts +1 -1
- package/types/lh.d.ts +0 -2
- package/types/lhr/audit-details.d.ts +9 -4
- package/types/lhr/lhr.d.ts +0 -4
- package/types/lhr/settings.d.ts +0 -4
- package/core/audits/accessibility/duplicate-id-active.js +0 -42
- package/core/audits/content-width.d.ts +0 -17
- package/core/audits/content-width.js +0 -76
- package/core/audits/installable-manifest.d.ts +0 -111
- package/core/audits/installable-manifest.js +0 -248
- package/core/audits/layout-shift-elements.d.ts +0 -16
- package/core/audits/layout-shift-elements.js +0 -101
- package/core/audits/manual/pwa-cross-browser.d.ts +0 -12
- package/core/audits/manual/pwa-cross-browser.js +0 -40
- package/core/audits/manual/pwa-each-page-has-url.d.ts +0 -12
- package/core/audits/manual/pwa-each-page-has-url.js +0 -38
- package/core/audits/manual/pwa-page-transitions.d.ts +0 -12
- package/core/audits/manual/pwa-page-transitions.js +0 -38
- package/core/audits/maskable-icon.d.ts +0 -25
- package/core/audits/maskable-icon.js +0 -70
- package/core/audits/multi-check-audit.d.ts +0 -28
- package/core/audits/multi-check-audit.js +0 -82
- package/core/audits/no-unload-listeners.d.ts +0 -16
- package/core/audits/no-unload-listeners.js +0 -86
- package/core/audits/performance-budget.d.ts +0 -39
- package/core/audits/performance-budget.js +0 -154
- package/core/audits/script-elements-test-audit.d.ts +0 -14
- package/core/audits/script-elements-test-audit.js +0 -29
- package/core/audits/seo/plugins.d.ts +0 -15
- package/core/audits/seo/plugins.js +0 -150
- package/core/audits/seo/tap-targets.d.ts +0 -50
- package/core/audits/seo/tap-targets.js +0 -352
- package/core/audits/splash-screen.d.ts +0 -37
- package/core/audits/splash-screen.js +0 -98
- package/core/audits/themed-omnibox.d.ts +0 -42
- package/core/audits/themed-omnibox.js +0 -102
- package/core/audits/timing-budget.d.ts +0 -43
- package/core/audits/timing-budget.js +0 -175
- package/core/computed/manifest-values.d.ts +0 -24
- package/core/computed/manifest-values.js +0 -136
- package/core/config/budget.d.ts +0 -74
- package/core/config/budget.js +0 -340
- package/core/config/metrics-to-audits.d.ts +0 -19
- package/core/config/metrics-to-audits.js +0 -62
- package/core/gather/driver/service-workers.d.ts +0 -16
- package/core/gather/driver/service-workers.js +0 -52
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +0 -47
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +0 -233
- package/core/gather/gatherers/global-listeners.d.ts +0 -27
- package/core/gather/gatherers/global-listeners.js +0 -108
- package/core/gather/gatherers/installability-errors.d.ts +0 -17
- package/core/gather/gatherers/installability-errors.js +0 -56
- package/core/gather/gatherers/script-elements.d.ts +0 -21
- package/core/gather/gatherers/script-elements.js +0 -100
- package/core/gather/gatherers/seo/embedded-content.d.ts +0 -10
- package/core/gather/gatherers/seo/embedded-content.js +0 -63
- package/core/gather/gatherers/seo/tap-targets.d.ts +0 -21
- package/core/gather/gatherers/seo/tap-targets.js +0 -389
- package/core/gather/gatherers/service-worker.d.ts +0 -10
- package/core/gather/gatherers/service-worker.js +0 -32
- package/core/gather/gatherers/web-app-manifest.d.ts +0 -32
- package/core/gather/gatherers/web-app-manifest.js +0 -106
- package/report/renderer/pwa-category-renderer.d.ts +0 -55
- package/report/renderer/pwa-category-renderer.js +0 -184
- package/third-party/chromium-synchronization/installability-errors-test.js +0 -79
- package/types/lhr/budget.d.ts +0 -60
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2018 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/* global document, window, getComputedStyle, getElementsInDocument, Node, getNodeDetails, getRectCenterPoint */
|
|
8
|
-
|
|
9
|
-
import BaseGatherer from '../../base-gatherer.js';
|
|
10
|
-
import {pageFunctions} from '../../../lib/page-functions.js';
|
|
11
|
-
import * as RectHelpers from '../../../lib/rect-helpers.js';
|
|
12
|
-
|
|
13
|
-
const TARGET_SELECTORS = [
|
|
14
|
-
'button',
|
|
15
|
-
'a',
|
|
16
|
-
'input',
|
|
17
|
-
'textarea',
|
|
18
|
-
'select',
|
|
19
|
-
'option',
|
|
20
|
-
'[role=button]',
|
|
21
|
-
'[role=checkbox]',
|
|
22
|
-
'[role=link]',
|
|
23
|
-
'[role=menuitem]',
|
|
24
|
-
'[role=menuitemcheckbox]',
|
|
25
|
-
'[role=menuitemradio]',
|
|
26
|
-
'[role=option]',
|
|
27
|
-
'[role=scrollbar]',
|
|
28
|
-
'[role=slider]',
|
|
29
|
-
'[role=spinbutton]',
|
|
30
|
-
];
|
|
31
|
-
const tapTargetsSelector = TARGET_SELECTORS.join(',');
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @param {HTMLElement} element
|
|
35
|
-
* @return {boolean}
|
|
36
|
-
*/
|
|
37
|
-
/* c8 ignore start */
|
|
38
|
-
function elementIsVisible(element) {
|
|
39
|
-
return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
|
|
40
|
-
}
|
|
41
|
-
/* c8 ignore stop */
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @param {Element} element
|
|
45
|
-
* @return {LH.Artifacts.Rect[]}
|
|
46
|
-
*/
|
|
47
|
-
/* c8 ignore start */
|
|
48
|
-
function getClientRects(element) {
|
|
49
|
-
const clientRects = Array.from(
|
|
50
|
-
element.getClientRects()
|
|
51
|
-
).map(clientRect => {
|
|
52
|
-
// Contents of DOMRect get lost when returned from Runtime.evaluate call,
|
|
53
|
-
// so we convert them to plain objects.
|
|
54
|
-
const {width, height, left, top, right, bottom} = clientRect;
|
|
55
|
-
return {width, height, left, top, right, bottom};
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
for (const child of element.children) {
|
|
59
|
-
clientRects.push(...getClientRects(child));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return clientRects;
|
|
63
|
-
}
|
|
64
|
-
/* c8 ignore stop */
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @param {Element} element
|
|
68
|
-
* @param {string} tapTargetsSelector
|
|
69
|
-
* @return {boolean}
|
|
70
|
-
*/
|
|
71
|
-
/* c8 ignore start */
|
|
72
|
-
function elementHasAncestorTapTarget(element, tapTargetsSelector) {
|
|
73
|
-
if (!element.parentElement) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
if (element.parentElement.matches(tapTargetsSelector)) {
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
return elementHasAncestorTapTarget(element.parentElement, tapTargetsSelector);
|
|
80
|
-
}
|
|
81
|
-
/* c8 ignore stop */
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @param {Element} element
|
|
85
|
-
*/
|
|
86
|
-
/* c8 ignore start */
|
|
87
|
-
function hasTextNodeSiblingsFormingTextBlock(element) {
|
|
88
|
-
if (!element.parentElement) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const parentElement = element.parentElement;
|
|
93
|
-
|
|
94
|
-
const nodeText = element.textContent || '';
|
|
95
|
-
const parentText = parentElement.textContent || '';
|
|
96
|
-
if (parentText.length - nodeText.length < 5) {
|
|
97
|
-
// Parent text mostly consists of this node, so the parent
|
|
98
|
-
// is not a text block container
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
for (const sibling of element.parentElement.childNodes) {
|
|
103
|
-
if (sibling === element) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
const siblingTextContent = (sibling.textContent || '').trim();
|
|
107
|
-
// Only count text in text nodes so that a series of e.g. buttons isn't counted
|
|
108
|
-
// as a text block.
|
|
109
|
-
// This works reasonably well, but means we miss text blocks where all text is e.g.
|
|
110
|
-
// wrapped in spans
|
|
111
|
-
if (sibling.nodeType === Node.TEXT_NODE && siblingTextContent.length > 0) {
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
/* c8 ignore stop */
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Check if element is in a block of text, such as paragraph with a bunch of links in it.
|
|
122
|
-
* Makes a reasonable guess, but for example gets it wrong if the element is surrounded by other
|
|
123
|
-
* HTML elements instead of direct text nodes.
|
|
124
|
-
* @param {Element} element
|
|
125
|
-
* @return {boolean}
|
|
126
|
-
*/
|
|
127
|
-
/* c8 ignore start */
|
|
128
|
-
function elementIsInTextBlock(element) {
|
|
129
|
-
const {display} = getComputedStyle(element);
|
|
130
|
-
if (display !== 'inline' && display !== 'inline-block') {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (hasTextNodeSiblingsFormingTextBlock(element)) {
|
|
135
|
-
return true;
|
|
136
|
-
} else if (element.parentElement) {
|
|
137
|
-
return elementIsInTextBlock(element.parentElement);
|
|
138
|
-
} else {
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
/* c8 ignore stop */
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* @param {Element} el
|
|
146
|
-
* @param {{x: number, y: number}} elCenterPoint
|
|
147
|
-
*/
|
|
148
|
-
/* c8 ignore start */
|
|
149
|
-
function elementCenterIsAtZAxisTop(el, elCenterPoint) {
|
|
150
|
-
const viewportHeight = window.innerHeight;
|
|
151
|
-
const targetScrollY = Math.floor(elCenterPoint.y / viewportHeight) * viewportHeight;
|
|
152
|
-
if (window.scrollY !== targetScrollY) {
|
|
153
|
-
window.scrollTo(0, targetScrollY);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const topEl = document.elementFromPoint(
|
|
157
|
-
elCenterPoint.x,
|
|
158
|
-
elCenterPoint.y - window.scrollY
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
return topEl === el || el.contains(topEl);
|
|
162
|
-
}
|
|
163
|
-
/* c8 ignore stop */
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Finds all position sticky/absolute elements on the page and adds a class
|
|
167
|
-
* that disables pointer events on them.
|
|
168
|
-
* @param {string} className
|
|
169
|
-
* @return {() => void} - undo function to re-enable pointer events
|
|
170
|
-
*/
|
|
171
|
-
/* c8 ignore start */
|
|
172
|
-
function disableFixedAndStickyElementPointerEvents(className) {
|
|
173
|
-
document.querySelectorAll('*').forEach(el => {
|
|
174
|
-
const position = getComputedStyle(el).position;
|
|
175
|
-
if (position === 'fixed' || position === 'sticky') {
|
|
176
|
-
el.classList.add(className);
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
return function undo() {
|
|
181
|
-
Array.from(document.getElementsByClassName(className)).forEach(el => {
|
|
182
|
-
el.classList.remove(className);
|
|
183
|
-
});
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
/* c8 ignore stop */
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* @param {string} tapTargetsSelector
|
|
190
|
-
* @param {string} className
|
|
191
|
-
* @return {LH.Artifacts.TapTarget[]}
|
|
192
|
-
*/
|
|
193
|
-
/* c8 ignore start */
|
|
194
|
-
function gatherTapTargets(tapTargetsSelector, className) {
|
|
195
|
-
/** @type {LH.Artifacts.TapTarget[]} */
|
|
196
|
-
const targets = [];
|
|
197
|
-
|
|
198
|
-
// Capture element positions relative to the top of the page
|
|
199
|
-
window.scrollTo(0, 0);
|
|
200
|
-
|
|
201
|
-
/** @type {HTMLElement[]} */
|
|
202
|
-
// @ts-expect-error - getElementsInDocument put into scope via stringification
|
|
203
|
-
const tapTargetElements = getElementsInDocument(tapTargetsSelector);
|
|
204
|
-
|
|
205
|
-
/** @type {{
|
|
206
|
-
tapTargetElement: Element,
|
|
207
|
-
clientRects: LH.Artifacts.Rect[]
|
|
208
|
-
}[]} */
|
|
209
|
-
const tapTargetsWithClientRects = [];
|
|
210
|
-
tapTargetElements.forEach(tapTargetElement => {
|
|
211
|
-
// Filter out tap targets that are likely to cause false failures:
|
|
212
|
-
if (elementHasAncestorTapTarget(tapTargetElement, tapTargetsSelector)) {
|
|
213
|
-
// This is usually intentional, either the tap targets trigger the same action
|
|
214
|
-
// or there's a child with a related action (like a delete button for an item)
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
if (elementIsInTextBlock(tapTargetElement)) {
|
|
218
|
-
// Links inside text blocks cause a lot of failures, and there's also an exception for them
|
|
219
|
-
// in the Web Content Accessibility Guidelines https://www.w3.org/TR/WCAG21/#target-size
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
if (!elementIsVisible(tapTargetElement)) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
tapTargetsWithClientRects.push({
|
|
227
|
-
tapTargetElement,
|
|
228
|
-
clientRects: getClientRects(tapTargetElement),
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// Disable pointer events so that tap targets below them don't get
|
|
233
|
-
// detected as non-tappable (they are tappable, just not while the viewport
|
|
234
|
-
// is at the current scroll position)
|
|
235
|
-
const reenableFixedAndStickyElementPointerEvents =
|
|
236
|
-
disableFixedAndStickyElementPointerEvents(className);
|
|
237
|
-
|
|
238
|
-
/** @type {{
|
|
239
|
-
tapTargetElement: Element,
|
|
240
|
-
visibleClientRects: LH.Artifacts.Rect[]
|
|
241
|
-
}[]} */
|
|
242
|
-
const tapTargetsWithVisibleClientRects = [];
|
|
243
|
-
// We use separate loop here to get visible client rects because that involves
|
|
244
|
-
// scrolling around the page for elementCenterIsAtZAxisTop, which would affect the
|
|
245
|
-
// client rect positions.
|
|
246
|
-
tapTargetsWithClientRects.forEach(({tapTargetElement, clientRects}) => {
|
|
247
|
-
// Filter out empty client rects
|
|
248
|
-
let visibleClientRects = clientRects.filter(cr => cr.width !== 0 && cr.height !== 0);
|
|
249
|
-
|
|
250
|
-
// Filter out client rects that are invisible, e.g because they are in a position absolute element
|
|
251
|
-
// with a lower z-index than the main content.
|
|
252
|
-
// This will also filter out all position fixed or sticky tap targets elements because we disable pointer
|
|
253
|
-
// events on them before running this. That's the correct behavior because whether a position fixed/stick
|
|
254
|
-
// element overlaps with another tap target depends on the scroll position.
|
|
255
|
-
visibleClientRects = visibleClientRects.filter(rect => {
|
|
256
|
-
// Just checking the center can cause false failures for large partially hidden tap targets,
|
|
257
|
-
// but that should be a rare edge case
|
|
258
|
-
// @ts-expect-error - put into scope via stringification
|
|
259
|
-
const rectCenterPoint = getRectCenterPoint(rect);
|
|
260
|
-
return elementCenterIsAtZAxisTop(tapTargetElement, rectCenterPoint);
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
if (visibleClientRects.length > 0) {
|
|
264
|
-
tapTargetsWithVisibleClientRects.push({
|
|
265
|
-
tapTargetElement,
|
|
266
|
-
visibleClientRects,
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
for (const {tapTargetElement, visibleClientRects} of tapTargetsWithVisibleClientRects) {
|
|
272
|
-
targets.push({
|
|
273
|
-
clientRects: visibleClientRects,
|
|
274
|
-
href: /** @type {HTMLAnchorElement} */(tapTargetElement)['href'] || '',
|
|
275
|
-
// @ts-expect-error - getNodeDetails put into scope via stringification
|
|
276
|
-
node: getNodeDetails(tapTargetElement),
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
reenableFixedAndStickyElementPointerEvents();
|
|
281
|
-
|
|
282
|
-
return targets;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* @param {string} tapTargetsSelector
|
|
287
|
-
* @param {string} className
|
|
288
|
-
* @return {LH.Artifacts.TapTarget[]}
|
|
289
|
-
*/
|
|
290
|
-
function gatherTapTargetsAndResetScroll(tapTargetsSelector, className) {
|
|
291
|
-
const originalScrollPosition = {
|
|
292
|
-
x: window.scrollX,
|
|
293
|
-
y: window.scrollY,
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
try {
|
|
297
|
-
return gatherTapTargets(tapTargetsSelector, className);
|
|
298
|
-
} finally {
|
|
299
|
-
window.scrollTo(originalScrollPosition.x, originalScrollPosition.y);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
/* c8 ignore stop */
|
|
303
|
-
|
|
304
|
-
class TapTargets extends BaseGatherer {
|
|
305
|
-
constructor() {
|
|
306
|
-
super();
|
|
307
|
-
/**
|
|
308
|
-
* This needs to be in the constructor.
|
|
309
|
-
* https://github.com/GoogleChrome/lighthouse/issues/12134
|
|
310
|
-
* @type {LH.Gatherer.GathererMeta}
|
|
311
|
-
*/
|
|
312
|
-
this.meta = {
|
|
313
|
-
supportedModes: ['snapshot', 'navigation'],
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
319
|
-
* @param {string} className
|
|
320
|
-
* @return {Promise<string>}
|
|
321
|
-
*/
|
|
322
|
-
async addStyleRule(session, className) {
|
|
323
|
-
const frameTreeResponse = await session.sendCommand('Page.getFrameTree');
|
|
324
|
-
const {styleSheetId} = await session.sendCommand('CSS.createStyleSheet', {
|
|
325
|
-
frameId: frameTreeResponse.frameTree.frame.id,
|
|
326
|
-
});
|
|
327
|
-
const ruleText = `.${className} { pointer-events: none !important }`;
|
|
328
|
-
await session.sendCommand('CSS.setStyleSheetText', {
|
|
329
|
-
styleSheetId,
|
|
330
|
-
text: ruleText,
|
|
331
|
-
});
|
|
332
|
-
return styleSheetId;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
337
|
-
* @param {string} styleSheetId
|
|
338
|
-
*/
|
|
339
|
-
async removeStyleRule(session, styleSheetId) {
|
|
340
|
-
await session.sendCommand('CSS.setStyleSheetText', {
|
|
341
|
-
styleSheetId,
|
|
342
|
-
text: '',
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* @param {LH.Gatherer.Context} passContext
|
|
348
|
-
* @return {Promise<LH.Artifacts.TapTarget[]>} All visible tap targets with their positions and sizes
|
|
349
|
-
*/
|
|
350
|
-
async getArtifact(passContext) {
|
|
351
|
-
const session = passContext.driver.defaultSession;
|
|
352
|
-
await session.sendCommand('DOM.enable');
|
|
353
|
-
await session.sendCommand('CSS.enable');
|
|
354
|
-
|
|
355
|
-
const className = 'lighthouse-disable-pointer-events';
|
|
356
|
-
const styleSheetId = await this.addStyleRule(session, className);
|
|
357
|
-
|
|
358
|
-
const tapTargets =
|
|
359
|
-
await passContext.driver.executionContext.evaluate(gatherTapTargetsAndResetScroll, {
|
|
360
|
-
args: [tapTargetsSelector, className],
|
|
361
|
-
useIsolation: true,
|
|
362
|
-
deps: [
|
|
363
|
-
pageFunctions.getNodeDetails,
|
|
364
|
-
pageFunctions.getElementsInDocument,
|
|
365
|
-
disableFixedAndStickyElementPointerEvents,
|
|
366
|
-
elementIsVisible,
|
|
367
|
-
elementHasAncestorTapTarget,
|
|
368
|
-
elementCenterIsAtZAxisTop,
|
|
369
|
-
getClientRects,
|
|
370
|
-
hasTextNodeSiblingsFormingTextBlock,
|
|
371
|
-
elementIsInTextBlock,
|
|
372
|
-
RectHelpers.getRectCenterPoint,
|
|
373
|
-
pageFunctions.getNodePath,
|
|
374
|
-
pageFunctions.getNodeSelector,
|
|
375
|
-
pageFunctions.getNodeLabel,
|
|
376
|
-
gatherTapTargets,
|
|
377
|
-
],
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
await this.removeStyleRule(session, styleSheetId);
|
|
381
|
-
|
|
382
|
-
await session.sendCommand('CSS.disable');
|
|
383
|
-
await session.sendCommand('DOM.disable');
|
|
384
|
-
|
|
385
|
-
return tapTargets;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
export default TapTargets;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export default ServiceWorker;
|
|
2
|
-
declare class ServiceWorker extends BaseGatherer {
|
|
3
|
-
/**
|
|
4
|
-
* @param {LH.Gatherer.Context} context
|
|
5
|
-
* @return {Promise<LH.Artifacts['ServiceWorker']>}
|
|
6
|
-
*/
|
|
7
|
-
getArtifact(context: LH.Gatherer.Context): Promise<LH.Artifacts['ServiceWorker']>;
|
|
8
|
-
}
|
|
9
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
10
|
-
//# sourceMappingURL=service-worker.d.ts.map
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2016 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
8
|
-
import * as serviceWorkers from '../driver/service-workers.js';
|
|
9
|
-
|
|
10
|
-
class ServiceWorker extends BaseGatherer {
|
|
11
|
-
/** @type {LH.Gatherer.GathererMeta} */
|
|
12
|
-
meta = {
|
|
13
|
-
supportedModes: ['navigation'],
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @param {LH.Gatherer.Context} context
|
|
18
|
-
* @return {Promise<LH.Artifacts['ServiceWorker']>}
|
|
19
|
-
*/
|
|
20
|
-
async getArtifact(context) {
|
|
21
|
-
const session = context.driver.defaultSession;
|
|
22
|
-
const {versions} = await serviceWorkers.getServiceWorkerVersions(session);
|
|
23
|
-
const {registrations} = await serviceWorkers.getServiceWorkerRegistrations(session);
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
versions,
|
|
27
|
-
registrations,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export default ServiceWorker;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export default WebAppManifest;
|
|
2
|
-
declare class WebAppManifest extends BaseGatherer {
|
|
3
|
-
/**
|
|
4
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
5
|
-
* @return {Promise<{url: string, data: string}|null>}
|
|
6
|
-
*/
|
|
7
|
-
static fetchAppManifest(session: LH.Gatherer.ProtocolSession): Promise<{
|
|
8
|
-
url: string;
|
|
9
|
-
data: string;
|
|
10
|
-
} | null>;
|
|
11
|
-
/**
|
|
12
|
-
* Uses the debugger protocol to fetch the manifest from within the context of
|
|
13
|
-
* the target page, reusing any credentials, emulation, etc, already established
|
|
14
|
-
* there.
|
|
15
|
-
*
|
|
16
|
-
* Returns the parsed manifest or null if the page had no manifest. If the manifest
|
|
17
|
-
* was unparseable as JSON, manifest.value will be undefined and manifest.warning
|
|
18
|
-
* will have the reason. See manifest-parser.js for more information.
|
|
19
|
-
*
|
|
20
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
21
|
-
* @param {string} pageUrl
|
|
22
|
-
* @return {Promise<LH.Artifacts.Manifest|null>}
|
|
23
|
-
*/
|
|
24
|
-
static getWebAppManifest(session: LH.Gatherer.ProtocolSession, pageUrl: string): Promise<LH.Artifacts.Manifest | null>;
|
|
25
|
-
/**
|
|
26
|
-
* @param {LH.Gatherer.Context} context
|
|
27
|
-
* @return {Promise<LH.Artifacts['WebAppManifest']>}
|
|
28
|
-
*/
|
|
29
|
-
getArtifact(context: LH.Gatherer.Context): Promise<LH.Artifacts['WebAppManifest']>;
|
|
30
|
-
}
|
|
31
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
32
|
-
//# sourceMappingURL=web-app-manifest.d.ts.map
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2021 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import log from 'lighthouse-logger';
|
|
8
|
-
|
|
9
|
-
import {parseManifest} from '../../lib/manifest-parser.js';
|
|
10
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
11
|
-
|
|
12
|
-
class WebAppManifest extends BaseGatherer {
|
|
13
|
-
/** @type {LH.Gatherer.GathererMeta} */
|
|
14
|
-
meta = {
|
|
15
|
-
supportedModes: ['snapshot', 'navigation'],
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
20
|
-
* @return {Promise<{url: string, data: string}|null>}
|
|
21
|
-
*/
|
|
22
|
-
static async fetchAppManifest(session) {
|
|
23
|
-
// In all environments but LR, Page.getAppManifest finishes very quickly.
|
|
24
|
-
// In LR, there is a bug that causes this command to hang until outgoing
|
|
25
|
-
// requests finish. This has been seen in long polling (where it will never
|
|
26
|
-
// return) and when other requests take a long time to finish. We allow 10 seconds
|
|
27
|
-
// for outgoing requests to finish. Anything more, and we continue the run without
|
|
28
|
-
// a manifest.
|
|
29
|
-
// Googlers, see: http://b/124008171
|
|
30
|
-
session.setNextProtocolTimeout(10000);
|
|
31
|
-
let response;
|
|
32
|
-
try {
|
|
33
|
-
response = await session.sendCommand('Page.getAppManifest');
|
|
34
|
-
} catch (err) {
|
|
35
|
-
if (err.code === 'PROTOCOL_TIMEOUT') {
|
|
36
|
-
// LR will timeout fetching the app manifest in some cases, move on without one.
|
|
37
|
-
// https://github.com/GoogleChrome/lighthouse/issues/7147#issuecomment-461210921
|
|
38
|
-
log.error('WebAppManifest', 'Failed fetching manifest', err);
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
throw err;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
let data = response.data;
|
|
46
|
-
|
|
47
|
-
// We're not reading `response.errors` however it may contain critical and noncritical
|
|
48
|
-
// errors from Blink's manifest parser:
|
|
49
|
-
// https://chromedevtools.github.io/debugger-protocol-viewer/tot/Page/#type-AppManifestError
|
|
50
|
-
if (!data) {
|
|
51
|
-
// If the data is empty, the page had no manifest.
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const BOM_LENGTH = 3;
|
|
56
|
-
const BOM_FIRSTCHAR = 65279;
|
|
57
|
-
const isBomEncoded = data.charCodeAt(0) === BOM_FIRSTCHAR;
|
|
58
|
-
|
|
59
|
-
if (isBomEncoded) {
|
|
60
|
-
data = Buffer.from(data)
|
|
61
|
-
.slice(BOM_LENGTH)
|
|
62
|
-
.toString();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return {...response, data};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Uses the debugger protocol to fetch the manifest from within the context of
|
|
70
|
-
* the target page, reusing any credentials, emulation, etc, already established
|
|
71
|
-
* there.
|
|
72
|
-
*
|
|
73
|
-
* Returns the parsed manifest or null if the page had no manifest. If the manifest
|
|
74
|
-
* was unparseable as JSON, manifest.value will be undefined and manifest.warning
|
|
75
|
-
* will have the reason. See manifest-parser.js for more information.
|
|
76
|
-
*
|
|
77
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
78
|
-
* @param {string} pageUrl
|
|
79
|
-
* @return {Promise<LH.Artifacts.Manifest|null>}
|
|
80
|
-
*/
|
|
81
|
-
static async getWebAppManifest(session, pageUrl) {
|
|
82
|
-
const status = {msg: 'Get webapp manifest', id: 'lh:gather:getWebAppManifest'};
|
|
83
|
-
log.time(status);
|
|
84
|
-
const response = await WebAppManifest.fetchAppManifest(session);
|
|
85
|
-
if (!response) return null;
|
|
86
|
-
const manifest = parseManifest(response.data, response.url, pageUrl);
|
|
87
|
-
log.timeEnd(status);
|
|
88
|
-
return manifest;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @param {LH.Gatherer.Context} context
|
|
93
|
-
* @return {Promise<LH.Artifacts['WebAppManifest']>}
|
|
94
|
-
*/
|
|
95
|
-
async getArtifact(context) {
|
|
96
|
-
const driver = context.driver;
|
|
97
|
-
const {finalDisplayedUrl} = context.baseArtifacts.URL;
|
|
98
|
-
try {
|
|
99
|
-
return await WebAppManifest.getWebAppManifest(driver.defaultSession, finalDisplayedUrl);
|
|
100
|
-
} catch {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export default WebAppManifest;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
export class PwaCategoryRenderer extends CategoryRenderer {
|
|
2
|
-
/**
|
|
3
|
-
* Alters SVG id references so multiple instances of an SVG element can coexist
|
|
4
|
-
* in a single page. If `svgRoot` has a `<defs>` block, gives all elements defined
|
|
5
|
-
* in it unique ids, then updates id references (`<use xlink:href="...">`,
|
|
6
|
-
* `fill="url(#...)"`) to the altered ids in all descendents of `svgRoot`.
|
|
7
|
-
* @param {SVGElement} svgRoot
|
|
8
|
-
*/
|
|
9
|
-
static _makeSvgReferencesUnique(svgRoot: SVGElement): void;
|
|
10
|
-
/**
|
|
11
|
-
* @param {LH.ReportResult.Category} category
|
|
12
|
-
* @param {Object<string, LH.Result.ReportGroup>} [groupDefinitions]
|
|
13
|
-
* @return {Element}
|
|
14
|
-
*/
|
|
15
|
-
render(category: LH.ReportResult.Category, groupDefinitions?: {
|
|
16
|
-
[x: string]: import("../../types/lhr/lhr.js").default.ReportGroup;
|
|
17
|
-
} | undefined): Element;
|
|
18
|
-
/**
|
|
19
|
-
* @param {LH.ReportResult.Category} category
|
|
20
|
-
* @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
|
|
21
|
-
* @return {DocumentFragment}
|
|
22
|
-
*/
|
|
23
|
-
renderCategoryScore(category: LH.ReportResult.Category, groupDefinitions: Record<string, LH.Result.ReportGroup>): DocumentFragment;
|
|
24
|
-
/**
|
|
25
|
-
* Returns the group IDs found in auditRefs.
|
|
26
|
-
* @param {Array<LH.ReportResult.AuditRef>} auditRefs
|
|
27
|
-
* @return {!Set<string>}
|
|
28
|
-
*/
|
|
29
|
-
_getGroupIds(auditRefs: Array<LH.ReportResult.AuditRef>): Set<string>;
|
|
30
|
-
/**
|
|
31
|
-
* Returns the group IDs whose audits are all considered passing.
|
|
32
|
-
* @param {Array<LH.ReportResult.AuditRef>} auditRefs
|
|
33
|
-
* @return {Set<string>}
|
|
34
|
-
*/
|
|
35
|
-
_getPassingGroupIds(auditRefs: Array<LH.ReportResult.AuditRef>): Set<string>;
|
|
36
|
-
/**
|
|
37
|
-
* Returns a tooltip string summarizing group pass rates.
|
|
38
|
-
* @param {Array<LH.ReportResult.AuditRef>} auditRefs
|
|
39
|
-
* @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
|
|
40
|
-
* @return {string}
|
|
41
|
-
*/
|
|
42
|
-
_getGaugeTooltip(auditRefs: Array<LH.ReportResult.AuditRef>, groupDefinitions: Record<string, LH.Result.ReportGroup>): string;
|
|
43
|
-
/**
|
|
44
|
-
* Render non-manual audits in groups, giving a badge to any group that has
|
|
45
|
-
* all passing audits.
|
|
46
|
-
* @param {Array<LH.ReportResult.AuditRef>} auditRefs
|
|
47
|
-
* @param {Object<string, LH.Result.ReportGroup>} groupDefinitions
|
|
48
|
-
* @return {Element}
|
|
49
|
-
*/
|
|
50
|
-
_renderAudits(auditRefs: Array<LH.ReportResult.AuditRef>, groupDefinitions: {
|
|
51
|
-
[x: string]: LH.Result.ReportGroup;
|
|
52
|
-
}): Element;
|
|
53
|
-
}
|
|
54
|
-
import { CategoryRenderer } from './category-renderer.js';
|
|
55
|
-
//# sourceMappingURL=pwa-category-renderer.d.ts.map
|