lighthouse 11.4.0 → 11.5.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/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +14 -4
- package/cli/test/smokehouse/core-tests.js +2 -0
- package/core/audits/audit.d.ts +5 -0
- package/core/audits/audit.js +46 -2
- package/core/audits/bf-cache.js +1 -1
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +1 -1
- package/core/audits/byte-efficiency/legacy-javascript.js +13 -2
- package/core/audits/byte-efficiency/render-blocking-resources.d.ts +5 -4
- package/core/audits/byte-efficiency/render-blocking-resources.js +15 -9
- package/core/audits/byte-efficiency/unused-css-rules.js +1 -1
- package/core/audits/byte-efficiency/unused-javascript.js +1 -1
- package/core/audits/layout-shift-elements.js +1 -1
- package/core/audits/layout-shifts.d.ts +33 -0
- package/core/audits/layout-shifts.js +158 -0
- package/core/audits/prioritize-lcp-image.js +1 -1
- package/core/audits/unsized-images.js +1 -1
- package/core/audits/viewport.js +10 -0
- package/core/computed/metrics/cumulative-layout-shift.d.ts +20 -1
- package/core/computed/metrics/cumulative-layout-shift.js +74 -4
- package/core/computed/trace-engine-result.d.ts +40 -0
- package/core/computed/trace-engine-result.js +69 -0
- package/core/computed/unused-css.js +4 -4
- package/core/computed/viewport-meta.d.ts +4 -0
- package/core/computed/viewport-meta.js +6 -1
- package/core/config/default-config.js +4 -1
- package/core/config/metrics-to-audits.js +1 -0
- package/core/gather/driver/target-manager.js +10 -1
- package/core/gather/driver/wait-for-condition.js +1 -1
- package/core/gather/gatherers/dobetterweb/response-compression.js +1 -12
- package/core/gather/gatherers/root-causes.d.ts +20 -0
- package/core/gather/gatherers/root-causes.js +133 -0
- package/core/gather/gatherers/trace-elements.d.ts +38 -7
- package/core/gather/gatherers/trace-elements.js +113 -34
- package/core/gather/gatherers/trace.js +6 -3
- package/core/gather/navigation-runner.js +1 -1
- package/core/gather/session.js +16 -3
- package/core/lib/i18n/i18n.js +2 -0
- package/core/lib/lighthouse-compatibility.js +4 -0
- package/core/lib/network-request.js +10 -2
- package/core/lib/polyfill-dom-rect.d.ts +2 -0
- package/core/lib/polyfill-dom-rect.js +111 -0
- package/core/lib/trace-engine.d.ts +7 -0
- package/core/lib/trace-engine.js +19 -0
- package/core/scripts/download-chrome.sh +17 -0
- package/dist/report/bundle.esm.js +14 -10
- package/dist/report/flow.js +15 -11
- package/dist/report/standalone.js +13 -9
- package/flow-report/src/i18n/i18n.d.ts +2 -0
- package/package.json +5 -4
- package/report/assets/styles.css +9 -5
- package/report/renderer/category-renderer.d.ts +5 -12
- package/report/renderer/category-renderer.js +18 -18
- package/report/renderer/components.js +1 -1
- package/report/renderer/performance-category-renderer.d.ts +2 -1
- package/report/renderer/performance-category-renderer.js +90 -69
- package/report/renderer/pwa-category-renderer.js +11 -2
- package/report/renderer/report-utils.d.ts +1 -0
- package/report/renderer/report-utils.js +3 -0
- package/shared/localization/locales/en-US.json +27 -0
- package/shared/localization/locales/en-XL.json +27 -0
- package/types/artifacts.d.ts +10 -1
- package/types/audit.d.ts +9 -1
- package/types/config.d.ts +1 -0
- package/types/lhr/audit-result.d.ts +1 -7
- package/types/trace-engine.d.ts +1516 -0
|
@@ -23,10 +23,13 @@ import {LighthouseError} from '../../lib/lh-error.js';
|
|
|
23
23
|
import {Responsiveness} from '../../computed/metrics/responsiveness.js';
|
|
24
24
|
import {CumulativeLayoutShift} from '../../computed/metrics/cumulative-layout-shift.js';
|
|
25
25
|
import {ExecutionContext} from '../driver/execution-context.js';
|
|
26
|
+
import RootCauses from './root-causes.js';
|
|
27
|
+
import {TraceEngineResult} from '../../computed/trace-engine-result.js';
|
|
26
28
|
|
|
27
29
|
/** @typedef {{nodeId: number, animations?: {name?: string, failureReasonsMask?: number, unsupportedProperties?: string[]}[], type?: string}} TraceElementData */
|
|
28
30
|
|
|
29
31
|
const MAX_LAYOUT_SHIFT_ELEMENTS = 15;
|
|
32
|
+
const MAX_LAYOUT_SHIFTS = 15;
|
|
30
33
|
|
|
31
34
|
/**
|
|
32
35
|
* @this {HTMLElement}
|
|
@@ -44,10 +47,10 @@ function getNodeDetailsData() {
|
|
|
44
47
|
/* c8 ignore stop */
|
|
45
48
|
|
|
46
49
|
class TraceElements extends BaseGatherer {
|
|
47
|
-
/** @type {LH.Gatherer.GathererMeta<'Trace'>} */
|
|
50
|
+
/** @type {LH.Gatherer.GathererMeta<'Trace'|'RootCauses'>} */
|
|
48
51
|
meta = {
|
|
49
52
|
supportedModes: ['timespan', 'navigation'],
|
|
50
|
-
dependencies: {Trace: Trace.symbol},
|
|
53
|
+
dependencies: {Trace: Trace.symbol, RootCauses: RootCauses.symbol},
|
|
51
54
|
};
|
|
52
55
|
|
|
53
56
|
/** @type {Map<string, string>} */
|
|
@@ -64,11 +67,11 @@ class TraceElements extends BaseGatherer {
|
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
/**
|
|
67
|
-
* This function finds the top (up to 15) elements that
|
|
70
|
+
* This function finds the top (up to 15) elements that shift on the page.
|
|
68
71
|
*
|
|
69
72
|
* @param {LH.Trace} trace
|
|
70
73
|
* @param {LH.Gatherer.Context} context
|
|
71
|
-
* @return {Promise<Array<
|
|
74
|
+
* @return {Promise<Array<{nodeId: number}>>}
|
|
72
75
|
*/
|
|
73
76
|
static async getTopLayoutShiftElements(trace, context) {
|
|
74
77
|
const {impactByNodeId} = await CumulativeLayoutShift.request(trace, context);
|
|
@@ -79,6 +82,66 @@ class TraceElements extends BaseGatherer {
|
|
|
79
82
|
.map(([nodeId]) => ({nodeId}));
|
|
80
83
|
}
|
|
81
84
|
|
|
85
|
+
/**
|
|
86
|
+
* We want to a single representative node to represent the shift, so let's pick
|
|
87
|
+
* the one with the largest impact (size x distance moved).
|
|
88
|
+
*
|
|
89
|
+
* @param {LH.Artifacts.TraceImpactedNode[]} impactedNodes
|
|
90
|
+
* @param {Map<number, number>} impactByNodeId
|
|
91
|
+
* @return {number|undefined}
|
|
92
|
+
*/
|
|
93
|
+
static getBiggestImpactNodeForShiftEvent(impactedNodes, impactByNodeId) {
|
|
94
|
+
let biggestImpactNodeId;
|
|
95
|
+
let biggestImpactNodeScore = Number.NEGATIVE_INFINITY;
|
|
96
|
+
for (const node of impactedNodes) {
|
|
97
|
+
const impactScore = impactByNodeId.get(node.node_id);
|
|
98
|
+
if (impactScore !== undefined && impactScore > biggestImpactNodeScore) {
|
|
99
|
+
biggestImpactNodeId = node.node_id;
|
|
100
|
+
biggestImpactNodeScore = impactScore;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return biggestImpactNodeId;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* This function finds the top (up to 15) layout shifts on the page, and returns
|
|
108
|
+
* the id of the largest impacted node of each shift, along with any related nodes
|
|
109
|
+
* that may have caused the shift.
|
|
110
|
+
*
|
|
111
|
+
* @param {LH.Trace} trace
|
|
112
|
+
* @param {LH.Artifacts.TraceEngineResult} traceEngineResult
|
|
113
|
+
* @param {LH.Artifacts.TraceEngineRootCauses} rootCauses
|
|
114
|
+
* @param {LH.Gatherer.Context} context
|
|
115
|
+
* @return {Promise<Array<{nodeId: number}>>}
|
|
116
|
+
*/
|
|
117
|
+
static async getTopLayoutShifts(trace, traceEngineResult, rootCauses, context) {
|
|
118
|
+
const {impactByNodeId} = await CumulativeLayoutShift.request(trace, context);
|
|
119
|
+
const clusters = traceEngineResult.LayoutShifts.clusters ?? [];
|
|
120
|
+
const layoutShiftEvents = clusters.flatMap(c => c.events);
|
|
121
|
+
|
|
122
|
+
return layoutShiftEvents
|
|
123
|
+
.sort((a, b) => b.args.data.weighted_score_delta - a.args.data.weighted_score_delta)
|
|
124
|
+
.slice(0, MAX_LAYOUT_SHIFTS)
|
|
125
|
+
.flatMap(event => {
|
|
126
|
+
const nodeIds = [];
|
|
127
|
+
const biggestImpactedNodeId =
|
|
128
|
+
this.getBiggestImpactNodeForShiftEvent(event.args.data.impacted_nodes, impactByNodeId);
|
|
129
|
+
if (biggestImpactedNodeId !== undefined) {
|
|
130
|
+
nodeIds.push(biggestImpactedNodeId);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const index = layoutShiftEvents.indexOf(event);
|
|
134
|
+
const shiftRootCauses = rootCauses.layoutShifts[index];
|
|
135
|
+
if (shiftRootCauses) {
|
|
136
|
+
for (const cause of shiftRootCauses.unsizedMedia) {
|
|
137
|
+
nodeIds.push(cause.node.backendNodeId);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return nodeIds.map(nodeId => ({nodeId}));
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
82
145
|
/**
|
|
83
146
|
* @param {LH.Trace} trace
|
|
84
147
|
* @param {LH.Gatherer.Context} context
|
|
@@ -195,61 +258,77 @@ class TraceElements extends BaseGatherer {
|
|
|
195
258
|
}
|
|
196
259
|
|
|
197
260
|
/**
|
|
198
|
-
* @param {LH.Gatherer.
|
|
261
|
+
* @param {LH.Gatherer.ProtocolSession} session
|
|
262
|
+
* @param {number} backendNodeId
|
|
263
|
+
*/
|
|
264
|
+
async getNodeDetails(session, backendNodeId) {
|
|
265
|
+
try {
|
|
266
|
+
const objectId = await resolveNodeIdToObjectId(session, backendNodeId);
|
|
267
|
+
if (!objectId) return null;
|
|
268
|
+
|
|
269
|
+
const deps = ExecutionContext.serializeDeps([
|
|
270
|
+
pageFunctions.getNodeDetails,
|
|
271
|
+
getNodeDetailsData,
|
|
272
|
+
]);
|
|
273
|
+
return await session.sendCommand('Runtime.callFunctionOn', {
|
|
274
|
+
objectId,
|
|
275
|
+
functionDeclaration: `function () {
|
|
276
|
+
${deps}
|
|
277
|
+
return getNodeDetailsData.call(this);
|
|
278
|
+
}`,
|
|
279
|
+
returnByValue: true,
|
|
280
|
+
awaitPromise: true,
|
|
281
|
+
});
|
|
282
|
+
} catch (err) {
|
|
283
|
+
Sentry.captureException(err, {
|
|
284
|
+
tags: {gatherer: 'TraceElements'},
|
|
285
|
+
level: 'error',
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @param {LH.Gatherer.Context<'Trace'|'RootCauses'>} context
|
|
199
294
|
* @return {Promise<LH.Artifacts.TraceElement[]>}
|
|
200
295
|
*/
|
|
201
296
|
async getArtifact(context) {
|
|
202
297
|
const session = context.driver.defaultSession;
|
|
203
298
|
|
|
204
299
|
const trace = context.dependencies.Trace;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
300
|
+
const traceEngineResult = await TraceEngineResult.request({trace}, context);
|
|
301
|
+
const rootCauses = context.dependencies.RootCauses;
|
|
208
302
|
|
|
209
303
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
210
304
|
const {mainThreadEvents} = processedTrace;
|
|
211
305
|
|
|
212
306
|
const lcpNodeData = await TraceElements.getLcpElement(trace, context);
|
|
213
|
-
const
|
|
307
|
+
const shiftElementsNodeData = await TraceElements.getTopLayoutShiftElements(trace, context);
|
|
308
|
+
const shiftsData = await TraceElements.getTopLayoutShifts(
|
|
309
|
+
trace, traceEngineResult, rootCauses, context);
|
|
214
310
|
const animatedElementData = await this.getAnimatedElements(mainThreadEvents);
|
|
215
311
|
const responsivenessElementData = await TraceElements.getResponsivenessElement(trace, context);
|
|
216
312
|
|
|
217
313
|
/** @type {Map<string, TraceElementData[]>} */
|
|
218
314
|
const backendNodeDataMap = new Map([
|
|
219
315
|
['largest-contentful-paint', lcpNodeData ? [lcpNodeData] : []],
|
|
220
|
-
['layout-shift',
|
|
316
|
+
['layout-shift-element', shiftElementsNodeData],
|
|
317
|
+
['layout-shift', shiftsData],
|
|
221
318
|
['animation', animatedElementData],
|
|
222
319
|
['responsiveness', responsivenessElementData ? [responsivenessElementData] : []],
|
|
223
320
|
]);
|
|
224
321
|
|
|
322
|
+
/** @type {Map<number, LH.Crdp.Runtime.CallFunctionOnResponse | null>} */
|
|
323
|
+
const callFunctionOnCache = new Map();
|
|
225
324
|
const traceElements = [];
|
|
226
325
|
for (const [traceEventType, backendNodeData] of backendNodeDataMap) {
|
|
227
326
|
for (let i = 0; i < backendNodeData.length; i++) {
|
|
228
327
|
const backendNodeId = backendNodeData[i].nodeId;
|
|
229
|
-
let response;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const deps = ExecutionContext.serializeDeps([
|
|
235
|
-
pageFunctions.getNodeDetails,
|
|
236
|
-
getNodeDetailsData,
|
|
237
|
-
]);
|
|
238
|
-
response = await session.sendCommand('Runtime.callFunctionOn', {
|
|
239
|
-
objectId,
|
|
240
|
-
functionDeclaration: `function () {
|
|
241
|
-
${deps}
|
|
242
|
-
return getNodeDetailsData.call(this);
|
|
243
|
-
}`,
|
|
244
|
-
returnByValue: true,
|
|
245
|
-
awaitPromise: true,
|
|
246
|
-
});
|
|
247
|
-
} catch (err) {
|
|
248
|
-
Sentry.captureException(err, {
|
|
249
|
-
tags: {gatherer: 'TraceElements'},
|
|
250
|
-
level: 'error',
|
|
251
|
-
});
|
|
252
|
-
continue;
|
|
328
|
+
let response = callFunctionOnCache.get(backendNodeId);
|
|
329
|
+
if (response === undefined) {
|
|
330
|
+
response = await this.getNodeDetails(session, backendNodeId);
|
|
331
|
+
callFunctionOnCache.set(backendNodeId, response);
|
|
253
332
|
}
|
|
254
333
|
|
|
255
334
|
if (response?.result?.value) {
|
|
@@ -56,9 +56,12 @@ class Trace extends BaseGatherer {
|
|
|
56
56
|
'disabled-by-default-devtools.timeline.frame',
|
|
57
57
|
'latencyInfo',
|
|
58
58
|
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
// For CLS root causes.
|
|
60
|
+
'disabled-by-default-devtools.timeline.invalidationTracking',
|
|
61
|
+
|
|
62
|
+
// Not used by Lighthouse (yet) but included for users that want JS samples when looking at
|
|
63
|
+
// a trace collected by Lighthouse (e.g. "View Trace" workflow in DevTools)
|
|
64
|
+
'disabled-by-default-v8.cpu_profiler',
|
|
62
65
|
];
|
|
63
66
|
}
|
|
64
67
|
|
package/core/gather/session.js
CHANGED
|
@@ -10,6 +10,17 @@ import {LighthouseError} from '../lib/lh-error.js';
|
|
|
10
10
|
|
|
11
11
|
// Controls how long to wait for a response after sending a DevTools protocol command.
|
|
12
12
|
const DEFAULT_PROTOCOL_TIMEOUT = 30000;
|
|
13
|
+
const PPTR_BUFFER = 50;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Puppeteer timeouts must fit into an int32 and the maximum timeout for `setTimeout` is a *signed*
|
|
17
|
+
* int32. However, this also needs to account for the puppeteer buffer we add to the timeout later.
|
|
18
|
+
*
|
|
19
|
+
* So this is defined as the max *signed* int32 minus PPTR_BUFFER.
|
|
20
|
+
*
|
|
21
|
+
* In human terms, this timeout is ~25 days which is as good as infinity for all practical purposes.
|
|
22
|
+
*/
|
|
23
|
+
const MAX_TIMEOUT = 2147483647 - PPTR_BUFFER;
|
|
13
24
|
|
|
14
25
|
/** @typedef {LH.Protocol.StrictEventEmitterClass<LH.CrdpEvents>} CrdpEventMessageEmitter */
|
|
15
26
|
const CrdpEventEmitter = /** @type {CrdpEventMessageEmitter} */ (EventEmitter);
|
|
@@ -70,6 +81,7 @@ class ProtocolSession extends CrdpEventEmitter {
|
|
|
70
81
|
* @param {number} ms
|
|
71
82
|
*/
|
|
72
83
|
setNextProtocolTimeout(ms) {
|
|
84
|
+
if (ms > MAX_TIMEOUT) ms = MAX_TIMEOUT;
|
|
73
85
|
this._nextProtocolTimeout = ms;
|
|
74
86
|
}
|
|
75
87
|
|
|
@@ -86,15 +98,16 @@ class ProtocolSession extends CrdpEventEmitter {
|
|
|
86
98
|
/** @type {NodeJS.Timer|undefined} */
|
|
87
99
|
let timeout;
|
|
88
100
|
const timeoutPromise = new Promise((resolve, reject) => {
|
|
89
|
-
if (timeoutMs === Infinity) return;
|
|
90
|
-
|
|
91
101
|
// eslint-disable-next-line max-len
|
|
92
102
|
timeout = setTimeout(reject, timeoutMs, new LighthouseError(LighthouseError.errors.PROTOCOL_TIMEOUT, {
|
|
93
103
|
protocolMethod: method,
|
|
94
104
|
}));
|
|
95
105
|
});
|
|
96
106
|
|
|
97
|
-
const resultPromise = this._cdpSession.send(method, ...params
|
|
107
|
+
const resultPromise = this._cdpSession.send(method, ...params, {
|
|
108
|
+
// Add 50ms to the Puppeteer timeout to ensure the Lighthouse timeout finishes first.
|
|
109
|
+
timeout: timeoutMs + PPTR_BUFFER,
|
|
110
|
+
});
|
|
98
111
|
const resultWithTimeoutPromise = Promise.race([resultPromise, timeoutPromise]);
|
|
99
112
|
|
|
100
113
|
return resultWithTimeoutPromise.finally(() => {
|
package/core/lib/i18n/i18n.js
CHANGED
|
@@ -17,6 +17,7 @@ import {LH_ROOT} from '../../../shared/root.js';
|
|
|
17
17
|
import {isIcuMessage, formatMessage, DEFAULT_LOCALE} from '../../../shared/localization/format.js';
|
|
18
18
|
import {getModulePath} from '../../../shared/esm-utils.js';
|
|
19
19
|
|
|
20
|
+
/* eslint-disable max-len */
|
|
20
21
|
const UIStrings = {
|
|
21
22
|
/** Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms) */
|
|
22
23
|
ms: '{timeInMs, number, milliseconds}\xa0ms',
|
|
@@ -113,6 +114,7 @@ const UIStrings = {
|
|
|
113
114
|
/** Table item value for the severity of a high impact, or dangerous vulnerability. Part of a ranking scale in the form: low, medium, high. */
|
|
114
115
|
itemSeverityHigh: 'High',
|
|
115
116
|
};
|
|
117
|
+
/* eslint-enable max-len */
|
|
116
118
|
|
|
117
119
|
/**
|
|
118
120
|
* Look up the best available locale for the requested language through these fall backs:
|
|
@@ -36,6 +36,10 @@ function upgradeLhrForCompatibility(lhr) {
|
|
|
36
36
|
audit.scoreDisplayMode = 'notApplicable';
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
if (audit.scoreDisplayMode === 'informative') {
|
|
40
|
+
audit.score = 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
if (audit.details) {
|
|
40
44
|
// Turn `auditDetails.type` of undefined (LHR <4.2) and 'diagnostic' (LHR <5.0)
|
|
41
45
|
// into 'debugdata' (LHR ≥5.0).
|
|
@@ -616,8 +616,16 @@ class NetworkRequest {
|
|
|
616
616
|
static isContentEncoded(record) {
|
|
617
617
|
// FYI: older devtools logs (like our test fixtures) seems to be lower case, while modern logs
|
|
618
618
|
// are Cased-Like-This.
|
|
619
|
-
const
|
|
620
|
-
|
|
619
|
+
const patterns = global.isLightrider ? [
|
|
620
|
+
/^x-original-content-encoding$/i,
|
|
621
|
+
] : [
|
|
622
|
+
/^content-encoding$/i,
|
|
623
|
+
/^x-content-encoding-over-network$/i,
|
|
624
|
+
];
|
|
625
|
+
const compressionTypes = ['gzip', 'br', 'deflate'];
|
|
626
|
+
return record.responseHeaders.some(header =>
|
|
627
|
+
patterns.some(p => header.name.match(p)) && compressionTypes.includes(header.value)
|
|
628
|
+
);
|
|
621
629
|
}
|
|
622
630
|
|
|
623
631
|
/**
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
function polyfillDOMRect() {
|
|
5
|
+
// devtools assumes clientside :(
|
|
6
|
+
|
|
7
|
+
// Everything else in here is the DOMRect polyfill
|
|
8
|
+
// https://raw.githubusercontent.com/JakeChampion/polyfill-library/master/polyfills/DOMRect/polyfill.js
|
|
9
|
+
|
|
10
|
+
(function (global) {
|
|
11
|
+
function number(v) {
|
|
12
|
+
return v === undefined ? 0 : Number(v);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function different(u, v) {
|
|
16
|
+
return u !== v && !(isNaN(u) && isNaN(v));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function DOMRect(xArg, yArg, wArg, hArg) {
|
|
20
|
+
let x, y, width, height, left, right, top, bottom;
|
|
21
|
+
|
|
22
|
+
x = number(xArg);
|
|
23
|
+
y = number(yArg);
|
|
24
|
+
width = number(wArg);
|
|
25
|
+
height = number(hArg);
|
|
26
|
+
|
|
27
|
+
Object.defineProperties(this, {
|
|
28
|
+
x: {
|
|
29
|
+
get: function () { return x; },
|
|
30
|
+
set: function (newX) {
|
|
31
|
+
if (different(x, newX)) {
|
|
32
|
+
x = newX;
|
|
33
|
+
left = right = undefined;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
enumerable: true
|
|
37
|
+
},
|
|
38
|
+
y: {
|
|
39
|
+
get: function () { return y; },
|
|
40
|
+
set: function (newY) {
|
|
41
|
+
if (different(y, newY)) {
|
|
42
|
+
y = newY;
|
|
43
|
+
top = bottom = undefined;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
enumerable: true
|
|
47
|
+
},
|
|
48
|
+
width: {
|
|
49
|
+
get: function () { return width; },
|
|
50
|
+
set: function (newWidth) {
|
|
51
|
+
if (different(width, newWidth)) {
|
|
52
|
+
width = newWidth;
|
|
53
|
+
left = right = undefined;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
enumerable: true
|
|
57
|
+
},
|
|
58
|
+
height: {
|
|
59
|
+
get: function () { return height; },
|
|
60
|
+
set: function (newHeight) {
|
|
61
|
+
if (different(height, newHeight)) {
|
|
62
|
+
height = newHeight;
|
|
63
|
+
top = bottom = undefined;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
enumerable: true
|
|
67
|
+
},
|
|
68
|
+
left: {
|
|
69
|
+
get: function () {
|
|
70
|
+
if (left === undefined) {
|
|
71
|
+
left = x + Math.min(0, width);
|
|
72
|
+
}
|
|
73
|
+
return left;
|
|
74
|
+
},
|
|
75
|
+
enumerable: true
|
|
76
|
+
},
|
|
77
|
+
right: {
|
|
78
|
+
get: function () {
|
|
79
|
+
if (right === undefined) {
|
|
80
|
+
right = x + Math.max(0, width);
|
|
81
|
+
}
|
|
82
|
+
return right;
|
|
83
|
+
},
|
|
84
|
+
enumerable: true
|
|
85
|
+
},
|
|
86
|
+
top: {
|
|
87
|
+
get: function () {
|
|
88
|
+
if (top === undefined) {
|
|
89
|
+
top = y + Math.min(0, height);
|
|
90
|
+
}
|
|
91
|
+
return top;
|
|
92
|
+
},
|
|
93
|
+
enumerable: true
|
|
94
|
+
},
|
|
95
|
+
bottom: {
|
|
96
|
+
get: function () {
|
|
97
|
+
if (bottom === undefined) {
|
|
98
|
+
bottom = y + Math.max(0, height);
|
|
99
|
+
}
|
|
100
|
+
return bottom;
|
|
101
|
+
},
|
|
102
|
+
enumerable: true
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
globalThis.DOMRect = DOMRect;
|
|
108
|
+
})(globalThis);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export {polyfillDOMRect};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** @type {import('../../types/trace-engine.js').TraceProcessor & typeof import('../../types/trace-engine.js').TraceProcessor} */
|
|
2
|
+
export const TraceProcessor: import('../../types/trace-engine.js').TraceProcessor & typeof import('../../types/trace-engine.js').TraceProcessor;
|
|
3
|
+
/** @type {import('../../types/trace-engine.js').TraceHandlers} */
|
|
4
|
+
export const TraceHandlers: any;
|
|
5
|
+
/** @type {import('../../types/trace-engine.js').RootCauses & typeof import('../../types/trace-engine.js').RootCauses} */
|
|
6
|
+
export const RootCauses: import('../../types/trace-engine.js').RootCauses & typeof import('../../types/trace-engine.js').RootCauses;
|
|
7
|
+
//# sourceMappingURL=trace-engine.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @ts-expect-error missing types
|
|
2
|
+
import * as TraceEngine from '@paulirish/trace_engine';
|
|
3
|
+
|
|
4
|
+
import {polyfillDOMRect} from './polyfill-dom-rect.js';
|
|
5
|
+
|
|
6
|
+
polyfillDOMRect();
|
|
7
|
+
|
|
8
|
+
/** @type {import('../../types/trace-engine.js').TraceProcessor & typeof import('../../types/trace-engine.js').TraceProcessor} */
|
|
9
|
+
const TraceProcessor = TraceEngine.Processor.TraceProcessor;
|
|
10
|
+
/** @type {import('../../types/trace-engine.js').TraceHandlers} */
|
|
11
|
+
const TraceHandlers = TraceEngine.Handlers.ModelHandlers;
|
|
12
|
+
/** @type {import('../../types/trace-engine.js').RootCauses & typeof import('../../types/trace-engine.js').RootCauses} */
|
|
13
|
+
const RootCauses = TraceEngine.RootCauses.RootCauses.RootCauses;
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
TraceProcessor,
|
|
17
|
+
TraceHandlers,
|
|
18
|
+
RootCauses,
|
|
19
|
+
};
|
|
@@ -75,4 +75,21 @@ curl "$url" -Lo chrome.zip && unzip -q chrome.zip && rm chrome.zip
|
|
|
75
75
|
mv * "$chrome_out"
|
|
76
76
|
cd - && rm -rf .tmp-download
|
|
77
77
|
|
|
78
|
+
echo "OUTPUT DIR: $chrome_out"
|
|
78
79
|
ls "$chrome_out"
|
|
80
|
+
|
|
81
|
+
echo "";
|
|
82
|
+
echo "Verifying CHROME_PATH...";
|
|
83
|
+
|
|
84
|
+
if ! [ -f $CHROME_PATH ]; then
|
|
85
|
+
echo "CHROME_PATH does not point to a valid file"
|
|
86
|
+
exit 1
|
|
87
|
+
else
|
|
88
|
+
echo "CHROME_PATH is good!"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# TODO: Find a convenient way to check the version in windows
|
|
92
|
+
if [ "$machine" != "MinGw" ]; then
|
|
93
|
+
echo "CHROME_PATH version:"
|
|
94
|
+
$CHROME_PATH --version
|
|
95
|
+
fi
|