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,233 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2016 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* @fileoverview
|
|
8
|
-
* Identifies stylesheets, HTML Imports, and scripts that potentially block
|
|
9
|
-
* the first paint of the page by running several scripts in the page context.
|
|
10
|
-
* Candidate blocking tags are collected by querying for all script tags in
|
|
11
|
-
* the head of the page and all link tags that are either matching media
|
|
12
|
-
* stylesheets or non-async HTML imports. These are then compared to the
|
|
13
|
-
* network requests to ensure they were initiated by the parser and not
|
|
14
|
-
* injected with script. To avoid false positives from strategies like
|
|
15
|
-
* (http://filamentgroup.github.io/loadCSS/test/preload.html), a separate
|
|
16
|
-
* script is run to flag all links that at one point were rel=preload.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import {NetworkRecords} from '../../../computed/network-records.js';
|
|
21
|
-
import DevtoolsLog from '../devtools-log.js';
|
|
22
|
-
import BaseGatherer from '../../base-gatherer.js';
|
|
23
|
-
|
|
24
|
-
/* global document, window, HTMLLinkElement, SVGScriptElement */
|
|
25
|
-
|
|
26
|
-
/** @typedef {{href: string, media: string, msSinceHTMLEnd: number, matches: boolean}} MediaChange */
|
|
27
|
-
/** @typedef {{tagName: 'LINK', url: string, href: string, rel: string, media: string, disabled: boolean, mediaChanges: Array<MediaChange>}} LinkTag */
|
|
28
|
-
/** @typedef {{tagName: 'SCRIPT', url: string, src: string}} ScriptTag */
|
|
29
|
-
|
|
30
|
-
/* c8 ignore start */
|
|
31
|
-
function installMediaListener() {
|
|
32
|
-
// @ts-expect-error - inserted in page to track media changes.
|
|
33
|
-
window.___linkMediaChanges = [];
|
|
34
|
-
Object.defineProperty(HTMLLinkElement.prototype, 'media', {
|
|
35
|
-
set: function(val) {
|
|
36
|
-
/** @type {MediaChange} */
|
|
37
|
-
const mediaChange = {
|
|
38
|
-
href: this.href,
|
|
39
|
-
media: val,
|
|
40
|
-
msSinceHTMLEnd: Date.now() - performance.timing.responseEnd,
|
|
41
|
-
matches: window.matchMedia(val).matches,
|
|
42
|
-
};
|
|
43
|
-
// @ts-expect-error - `___linkMediaChanges` created above.
|
|
44
|
-
window.___linkMediaChanges.push(mediaChange);
|
|
45
|
-
|
|
46
|
-
this.setAttribute('media', val);
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
/* c8 ignore stop */
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* @return {Promise<Array<LinkTag | ScriptTag>>}
|
|
54
|
-
*/
|
|
55
|
-
/* c8 ignore start */
|
|
56
|
-
async function collectTagsThatBlockFirstPaint() {
|
|
57
|
-
/** @type {Array<MediaChange>} */
|
|
58
|
-
// @ts-expect-error - `___linkMediaChanges` created in `installMediaListener`.
|
|
59
|
-
const linkMediaChanges = window.___linkMediaChanges;
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
/** @type {Array<LinkTag>} */
|
|
63
|
-
const linkTags = [...document.querySelectorAll('link')]
|
|
64
|
-
.filter(linkTag => {
|
|
65
|
-
// Ignore malformed links with no href (e.g. `<link rel="stylesheet" href="">`)
|
|
66
|
-
// The resolved `linkTag.href` will be the main document, but the main document
|
|
67
|
-
// should never be render blocking.
|
|
68
|
-
if (!linkTag.getAttribute('href')) return false;
|
|
69
|
-
|
|
70
|
-
// Filter stylesheet/HTML imports that block rendering.
|
|
71
|
-
// https://www.igvita.com/2012/06/14/debunking-responsive-css-performance-myths/
|
|
72
|
-
// https://www.w3.org/TR/html-imports/#dfn-import-async-attribute
|
|
73
|
-
const blockingStylesheet = linkTag.rel === 'stylesheet' &&
|
|
74
|
-
window.matchMedia(linkTag.media).matches && !linkTag.disabled;
|
|
75
|
-
const blockingImport = linkTag.rel === 'import' && !linkTag.hasAttribute('async');
|
|
76
|
-
return blockingStylesheet || blockingImport;
|
|
77
|
-
})
|
|
78
|
-
.map(tag => {
|
|
79
|
-
return {
|
|
80
|
-
tagName: 'LINK',
|
|
81
|
-
url: tag.href,
|
|
82
|
-
href: tag.href,
|
|
83
|
-
rel: tag.rel,
|
|
84
|
-
media: tag.media,
|
|
85
|
-
disabled: tag.disabled,
|
|
86
|
-
mediaChanges: linkMediaChanges.filter(item => item.href === tag.href),
|
|
87
|
-
};
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
/** @type {Array<ScriptTag>} */
|
|
91
|
-
const scriptTags = [...document.querySelectorAll('head script[src]')]
|
|
92
|
-
.filter(/** @return {scriptTag is HTMLScriptElement} */ scriptTag => {
|
|
93
|
-
// SVGScriptElement can't appear in <head> (it'll be kicked to <body>), but keep tsc happy.
|
|
94
|
-
// https://html.spec.whatwg.org/multipage/semantics.html#the-head-element
|
|
95
|
-
if (scriptTag instanceof SVGScriptElement) return false;
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
!scriptTag.hasAttribute('async') &&
|
|
99
|
-
!scriptTag.hasAttribute('defer') &&
|
|
100
|
-
!/^data:/.test(scriptTag.src) &&
|
|
101
|
-
!/^blob:/.test(scriptTag.src) &&
|
|
102
|
-
scriptTag.getAttribute('type') !== 'module'
|
|
103
|
-
);
|
|
104
|
-
})
|
|
105
|
-
.map(tag => {
|
|
106
|
-
return {
|
|
107
|
-
tagName: 'SCRIPT',
|
|
108
|
-
url: tag.src,
|
|
109
|
-
src: tag.src,
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
return [...linkTags, ...scriptTags];
|
|
114
|
-
} catch (e) {
|
|
115
|
-
const friendly = 'Unable to gather Scripts/Stylesheets/HTML Imports on the page';
|
|
116
|
-
throw new Error(`${friendly}: ${e.message}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
/* c8 ignore stop */
|
|
120
|
-
|
|
121
|
-
class TagsBlockingFirstPaint extends BaseGatherer {
|
|
122
|
-
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */
|
|
123
|
-
meta = {
|
|
124
|
-
supportedModes: ['navigation'],
|
|
125
|
-
dependencies: {DevtoolsLog: DevtoolsLog.symbol},
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
130
|
-
* @return {Map<string, LH.Artifacts.NetworkRequest>}
|
|
131
|
-
*/
|
|
132
|
-
static _filteredAndIndexedByUrl(networkRecords) {
|
|
133
|
-
/** @type {Map<string, LH.Artifacts.NetworkRequest>} */
|
|
134
|
-
const result = new Map();
|
|
135
|
-
|
|
136
|
-
for (const record of networkRecords) {
|
|
137
|
-
if (!record.finished) continue;
|
|
138
|
-
|
|
139
|
-
const isParserGenerated = record.initiator.type === 'parser';
|
|
140
|
-
// A stylesheet only blocks script if it was initiated by the parser
|
|
141
|
-
// https://html.spec.whatwg.org/multipage/semantics.html#interactions-of-styling-and-scripting
|
|
142
|
-
const isParserScriptOrStyle = /(css|script)/.test(record.mimeType) && isParserGenerated;
|
|
143
|
-
const isFailedRequest = record.failed;
|
|
144
|
-
const isHtml = record.mimeType && record.mimeType.includes('html');
|
|
145
|
-
|
|
146
|
-
// Filter stylesheet, javascript, and html import mimetypes.
|
|
147
|
-
// Include 404 scripts/links generated by the parser because they are likely blocking.
|
|
148
|
-
if (isHtml || isParserScriptOrStyle || (isFailedRequest && isParserGenerated)) {
|
|
149
|
-
result.set(record.url, record);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return result;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* @param {LH.Gatherer.Driver} driver
|
|
158
|
-
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
159
|
-
* @return {Promise<Array<LH.Artifacts.TagBlockingFirstPaint>>}
|
|
160
|
-
*/
|
|
161
|
-
static async findBlockingTags(driver, networkRecords) {
|
|
162
|
-
const firstRequestEndTime = networkRecords.reduce(
|
|
163
|
-
(min, record) => Math.min(min, record.networkEndTime),
|
|
164
|
-
Infinity
|
|
165
|
-
);
|
|
166
|
-
const tags = await driver.executionContext.evaluate(collectTagsThatBlockFirstPaint, {args: []});
|
|
167
|
-
const requests = TagsBlockingFirstPaint._filteredAndIndexedByUrl(networkRecords);
|
|
168
|
-
|
|
169
|
-
/** @type {Array<LH.Artifacts.TagBlockingFirstPaint>} */
|
|
170
|
-
const result = [];
|
|
171
|
-
for (const tag of tags) {
|
|
172
|
-
const request = requests.get(tag.url);
|
|
173
|
-
if (!request || request.isLinkPreload) continue;
|
|
174
|
-
|
|
175
|
-
let endTime = request.networkEndTime;
|
|
176
|
-
let mediaChanges;
|
|
177
|
-
|
|
178
|
-
if (tag.tagName === 'LINK') {
|
|
179
|
-
// Even if the request was initially blocking or appeared to be blocking once the
|
|
180
|
-
// page was loaded, the media attribute could have been changed during load, capping the
|
|
181
|
-
// amount of time it was render blocking. See https://github.com/GoogleChrome/lighthouse/issues/2832.
|
|
182
|
-
const timesResourceBecameNonBlocking = tag.mediaChanges
|
|
183
|
-
.filter(change => !change.matches)
|
|
184
|
-
.map(change => change.msSinceHTMLEnd);
|
|
185
|
-
if (timesResourceBecameNonBlocking.length > 0) {
|
|
186
|
-
const earliestNonBlockingTime = Math.min(...timesResourceBecameNonBlocking);
|
|
187
|
-
const lastTimeResourceWasBlocking = Math.max(
|
|
188
|
-
request.networkRequestTime,
|
|
189
|
-
firstRequestEndTime + earliestNonBlockingTime / 1000
|
|
190
|
-
);
|
|
191
|
-
endTime = Math.min(endTime, lastTimeResourceWasBlocking);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
mediaChanges = tag.mediaChanges;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const {tagName, url} = tag;
|
|
198
|
-
|
|
199
|
-
result.push({
|
|
200
|
-
tag: {tagName, url, mediaChanges},
|
|
201
|
-
transferSize: request.transferSize,
|
|
202
|
-
startTime: request.networkRequestTime,
|
|
203
|
-
endTime,
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
// Prevent duplicates from showing up again
|
|
207
|
-
requests.delete(tag.url);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return result;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* @param {LH.Gatherer.Context} context
|
|
215
|
-
*/
|
|
216
|
-
async startSensitiveInstrumentation(context) {
|
|
217
|
-
const {executionContext} = context.driver;
|
|
218
|
-
// Don't return return value of `evaluateOnNewDocument`.
|
|
219
|
-
await executionContext.evaluateOnNewDocument(installMediaListener, {args: []});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* @param {LH.Gatherer.Context<'DevtoolsLog'>} context
|
|
224
|
-
* @return {Promise<LH.Artifacts['TagsBlockingFirstPaint']>}
|
|
225
|
-
*/
|
|
226
|
-
async getArtifact(context) {
|
|
227
|
-
const devtoolsLog = context.dependencies.DevtoolsLog;
|
|
228
|
-
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
229
|
-
return TagsBlockingFirstPaint.findBlockingTags(context.driver, networkRecords);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export default TagsBlockingFirstPaint;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export default GlobalListeners;
|
|
2
|
-
declare class GlobalListeners extends BaseGatherer {
|
|
3
|
-
/**
|
|
4
|
-
* @param {LH.Crdp.DOMDebugger.EventListener} listener
|
|
5
|
-
* @return {listener is {type: 'pagehide'|'unload'|'visibilitychange'} & LH.Crdp.DOMDebugger.EventListener}
|
|
6
|
-
*/
|
|
7
|
-
static _filterForAllowlistedTypes(listener: LH.Crdp.DOMDebugger.EventListener): listener is {
|
|
8
|
-
type: 'pagehide' | 'unload' | 'visibilitychange';
|
|
9
|
-
} & import("devtools-protocol").Protocol.DOMDebugger.EventListener;
|
|
10
|
-
/**
|
|
11
|
-
* @param { LH.Artifacts.GlobalListener } listener
|
|
12
|
-
* @return { string }
|
|
13
|
-
*/
|
|
14
|
-
getListenerIndentifier(listener: LH.Artifacts.GlobalListener): string;
|
|
15
|
-
/**
|
|
16
|
-
* @param { LH.Artifacts['GlobalListeners'] } listeners
|
|
17
|
-
* @return { LH.Artifacts['GlobalListeners'] }
|
|
18
|
-
*/
|
|
19
|
-
dedupeListeners(listeners: LH.Artifacts['GlobalListeners']): LH.Artifacts['GlobalListeners'];
|
|
20
|
-
/**
|
|
21
|
-
* @param {LH.Gatherer.Context} passContext
|
|
22
|
-
* @return {Promise<LH.Artifacts['GlobalListeners']>}
|
|
23
|
-
*/
|
|
24
|
-
getArtifact(passContext: LH.Gatherer.Context): Promise<LH.Artifacts['GlobalListeners']>;
|
|
25
|
-
}
|
|
26
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
27
|
-
//# sourceMappingURL=global-listeners.d.ts.map
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2020 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @fileoverview
|
|
9
|
-
* A gatherer to collect information about the event listeners registered on the
|
|
10
|
-
* global object. For now, the scope is narrowed to events that occur on and
|
|
11
|
-
* around page unload, but this can be expanded in the future.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import log from 'lighthouse-logger';
|
|
15
|
-
|
|
16
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
17
|
-
|
|
18
|
-
class GlobalListeners extends BaseGatherer {
|
|
19
|
-
/** @type {LH.Gatherer.GathererMeta} */
|
|
20
|
-
meta = {
|
|
21
|
-
supportedModes: ['snapshot', 'timespan', 'navigation'],
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @param {LH.Crdp.DOMDebugger.EventListener} listener
|
|
26
|
-
* @return {listener is {type: 'pagehide'|'unload'|'visibilitychange'} & LH.Crdp.DOMDebugger.EventListener}
|
|
27
|
-
*/
|
|
28
|
-
static _filterForAllowlistedTypes(listener) {
|
|
29
|
-
return listener.type === 'pagehide' ||
|
|
30
|
-
listener.type === 'unload' ||
|
|
31
|
-
listener.type === 'visibilitychange';
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @param { LH.Artifacts.GlobalListener } listener
|
|
36
|
-
* @return { string }
|
|
37
|
-
*/
|
|
38
|
-
getListenerIndentifier(listener) {
|
|
39
|
-
return `${listener.type}:${listener.scriptId}:${listener.columnNumber}:${listener.lineNumber}`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @param { LH.Artifacts['GlobalListeners'] } listeners
|
|
44
|
-
* @return { LH.Artifacts['GlobalListeners'] }
|
|
45
|
-
*/
|
|
46
|
-
dedupeListeners(listeners) {
|
|
47
|
-
const seenListeners = new Set();
|
|
48
|
-
return listeners.filter(listener => {
|
|
49
|
-
const id = this.getListenerIndentifier(listener);
|
|
50
|
-
if (!seenListeners.has(id)) {
|
|
51
|
-
seenListeners.add(id);
|
|
52
|
-
return true;
|
|
53
|
-
} else {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @param {LH.Gatherer.Context} passContext
|
|
61
|
-
* @return {Promise<LH.Artifacts['GlobalListeners']>}
|
|
62
|
-
*/
|
|
63
|
-
async getArtifact(passContext) {
|
|
64
|
-
const session = passContext.driver.defaultSession;
|
|
65
|
-
|
|
66
|
-
/** @type {Array<LH.Artifacts.GlobalListener>} */
|
|
67
|
-
const listeners = [];
|
|
68
|
-
|
|
69
|
-
for (const executionContext of passContext.driver.targetManager.mainFrameExecutionContexts()) {
|
|
70
|
-
// Get a RemoteObject handle to `window`.
|
|
71
|
-
let objectId;
|
|
72
|
-
try {
|
|
73
|
-
const {result} = await session.sendCommand('Runtime.evaluate', {
|
|
74
|
-
expression: 'window',
|
|
75
|
-
returnByValue: false,
|
|
76
|
-
uniqueContextId: executionContext.uniqueId,
|
|
77
|
-
});
|
|
78
|
-
if (!result.objectId) {
|
|
79
|
-
throw new Error('Error fetching information about the global object');
|
|
80
|
-
}
|
|
81
|
-
objectId = result.objectId;
|
|
82
|
-
} catch (err) {
|
|
83
|
-
// Execution context is no longer valid, but don't let that fail the gatherer.
|
|
84
|
-
log.warn('Execution context is no longer valid', executionContext, err);
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// And get all its listeners of interest.
|
|
89
|
-
const response = await session.sendCommand('DOMDebugger.getEventListeners', {objectId});
|
|
90
|
-
for (const listener of response.listeners) {
|
|
91
|
-
if (GlobalListeners._filterForAllowlistedTypes(listener)) {
|
|
92
|
-
const {type, scriptId, lineNumber, columnNumber} = listener;
|
|
93
|
-
listeners.push({
|
|
94
|
-
type,
|
|
95
|
-
scriptId,
|
|
96
|
-
lineNumber,
|
|
97
|
-
columnNumber,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Dedupe listeners with same underlying data.
|
|
104
|
-
return this.dedupeListeners(listeners);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export default GlobalListeners;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export default InstallabilityErrors;
|
|
2
|
-
declare class InstallabilityErrors extends BaseGatherer {
|
|
3
|
-
/**
|
|
4
|
-
* Creates an Artifacts.InstallabilityErrors, tranforming data from the protocol
|
|
5
|
-
* for old versions of Chrome.
|
|
6
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
7
|
-
* @return {Promise<LH.Artifacts['InstallabilityErrors']>}
|
|
8
|
-
*/
|
|
9
|
-
static getInstallabilityErrors(session: LH.Gatherer.ProtocolSession): Promise<LH.Artifacts['InstallabilityErrors']>;
|
|
10
|
-
/**
|
|
11
|
-
* @param {LH.Gatherer.Context} context
|
|
12
|
-
* @return {Promise<LH.Artifacts['InstallabilityErrors']>}
|
|
13
|
-
*/
|
|
14
|
-
getArtifact(context: LH.Gatherer.Context): Promise<LH.Artifacts['InstallabilityErrors']>;
|
|
15
|
-
}
|
|
16
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
17
|
-
//# sourceMappingURL=installability-errors.d.ts.map
|
|
@@ -1,56 +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 BaseGatherer from '../base-gatherer.js';
|
|
10
|
-
|
|
11
|
-
class InstallabilityErrors extends BaseGatherer {
|
|
12
|
-
/** @type {LH.Gatherer.GathererMeta} */
|
|
13
|
-
meta = {
|
|
14
|
-
supportedModes: ['snapshot', 'navigation'],
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Creates an Artifacts.InstallabilityErrors, tranforming data from the protocol
|
|
19
|
-
* for old versions of Chrome.
|
|
20
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
21
|
-
* @return {Promise<LH.Artifacts['InstallabilityErrors']>}
|
|
22
|
-
*/
|
|
23
|
-
static async getInstallabilityErrors(session) {
|
|
24
|
-
const status = {
|
|
25
|
-
msg: 'Get webapp installability errors',
|
|
26
|
-
id: 'lh:gather:getInstallabilityErrors',
|
|
27
|
-
};
|
|
28
|
-
log.time(status);
|
|
29
|
-
const response = await session.sendCommand('Page.getInstallabilityErrors');
|
|
30
|
-
|
|
31
|
-
const errors = response.installabilityErrors;
|
|
32
|
-
|
|
33
|
-
log.timeEnd(status);
|
|
34
|
-
return {errors};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {LH.Gatherer.Context} context
|
|
39
|
-
* @return {Promise<LH.Artifacts['InstallabilityErrors']>}
|
|
40
|
-
*/
|
|
41
|
-
async getArtifact(context) {
|
|
42
|
-
const driver = context.driver;
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
return await InstallabilityErrors.getInstallabilityErrors(driver.defaultSession);
|
|
46
|
-
} catch {
|
|
47
|
-
return {
|
|
48
|
-
errors: [
|
|
49
|
-
{errorId: 'protocol-timeout', errorArguments: []},
|
|
50
|
-
],
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export default InstallabilityErrors;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export default ScriptElements;
|
|
2
|
-
/**
|
|
3
|
-
* @fileoverview Gets JavaScript file contents.
|
|
4
|
-
*/
|
|
5
|
-
declare class ScriptElements extends BaseGatherer {
|
|
6
|
-
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */
|
|
7
|
-
meta: LH.Gatherer.GathererMeta<'DevtoolsLog'>;
|
|
8
|
-
/**
|
|
9
|
-
* @param {LH.Gatherer.Context} context
|
|
10
|
-
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
11
|
-
* @return {Promise<LH.Artifacts['ScriptElements']>}
|
|
12
|
-
*/
|
|
13
|
-
_getArtifact(context: LH.Gatherer.Context, networkRecords: LH.Artifacts.NetworkRequest[]): Promise<LH.Artifacts['ScriptElements']>;
|
|
14
|
-
/**
|
|
15
|
-
* @param {LH.Gatherer.Context<'DevtoolsLog'>} context
|
|
16
|
-
*/
|
|
17
|
-
getArtifact(context: LH.Gatherer.Context<'DevtoolsLog'>): Promise<import("../../index.js").Artifacts.ScriptElement[]>;
|
|
18
|
-
}
|
|
19
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
20
|
-
import { NetworkRequest } from '../../lib/network-request.js';
|
|
21
|
-
//# sourceMappingURL=script-elements.d.ts.map
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2017 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
8
|
-
import {NetworkRecords} from '../../computed/network-records.js';
|
|
9
|
-
import {NetworkRequest} from '../../lib/network-request.js';
|
|
10
|
-
import {pageFunctions} from '../../lib/page-functions.js';
|
|
11
|
-
import DevtoolsLog from './devtools-log.js';
|
|
12
|
-
|
|
13
|
-
/* global getNodeDetails */
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @return {LH.Artifacts['ScriptElements']}
|
|
17
|
-
*/
|
|
18
|
-
/* c8 ignore start */
|
|
19
|
-
function collectAllScriptElements() {
|
|
20
|
-
/** @type {HTMLScriptElement[]} */
|
|
21
|
-
// @ts-expect-error - getElementsInDocument put into scope via stringification
|
|
22
|
-
const scripts = getElementsInDocument('script'); // eslint-disable-line no-undef
|
|
23
|
-
|
|
24
|
-
return scripts.map(script => {
|
|
25
|
-
return {
|
|
26
|
-
type: script.type || null,
|
|
27
|
-
src: script.src || null,
|
|
28
|
-
id: script.id || null,
|
|
29
|
-
async: script.async,
|
|
30
|
-
defer: script.defer,
|
|
31
|
-
source: script.closest('head') ? 'head' : 'body',
|
|
32
|
-
// @ts-expect-error - getNodeDetails put into scope via stringification
|
|
33
|
-
node: getNodeDetails(script),
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
/* c8 ignore stop */
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @fileoverview Gets JavaScript file contents.
|
|
41
|
-
*/
|
|
42
|
-
class ScriptElements extends BaseGatherer {
|
|
43
|
-
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */
|
|
44
|
-
meta = {
|
|
45
|
-
supportedModes: ['timespan', 'navigation'],
|
|
46
|
-
dependencies: {DevtoolsLog: DevtoolsLog.symbol},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @param {LH.Gatherer.Context} context
|
|
51
|
-
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
52
|
-
* @return {Promise<LH.Artifacts['ScriptElements']>}
|
|
53
|
-
*/
|
|
54
|
-
async _getArtifact(context, networkRecords) {
|
|
55
|
-
const executionContext = context.driver.executionContext;
|
|
56
|
-
|
|
57
|
-
const scripts = await executionContext.evaluate(collectAllScriptElements, {
|
|
58
|
-
args: [],
|
|
59
|
-
useIsolation: true,
|
|
60
|
-
deps: [
|
|
61
|
-
pageFunctions.getNodeDetails,
|
|
62
|
-
pageFunctions.getElementsInDocument,
|
|
63
|
-
],
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const scriptRecords = networkRecords
|
|
67
|
-
.filter(record => record.resourceType === NetworkRequest.TYPES.Script)
|
|
68
|
-
.filter(record => record.sessionTargetType === 'page');
|
|
69
|
-
|
|
70
|
-
for (let i = 0; i < scriptRecords.length; i++) {
|
|
71
|
-
const record = scriptRecords[i];
|
|
72
|
-
|
|
73
|
-
const matchedScriptElement = scripts.find(script => script.src === record.url);
|
|
74
|
-
if (!matchedScriptElement) {
|
|
75
|
-
scripts.push({
|
|
76
|
-
type: null,
|
|
77
|
-
src: record.url,
|
|
78
|
-
id: null,
|
|
79
|
-
async: false,
|
|
80
|
-
defer: false,
|
|
81
|
-
source: 'network',
|
|
82
|
-
node: null,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return scripts;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @param {LH.Gatherer.Context<'DevtoolsLog'>} context
|
|
92
|
-
*/
|
|
93
|
-
async getArtifact(context) {
|
|
94
|
-
const devtoolsLog = context.dependencies.DevtoolsLog;
|
|
95
|
-
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
96
|
-
return this._getArtifact(context, networkRecords);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export default ScriptElements;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export default EmbeddedContent;
|
|
2
|
-
declare class EmbeddedContent extends BaseGatherer {
|
|
3
|
-
/**
|
|
4
|
-
* @param {LH.Gatherer.Context} passContext
|
|
5
|
-
* @return {Promise<LH.Artifacts['EmbeddedContent']>}
|
|
6
|
-
*/
|
|
7
|
-
getArtifact(passContext: LH.Gatherer.Context): Promise<LH.Artifacts['EmbeddedContent']>;
|
|
8
|
-
}
|
|
9
|
-
import BaseGatherer from '../../base-gatherer.js';
|
|
10
|
-
//# sourceMappingURL=embedded-content.d.ts.map
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2018 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/* globals getElementsInDocument getNodeDetails */
|
|
8
|
-
|
|
9
|
-
import BaseGatherer from '../../base-gatherer.js';
|
|
10
|
-
import {pageFunctions} from '../../../lib/page-functions.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @return {LH.Artifacts.EmbeddedContentInfo[]}
|
|
14
|
-
*/
|
|
15
|
-
function getEmbeddedContent() {
|
|
16
|
-
const functions = /** @type {typeof pageFunctions} */ ({
|
|
17
|
-
// @ts-expect-error - getElementsInDocument put into scope via stringification
|
|
18
|
-
getElementsInDocument,
|
|
19
|
-
// @ts-expect-error - getNodeDetails put into scope via stringification
|
|
20
|
-
getNodeDetails,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const selector = 'object, embed, applet';
|
|
24
|
-
const elements = functions.getElementsInDocument(selector);
|
|
25
|
-
return elements
|
|
26
|
-
.map(node => ({
|
|
27
|
-
tagName: node.tagName,
|
|
28
|
-
type: node.getAttribute('type'),
|
|
29
|
-
src: node.getAttribute('src'),
|
|
30
|
-
data: node.getAttribute('data'),
|
|
31
|
-
code: node.getAttribute('code'),
|
|
32
|
-
params: Array.from(node.children)
|
|
33
|
-
.filter(el => el.tagName === 'PARAM')
|
|
34
|
-
.map(el => ({
|
|
35
|
-
name: el.getAttribute('name') || '',
|
|
36
|
-
value: el.getAttribute('value') || '',
|
|
37
|
-
})),
|
|
38
|
-
node: functions.getNodeDetails(node),
|
|
39
|
-
}));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
class EmbeddedContent extends BaseGatherer {
|
|
43
|
-
/** @type {LH.Gatherer.GathererMeta} */
|
|
44
|
-
meta = {
|
|
45
|
-
supportedModes: ['snapshot', 'navigation'],
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @param {LH.Gatherer.Context} passContext
|
|
50
|
-
* @return {Promise<LH.Artifacts['EmbeddedContent']>}
|
|
51
|
-
*/
|
|
52
|
-
getArtifact(passContext) {
|
|
53
|
-
return passContext.driver.executionContext.evaluate(getEmbeddedContent, {
|
|
54
|
-
args: [],
|
|
55
|
-
deps: [
|
|
56
|
-
pageFunctions.getElementsInDocument,
|
|
57
|
-
pageFunctions.getNodeDetails,
|
|
58
|
-
],
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export default EmbeddedContent;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export default TapTargets;
|
|
2
|
-
declare class TapTargets extends BaseGatherer {
|
|
3
|
-
/**
|
|
4
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
5
|
-
* @param {string} className
|
|
6
|
-
* @return {Promise<string>}
|
|
7
|
-
*/
|
|
8
|
-
addStyleRule(session: LH.Gatherer.ProtocolSession, className: string): Promise<string>;
|
|
9
|
-
/**
|
|
10
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
11
|
-
* @param {string} styleSheetId
|
|
12
|
-
*/
|
|
13
|
-
removeStyleRule(session: LH.Gatherer.ProtocolSession, styleSheetId: string): Promise<void>;
|
|
14
|
-
/**
|
|
15
|
-
* @param {LH.Gatherer.Context} passContext
|
|
16
|
-
* @return {Promise<LH.Artifacts.TapTarget[]>} All visible tap targets with their positions and sizes
|
|
17
|
-
*/
|
|
18
|
-
getArtifact(passContext: LH.Gatherer.Context): Promise<LH.Artifacts.TapTarget[]>;
|
|
19
|
-
}
|
|
20
|
-
import BaseGatherer from '../../base-gatherer.js';
|
|
21
|
-
//# sourceMappingURL=tap-targets.d.ts.map
|