forked from GoogleChrome/lighthouse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
script-elements.js
100 lines (87 loc) · 2.8 KB
/
script-elements.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import BaseGatherer from '../base-gatherer.js';
import {NetworkRecords} from '../../computed/network-records.js';
import {NetworkRequest} from '../../lib/network-request.js';
import {pageFunctions} from '../../lib/page-functions.js';
import DevtoolsLog from './devtools-log.js';
/* global getNodeDetails */
/**
* @return {LH.Artifacts['ScriptElements']}
*/
/* c8 ignore start */
function collectAllScriptElements() {
/** @type {HTMLScriptElement[]} */
// @ts-expect-error - getElementsInDocument put into scope via stringification
const scripts = getElementsInDocument('script'); // eslint-disable-line no-undef
return scripts.map(script => {
return {
type: script.type || null,
src: script.src || null,
id: script.id || null,
async: script.async,
defer: script.defer,
source: script.closest('head') ? 'head' : 'body',
// @ts-expect-error - getNodeDetails put into scope via stringification
node: getNodeDetails(script),
};
});
}
/* c8 ignore stop */
/**
* @fileoverview Gets JavaScript file contents.
*/
class ScriptElements extends BaseGatherer {
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */
meta = {
supportedModes: ['timespan', 'navigation'],
dependencies: {DevtoolsLog: DevtoolsLog.symbol},
};
/**
* @param {LH.Gatherer.Context} context
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
* @return {Promise<LH.Artifacts['ScriptElements']>}
*/
async _getArtifact(context, networkRecords) {
const executionContext = context.driver.executionContext;
const scripts = await executionContext.evaluate(collectAllScriptElements, {
args: [],
useIsolation: true,
deps: [
pageFunctions.getNodeDetails,
pageFunctions.getElementsInDocument,
],
});
const scriptRecords = networkRecords
.filter(record => record.resourceType === NetworkRequest.TYPES.Script)
.filter(record => record.sessionTargetType === 'page');
for (let i = 0; i < scriptRecords.length; i++) {
const record = scriptRecords[i];
const matchedScriptElement = scripts.find(script => script.src === record.url);
if (!matchedScriptElement) {
scripts.push({
type: null,
src: record.url,
id: null,
async: false,
defer: false,
source: 'network',
node: null,
});
}
}
return scripts;
}
/**
* @param {LH.Gatherer.Context<'DevtoolsLog'>} context
*/
async getArtifact(context) {
const devtoolsLog = context.dependencies.DevtoolsLog;
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
return this._getArtifact(context, networkRecords);
}
}
export default ScriptElements;