lighthouse 12.3.0 → 12.4.0-dev.20250227
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/core-tests.js +4 -0
- package/core/audits/audit.d.ts +5 -0
- package/core/audits/audit.js +12 -0
- package/core/audits/bootup-time.js +0 -2
- package/core/audits/byte-efficiency/duplicated-javascript.d.ts +4 -5
- package/core/audits/byte-efficiency/duplicated-javascript.js +9 -5
- package/core/audits/byte-efficiency/legacy-javascript.d.ts +2 -2
- package/core/audits/byte-efficiency/legacy-javascript.js +17 -5
- package/core/audits/byte-efficiency/polyfill-graph-data.json +48 -49
- package/core/audits/byte-efficiency/total-byte-weight.js +0 -2
- package/core/audits/clickjacking-mitigation.d.ts +42 -0
- package/core/audits/clickjacking-mitigation.js +139 -0
- package/core/audits/dobetterweb/dom-size.js +0 -2
- package/core/audits/insights/README.md +3 -0
- package/core/audits/insights/cls-culprits-insight.d.ts +25 -0
- package/core/audits/insights/cls-culprits-insight.js +137 -0
- package/core/audits/insights/document-latency-insight.d.ts +11 -0
- package/core/audits/insights/document-latency-insight.js +48 -0
- package/core/audits/insights/dom-size-insight.d.ts +11 -0
- package/core/audits/insights/dom-size-insight.js +85 -0
- package/core/audits/insights/font-display-insight.d.ts +11 -0
- package/core/audits/insights/font-display-insight.js +53 -0
- package/core/audits/insights/forced-reflow-insight.d.ts +11 -0
- package/core/audits/insights/forced-reflow-insight.js +52 -0
- package/core/audits/insights/image-delivery-insight.d.ts +11 -0
- package/core/audits/insights/image-delivery-insight.js +83 -0
- package/core/audits/insights/insight-audit.d.ts +23 -0
- package/core/audits/insights/insight-audit.js +133 -0
- package/core/audits/insights/interaction-to-next-paint-insight.d.ts +11 -0
- package/core/audits/insights/interaction-to-next-paint-insight.js +71 -0
- package/core/audits/insights/lcp-discovery-insight.d.ts +11 -0
- package/core/audits/insights/lcp-discovery-insight.js +48 -0
- package/core/audits/insights/lcp-phases-insight.d.ts +16 -0
- package/core/audits/insights/lcp-phases-insight.js +87 -0
- package/core/audits/insights/long-critical-network-tree-insight.d.ts +11 -0
- package/core/audits/insights/long-critical-network-tree-insight.js +53 -0
- package/core/audits/insights/render-blocking-insight.d.ts +11 -0
- package/core/audits/insights/render-blocking-insight.js +57 -0
- package/core/audits/insights/slow-css-selector-insight.d.ts +11 -0
- package/core/audits/insights/slow-css-selector-insight.js +52 -0
- package/core/audits/insights/third-parties-insight.d.ts +28 -0
- package/core/audits/insights/third-parties-insight.js +90 -0
- package/core/audits/insights/viewport-insight.d.ts +11 -0
- package/core/audits/insights/viewport-insight.js +54 -0
- package/core/audits/layout-shifts.d.ts +0 -1
- package/core/audits/layout-shifts.js +18 -21
- package/core/audits/mainthread-work-breakdown.js +0 -2
- package/core/audits/seo/is-crawlable.d.ts +1 -0
- package/core/audits/server-response-time.js +0 -1
- package/core/computed/metrics/lantern-metric.js +5 -1
- package/core/computed/trace-engine-result.js +71 -17
- package/core/config/default-config.js +37 -1
- package/core/gather/gatherers/inspector-issues.js +3 -0
- package/core/gather/gatherers/trace-elements.d.ts +10 -2
- package/core/gather/gatherers/trace-elements.js +89 -12
- package/core/lib/bf-cache-strings.d.ts +7 -4
- package/core/lib/bf-cache-strings.js +174 -140
- package/core/lib/cdt/generated/ParsedURL.d.ts +1 -0
- package/core/lib/cdt/generated/ParsedURL.js +16 -4
- package/core/lib/cdt/generated/SourceMap.d.ts +32 -5
- package/core/lib/cdt/generated/SourceMap.js +192 -100
- package/core/lib/deprecations-strings.d.ts +78 -98
- package/core/lib/deprecations-strings.js +23 -41
- package/core/lib/i18n/i18n.d.ts +1 -0
- package/core/lib/i18n/i18n.js +2 -0
- package/core/lib/trace-engine.d.ts +1 -0
- package/core/lib/trace-engine.js +2 -0
- package/core/runner.js +2 -0
- package/dist/report/bundle.esm.js +196 -9
- package/dist/report/flow.js +197 -10
- package/dist/report/standalone.js +197 -10
- package/flow-report/src/i18n/i18n.d.ts +2 -0
- package/package.json +15 -13
- package/readme.md +3 -0
- package/report/assets/styles.css +179 -5
- package/report/assets/templates.html +14 -0
- package/report/renderer/components.js +9 -3
- package/report/renderer/details-renderer.d.ts +5 -0
- package/report/renderer/details-renderer.js +24 -0
- package/report/renderer/dom.d.ts +12 -1
- package/report/renderer/dom.js +26 -1
- package/report/renderer/i18n-formatter.d.ts +1 -1
- package/report/renderer/performance-category-renderer.d.ts +10 -0
- package/report/renderer/performance-category-renderer.js +81 -20
- package/report/renderer/report-utils.d.ts +1 -0
- package/report/renderer/report-utils.js +2 -0
- package/report/renderer/topbar-features.js +7 -0
- package/shared/localization/locales/ar-XB.json +74 -26
- package/shared/localization/locales/ar.json +76 -28
- package/shared/localization/locales/bg.json +74 -26
- package/shared/localization/locales/ca.json +74 -26
- package/shared/localization/locales/cs.json +74 -26
- package/shared/localization/locales/da.json +74 -26
- package/shared/localization/locales/de.json +75 -27
- package/shared/localization/locales/el.json +74 -26
- package/shared/localization/locales/en-GB.json +74 -26
- package/shared/localization/locales/en-US.json +288 -30
- package/shared/localization/locales/en-XA.json +48 -24
- package/shared/localization/locales/en-XL.json +288 -30
- package/shared/localization/locales/es-419.json +74 -26
- package/shared/localization/locales/es.json +74 -26
- package/shared/localization/locales/fi.json +74 -26
- package/shared/localization/locales/fil.json +75 -27
- package/shared/localization/locales/fr.json +74 -26
- package/shared/localization/locales/he.json +82 -34
- package/shared/localization/locales/hi.json +74 -26
- package/shared/localization/locales/hr.json +75 -27
- package/shared/localization/locales/hu.json +74 -26
- package/shared/localization/locales/id.json +74 -26
- package/shared/localization/locales/it.json +85 -37
- package/shared/localization/locales/ja.json +75 -27
- package/shared/localization/locales/ko.json +75 -27
- package/shared/localization/locales/lt.json +75 -27
- package/shared/localization/locales/lv.json +74 -26
- package/shared/localization/locales/nl.json +74 -26
- package/shared/localization/locales/no.json +75 -27
- package/shared/localization/locales/pl.json +74 -26
- package/shared/localization/locales/pt-PT.json +74 -26
- package/shared/localization/locales/pt.json +74 -26
- package/shared/localization/locales/ro.json +74 -26
- package/shared/localization/locales/ru.json +74 -26
- package/shared/localization/locales/sk.json +74 -26
- package/shared/localization/locales/sl.json +74 -26
- package/shared/localization/locales/sr-Latn.json +74 -26
- package/shared/localization/locales/sr.json +74 -26
- package/shared/localization/locales/sv.json +74 -26
- package/shared/localization/locales/ta.json +74 -26
- package/shared/localization/locales/te.json +74 -26
- package/shared/localization/locales/th.json +76 -28
- package/shared/localization/locales/tr.json +74 -26
- package/shared/localization/locales/uk.json +74 -26
- package/shared/localization/locales/vi.json +74 -26
- package/shared/localization/locales/zh-HK.json +75 -27
- package/shared/localization/locales/zh-TW.json +74 -26
- package/shared/localization/locales/zh.json +74 -26
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +3 -0
- package/types/artifacts.d.ts +5 -3
- package/types/audit.d.ts +2 -0
- package/types/lhr/audit-details.d.ts +13 -1
- package/types/lhr/audit-result.d.ts +2 -0
- package/core/gather/gatherers/root-causes.d.ts +0 -19
- package/core/gather/gatherers/root-causes.js +0 -144
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
import a11y from './test-definitions/a11y.js';
|
|
8
8
|
import byteEfficiency from './test-definitions/byte-efficiency.js';
|
|
9
9
|
import byteGzip from './test-definitions/byte-gzip.js';
|
|
10
|
+
import clickjackingMissingHeaders from './test-definitions/clickjacking-missing-headers.js';
|
|
11
|
+
import clickjackingMitigationPresent from './test-definitions/clickjacking-mitigation-headers-present.js';
|
|
10
12
|
import crash from './test-definitions/crash.js';
|
|
11
13
|
import cspAllowAll from './test-definitions/csp-allow-all.js';
|
|
12
14
|
import cspBlockAll from './test-definitions/csp-block-all.js';
|
|
@@ -69,6 +71,8 @@ const smokeTests = [
|
|
|
69
71
|
a11y,
|
|
70
72
|
byteEfficiency,
|
|
71
73
|
byteGzip,
|
|
74
|
+
clickjackingMissingHeaders,
|
|
75
|
+
clickjackingMitigationPresent,
|
|
72
76
|
crash,
|
|
73
77
|
cspAllowAll,
|
|
74
78
|
cspBlockAll,
|
package/core/audits/audit.d.ts
CHANGED
|
@@ -66,6 +66,11 @@ export class Audit {
|
|
|
66
66
|
* @param {LH.Audit.Details.Opportunity['items']|LH.Audit.Details.Table['items']} items
|
|
67
67
|
*/
|
|
68
68
|
static assertHeadingKeysExist(headings: LH.Audit.Details.Table["headings"] | LH.Audit.Details.Opportunity["headings"], items: LH.Audit.Details.Opportunity["items"] | LH.Audit.Details.Table["items"]): void;
|
|
69
|
+
/**
|
|
70
|
+
* @param {LH.Audit.Details.Checklist['items']} items
|
|
71
|
+
* @return {LH.Audit.Details.Checklist}
|
|
72
|
+
*/
|
|
73
|
+
static makeChecklistDetails(items: LH.Audit.Details.Checklist["items"]): LH.Audit.Details.Checklist;
|
|
69
74
|
/**
|
|
70
75
|
* @param {LH.Audit.Details.Table['headings']} headings
|
|
71
76
|
* @param {LH.Audit.Details.Table['items']} results
|
package/core/audits/audit.js
CHANGED
|
@@ -140,6 +140,17 @@ class Audit {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/**
|
|
144
|
+
* @param {LH.Audit.Details.Checklist['items']} items
|
|
145
|
+
* @return {LH.Audit.Details.Checklist}
|
|
146
|
+
*/
|
|
147
|
+
static makeChecklistDetails(items) {
|
|
148
|
+
return {
|
|
149
|
+
type: 'checklist',
|
|
150
|
+
items,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
143
154
|
/**
|
|
144
155
|
* @param {LH.Audit.Details.Table['headings']} headings
|
|
145
156
|
* @param {LH.Audit.Details.Table['items']} results
|
|
@@ -467,6 +478,7 @@ class Audit {
|
|
|
467
478
|
|
|
468
479
|
details: product.details,
|
|
469
480
|
guidanceLevel: audit.meta.guidanceLevel,
|
|
481
|
+
replacesAudits: audit.meta.replacesAudits,
|
|
470
482
|
};
|
|
471
483
|
}
|
|
472
484
|
|
|
@@ -14,7 +14,6 @@ import {MainThreadTasks} from '../computed/main-thread-tasks.js';
|
|
|
14
14
|
import {getExecutionTimingsByURL} from '../lib/tracehouse/task-summary.js';
|
|
15
15
|
import {TBTImpactTasks} from '../computed/tbt-impact-tasks.js';
|
|
16
16
|
import {Sentry} from '../lib/sentry.js';
|
|
17
|
-
import {Util} from '../../shared/util.js';
|
|
18
17
|
|
|
19
18
|
const UIStrings = {
|
|
20
19
|
/** Title of a diagnostic audit that provides detail on the time spent executing javascript files during the load. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
|
|
@@ -173,7 +172,6 @@ class BootupTime extends Audit {
|
|
|
173
172
|
|
|
174
173
|
return {
|
|
175
174
|
score,
|
|
176
|
-
scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
|
|
177
175
|
notApplicable: !results.length,
|
|
178
176
|
numericValue: totalBootupTime,
|
|
179
177
|
numericUnit: 'millisecond',
|
|
@@ -26,11 +26,10 @@ declare class DuplicatedJavascript extends ByteEfficiencyAudit {
|
|
|
26
26
|
resourceSize: number;
|
|
27
27
|
}[]>>;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* wastedBytesByUrl attributes the cost of the bytes to a specific resource, for use by lantern.
|
|
29
|
+
* Each details item returned is a module with subItems for each resource that
|
|
30
|
+
* includes it. The wastedBytes for the details item is the number of bytes
|
|
31
|
+
* occupied by the sum of all but the largest copy of the module. wastedBytesByUrl
|
|
32
|
+
* attributes the cost of the bytes to a specific resource, for use by lantern.
|
|
34
33
|
* @param {LH.Artifacts} artifacts
|
|
35
34
|
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
36
35
|
* @param {LH.Audit.Context} context
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview This audit highlights JavaScript modules that appear to be duplicated across
|
|
9
|
+
* all resources, either within the same bundle or between different bundles.
|
|
10
|
+
*/
|
|
11
|
+
|
|
7
12
|
/** @typedef {import('./byte-efficiency-audit.js').ByteEfficiencyProduct} ByteEfficiencyProduct */
|
|
8
13
|
/** @typedef {LH.Audit.ByteEfficiencyItem & {source: string, subItems: {type: 'subitems', items: SubItem[]}}} Item */
|
|
9
14
|
/** @typedef {{url: string, sourceTransferBytes?: number}} SubItem */
|
|
@@ -104,11 +109,10 @@ class DuplicatedJavascript extends ByteEfficiencyAudit {
|
|
|
104
109
|
}
|
|
105
110
|
|
|
106
111
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* wastedBytesByUrl attributes the cost of the bytes to a specific resource, for use by lantern.
|
|
112
|
+
* Each details item returned is a module with subItems for each resource that
|
|
113
|
+
* includes it. The wastedBytes for the details item is the number of bytes
|
|
114
|
+
* occupied by the sum of all but the largest copy of the module. wastedBytesByUrl
|
|
115
|
+
* attributes the cost of the bytes to a specific resource, for use by lantern.
|
|
112
116
|
* @param {LH.Artifacts} artifacts
|
|
113
117
|
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
114
118
|
* @param {LH.Audit.Context} context
|
|
@@ -50,11 +50,10 @@ declare class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
50
50
|
*
|
|
51
51
|
* @param {CodePatternMatcher} matcher
|
|
52
52
|
* @param {LH.Artifacts['Scripts']} scripts
|
|
53
|
-
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
54
53
|
* @param {LH.Artifacts.Bundle[]} bundles
|
|
55
54
|
* @return {Map<LH.Artifacts.Script, PatternMatchResult[]>}
|
|
56
55
|
*/
|
|
57
|
-
static detectAcrossScripts(matcher: CodePatternMatcher, scripts: LH.Artifacts["Scripts"],
|
|
56
|
+
static detectAcrossScripts(matcher: CodePatternMatcher, scripts: LH.Artifacts["Scripts"], bundles: LH.Artifacts.Bundle[]): Map<LH.Artifacts.Script, PatternMatchResult[]>;
|
|
58
57
|
/**
|
|
59
58
|
* @param {PatternMatchResult[]} matches
|
|
60
59
|
* @return {number}
|
|
@@ -71,6 +70,7 @@ declare class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
71
70
|
export namespace UIStrings {
|
|
72
71
|
let title: string;
|
|
73
72
|
let description: string;
|
|
73
|
+
let detectedCoreJs2Warning: string;
|
|
74
74
|
}
|
|
75
75
|
import { ByteEfficiencyAudit } from './byte-efficiency-audit.js';
|
|
76
76
|
/**
|
|
@@ -39,7 +39,10 @@ const UIStrings = {
|
|
|
39
39
|
// eslint-disable-next-line max-len
|
|
40
40
|
// TODO: developer.chrome.com article. this codelab is good starting place: https://web.dev/articles/codelab-serve-modern-code
|
|
41
41
|
/** Description of a Lighthouse audit that tells the user about old JavaScript that is no longer needed. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
42
|
-
description: 'Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren\'t necessary for modern browsers. For your bundled JavaScript, adopt a modern script deployment strategy using module/nomodule feature detection to reduce the amount of code shipped to modern browsers, while retaining support for legacy browsers. [Learn how to
|
|
42
|
+
description: 'Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren\'t necessary for modern browsers. For your bundled JavaScript, adopt a modern script deployment strategy using [module/nomodule feature detection](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) to reduce the amount of code shipped to modern browsers, while retaining support for legacy browsers. [Learn how to serve modern JavaScript](https://web.dev/articles/codelab-serve-modern-code)',
|
|
43
|
+
/** Warning text that an outdated version of the library "core-js" was found, and the developer should upgrade. */
|
|
44
|
+
// eslint-disable-next-line max-len
|
|
45
|
+
detectedCoreJs2Warning: 'Version 2 of core-js was detected on the page. You should upgrade to version 3 for many performance improvements.',
|
|
43
46
|
};
|
|
44
47
|
|
|
45
48
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
@@ -231,7 +234,6 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
231
234
|
['Reflect.preventExtensions', 'es6.reflect.prevent-extensions'],
|
|
232
235
|
['Reflect.setPrototypeOf', 'es6.reflect.set-prototype-of'],
|
|
233
236
|
['String.prototype.codePointAt', 'es6.string.code-point-at'],
|
|
234
|
-
['String.fromCodePoint', 'es6.string.from-code-point'],
|
|
235
237
|
['String.raw', 'es6.string.raw'],
|
|
236
238
|
['String.prototype.repeat', 'es6.string.repeat'],
|
|
237
239
|
['Object.entries', 'es7.object.entries'],
|
|
@@ -321,11 +323,10 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
321
323
|
*
|
|
322
324
|
* @param {CodePatternMatcher} matcher
|
|
323
325
|
* @param {LH.Artifacts['Scripts']} scripts
|
|
324
|
-
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
325
326
|
* @param {LH.Artifacts.Bundle[]} bundles
|
|
326
327
|
* @return {Map<LH.Artifacts.Script, PatternMatchResult[]>}
|
|
327
328
|
*/
|
|
328
|
-
static detectAcrossScripts(matcher, scripts,
|
|
329
|
+
static detectAcrossScripts(matcher, scripts, bundles) {
|
|
329
330
|
/** @type {Map<LH.Artifacts.Script, PatternMatchResult[]>} */
|
|
330
331
|
const scriptToMatchResults = new Map();
|
|
331
332
|
const polyfillData = this.getPolyfillData();
|
|
@@ -426,7 +427,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
426
427
|
const compressionRatioByUrl = new Map();
|
|
427
428
|
|
|
428
429
|
const scriptToMatchResults =
|
|
429
|
-
this.detectAcrossScripts(matcher, artifacts.Scripts,
|
|
430
|
+
this.detectAcrossScripts(matcher, artifacts.Scripts, bundles);
|
|
430
431
|
for (const [script, matches] of scriptToMatchResults.entries()) {
|
|
431
432
|
const compressionRatio = estimateCompressionRatioForContent(
|
|
432
433
|
compressionRatioByUrl, script.url, artifacts, networkRecords);
|
|
@@ -456,6 +457,16 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
456
457
|
items.push(item);
|
|
457
458
|
}
|
|
458
459
|
|
|
460
|
+
const warnings = [];
|
|
461
|
+
for (const bundle of bundles) {
|
|
462
|
+
if (classifiedEntities.isFirstParty(bundle.script.url)) {
|
|
463
|
+
if (bundle.rawMap.sources.some(s => s.match(/node_modules\/core-js\/modules\/es[67]/))) {
|
|
464
|
+
warnings.push(str_(UIStrings.detectedCoreJs2Warning));
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
459
470
|
/** @type {Map<string, number>} */
|
|
460
471
|
const wastedBytesByUrl = new Map();
|
|
461
472
|
for (const item of items) {
|
|
@@ -478,6 +489,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
478
489
|
items,
|
|
479
490
|
headings,
|
|
480
491
|
wastedBytesByUrl,
|
|
492
|
+
warnings,
|
|
481
493
|
};
|
|
482
494
|
}
|
|
483
495
|
}
|
|
@@ -1,54 +1,53 @@
|
|
|
1
1
|
{
|
|
2
|
-
"moduleSizes": [
|
|
2
|
+
"moduleSizes": [17302, 498, 282, 294, 281, 467, 236, 229, 546, 339, 1608, 723, 1545, 438, 214, 111, 537, 209, 281, 685, 217, 757, 631, 182, 407, 140, 366, 1478, 359, 792, 269, 158, 280, 137, 189, 543, 1436, 88, 146, 314, 375, 183, 1083, 195, 503, 269, 208, 334, 350, 460, 568, 229, 334, 266, 30, 120, 309, 370, 358, 1952, 1638, 304, 153, 274, 1288, 192, 543, 187, 74, 144, 137, 33, 457, 535, 117, 1961, 133, 1956, 693, 1426, 863, 637, 301, 51, 708, 583, 119, 600, 221, 370, 728, 1085, 552, 629, 217, 183, 546, 137, 983, 992, 503, 402, 254, 223, 164, 214, 191, 831, 218, 202, 232, 124, 249, 160, 251, 217, 717, 225, 432, 499, 445, 177, 346, 142, 414, 617, 380, 264, 212, 524, 529, 708, 173, 272, 308, 296, 191, 485, 799, 533, 215, 589, 589, 362, 562, 471, 179, 186, 521, 1536, 756, 427, 444, 406, 912, 150, 283, 144, 485, 470, 205, 814, 146, 3000],
|
|
3
3
|
"dependencies": {
|
|
4
|
-
"Array.prototype.fill": [0, 5, 8, 11,
|
|
5
|
-
"Array.prototype.filter": [0, 11, 12, 13, 17,
|
|
6
|
-
"Array.prototype.find": [0, 5, 11, 12, 17,
|
|
7
|
-
"Array.prototype.findIndex": [0, 5, 11, 12, 17,
|
|
8
|
-
"Array.prototype.forEach": [0, 9, 11, 12, 14, 17,
|
|
9
|
-
"Array.from": [0, 10, 11, 19, 20, 21, 22,
|
|
10
|
-
"Array.isArray": [0, 11,
|
|
11
|
-
"Array.prototype.map": [0, 11, 12, 13, 17,
|
|
12
|
-
"Array.of": [0, 11, 21, 22,
|
|
13
|
-
"Array.prototype.some": [0, 11, 12, 14, 17,
|
|
14
|
-
"Date.now": [0, 11,
|
|
15
|
-
"Date.prototype.toISOString": [0, 11, 21, 22,
|
|
16
|
-
"Date.prototype.toJSON": [0, 11,
|
|
17
|
-
"Date.prototype.toString": [0,
|
|
18
|
-
"Function.prototype.name": [0,
|
|
19
|
-
"Number.isInteger": [0, 11,
|
|
20
|
-
"Number.isSafeInteger": [0, 11,
|
|
21
|
-
"Object.defineProperties": [0, 11,
|
|
22
|
-
"Object.defineProperty": [0, 11,
|
|
23
|
-
"Object.freeze": [0, 7, 11, 15,
|
|
24
|
-
"Object.getPrototypeOf": [0, 11,
|
|
25
|
-
"Object.isExtensible": [0, 7, 11,
|
|
26
|
-
"Object.isFrozen": [0, 7, 11,
|
|
27
|
-
"Object.isSealed": [0, 7, 11,
|
|
28
|
-
"Object.keys": [0, 11,
|
|
29
|
-
"Object.preventExtensions": [0, 7, 11, 15,
|
|
30
|
-
"Object.seal": [0, 7, 11, 15,
|
|
31
|
-
"Object.setPrototypeOf": [0, 4, 11,
|
|
32
|
-
"Reflect.apply": [0, 11,
|
|
33
|
-
"Reflect.construct": [0, 3, 11,
|
|
34
|
-
"Reflect.defineProperty": [0, 11,
|
|
35
|
-
"Reflect.deleteProperty": [0, 11,
|
|
36
|
-
"Reflect.get": [0, 11,
|
|
37
|
-
"Reflect.getOwnPropertyDescriptor": [0, 11,
|
|
38
|
-
"Reflect.getPrototypeOf": [0, 11,
|
|
39
|
-
"Reflect.has": [0, 11,
|
|
40
|
-
"Reflect.isExtensible": [0, 7, 11,
|
|
41
|
-
"Reflect.ownKeys": [0, 11,
|
|
42
|
-
"Reflect.preventExtensions": [0, 11,
|
|
43
|
-
"Reflect.setPrototypeOf": [0, 4, 11,
|
|
44
|
-
"String.prototype.codePointAt": [0, 11, 21, 22,
|
|
45
|
-
"String.
|
|
46
|
-
"String.
|
|
47
|
-
"
|
|
48
|
-
"Object.
|
|
49
|
-
"Object.
|
|
50
|
-
"Object.values": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 87, 88, 90, 92, 94, 101, 102, 103, 104, 114, 146],
|
|
4
|
+
"Array.prototype.fill": [0, 5, 8, 11, 20, 22, 29, 33, 36, 55, 57, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 117],
|
|
5
|
+
"Array.prototype.filter": [0, 11, 12, 13, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 118],
|
|
6
|
+
"Array.prototype.find": [0, 5, 11, 12, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 55, 57, 62, 64, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 109, 120],
|
|
7
|
+
"Array.prototype.findIndex": [0, 5, 11, 12, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 55, 57, 62, 64, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 109, 119],
|
|
8
|
+
"Array.prototype.forEach": [0, 9, 11, 12, 14, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 121],
|
|
9
|
+
"Array.from": [0, 10, 11, 18, 19, 20, 21, 22, 26, 29, 33, 36, 40, 46, 49, 50, 57, 61, 64, 66, 73, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 122],
|
|
10
|
+
"Array.isArray": [0, 11, 20, 22, 29, 33, 36, 57, 62, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 123],
|
|
11
|
+
"Array.prototype.map": [0, 11, 12, 13, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 124],
|
|
12
|
+
"Array.of": [0, 11, 20, 21, 22, 26, 29, 33, 36, 57, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 125],
|
|
13
|
+
"Array.prototype.some": [0, 11, 12, 14, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 126],
|
|
14
|
+
"Date.now": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 127],
|
|
15
|
+
"Date.prototype.toISOString": [0, 11, 20, 21, 22, 27, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 99, 100, 102, 103, 104, 105, 109, 110, 128],
|
|
16
|
+
"Date.prototype.toJSON": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 129],
|
|
17
|
+
"Date.prototype.toString": [0, 29, 130],
|
|
18
|
+
"Function.prototype.name": [0, 28, 131],
|
|
19
|
+
"Number.isInteger": [0, 11, 20, 22, 29, 33, 36, 57, 66, 67, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 132],
|
|
20
|
+
"Number.isSafeInteger": [0, 11, 20, 22, 29, 33, 36, 57, 66, 67, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 133],
|
|
21
|
+
"Object.defineProperties": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 134],
|
|
22
|
+
"Object.defineProperty": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 135],
|
|
23
|
+
"Object.freeze": [0, 7, 11, 15, 20, 22, 29, 33, 36, 38, 57, 59, 66, 74, 76, 80, 81, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 137],
|
|
24
|
+
"Object.getPrototypeOf": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 89, 93, 102, 103, 104, 105, 139],
|
|
25
|
+
"Object.isExtensible": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 140],
|
|
26
|
+
"Object.isFrozen": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 141],
|
|
27
|
+
"Object.isSealed": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 142],
|
|
28
|
+
"Object.keys": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 143],
|
|
29
|
+
"Object.preventExtensions": [0, 7, 11, 15, 20, 22, 29, 33, 36, 38, 57, 59, 66, 74, 76, 80, 81, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 144],
|
|
30
|
+
"Object.seal": [0, 7, 11, 15, 20, 22, 29, 33, 36, 38, 57, 59, 66, 74, 76, 80, 81, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 145],
|
|
31
|
+
"Object.setPrototypeOf": [0, 4, 11, 20, 22, 29, 33, 36, 45, 57, 66, 70, 74, 76, 80, 82, 83, 87, 89, 90, 93, 102, 103, 104, 105, 146],
|
|
32
|
+
"Reflect.apply": [0, 11, 20, 22, 29, 33, 36, 39, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 148],
|
|
33
|
+
"Reflect.construct": [0, 3, 11, 15, 20, 21, 22, 29, 33, 36, 39, 42, 55, 57, 64, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 109, 149],
|
|
34
|
+
"Reflect.defineProperty": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 150],
|
|
35
|
+
"Reflect.deleteProperty": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 151],
|
|
36
|
+
"Reflect.get": [0, 11, 20, 22, 23, 29, 33, 36, 57, 65, 66, 74, 76, 80, 82, 83, 84, 87, 89, 93, 102, 103, 104, 105, 154],
|
|
37
|
+
"Reflect.getOwnPropertyDescriptor": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 152],
|
|
38
|
+
"Reflect.getPrototypeOf": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 89, 93, 102, 103, 104, 105, 153],
|
|
39
|
+
"Reflect.has": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 155],
|
|
40
|
+
"Reflect.isExtensible": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 156],
|
|
41
|
+
"Reflect.ownKeys": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 157],
|
|
42
|
+
"Reflect.preventExtensions": [0, 11, 20, 22, 29, 33, 36, 38, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 158],
|
|
43
|
+
"Reflect.setPrototypeOf": [0, 4, 11, 20, 22, 29, 33, 36, 45, 57, 66, 70, 74, 76, 80, 82, 83, 87, 89, 90, 93, 102, 103, 104, 105, 159],
|
|
44
|
+
"String.prototype.codePointAt": [0, 11, 20, 21, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 98, 102, 103, 104, 105, 109, 110, 160],
|
|
45
|
+
"String.raw": [0, 11, 20, 21, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 110, 161],
|
|
46
|
+
"String.prototype.repeat": [0, 11, 20, 21, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 100, 102, 103, 104, 105, 109, 110, 162],
|
|
47
|
+
"Object.entries": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 88, 89, 91, 93, 102, 103, 104, 105, 136],
|
|
48
|
+
"Object.getOwnPropertyDescriptors": [0, 11, 20, 22, 26, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 138],
|
|
49
|
+
"Object.values": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 88, 89, 91, 93, 102, 103, 104, 105, 147],
|
|
51
50
|
"focus-visible": [163]
|
|
52
51
|
},
|
|
53
|
-
"maxSize":
|
|
52
|
+
"maxSize": 94935
|
|
54
53
|
}
|
|
@@ -8,7 +8,6 @@ import {Audit} from '../audit.js';
|
|
|
8
8
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
9
9
|
import {NetworkRequest} from '../../lib/network-request.js';
|
|
10
10
|
import {NetworkRecords} from '../../computed/network-records.js';
|
|
11
|
-
import {Util} from '../../../shared/util.js';
|
|
12
11
|
|
|
13
12
|
const UIStrings = {
|
|
14
13
|
/** Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
|
|
@@ -99,7 +98,6 @@ class TotalByteWeight extends Audit {
|
|
|
99
98
|
|
|
100
99
|
return {
|
|
101
100
|
score,
|
|
102
|
-
scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
|
|
103
101
|
numericValue: totalBytes,
|
|
104
102
|
numericUnit: 'byte',
|
|
105
103
|
displayValue: str_(UIStrings.displayValue, {totalBytes}),
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export default ClickjackingMitigation;
|
|
2
|
+
declare class ClickjackingMitigation extends Audit {
|
|
3
|
+
/**
|
|
4
|
+
* @param {LH.Artifacts} artifacts
|
|
5
|
+
* @param {LH.Audit.Context} context
|
|
6
|
+
* @return {Promise<{cspHeaders: string[], xfoHeaders: string[]}>}
|
|
7
|
+
*/
|
|
8
|
+
static getRawCspsAndXfo(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<{
|
|
9
|
+
cspHeaders: string[];
|
|
10
|
+
xfoHeaders: string[];
|
|
11
|
+
}>;
|
|
12
|
+
/**
|
|
13
|
+
* @param {string | undefined} directive
|
|
14
|
+
* @param {LH.IcuMessage | string} findingDescription
|
|
15
|
+
* @param {LH.IcuMessage=} severity
|
|
16
|
+
* @return {LH.Audit.Details.TableItem}
|
|
17
|
+
*/
|
|
18
|
+
static findingToTableItem(directive: string | undefined, findingDescription: LH.IcuMessage | string, severity?: LH.IcuMessage | undefined): LH.Audit.Details.TableItem;
|
|
19
|
+
/**
|
|
20
|
+
* @param {string[]} cspHeaders
|
|
21
|
+
* @param {string[]} xfoHeaders
|
|
22
|
+
* @return {{score: number, results: LH.Audit.Details.TableItem[]}}
|
|
23
|
+
*/
|
|
24
|
+
static constructResults(cspHeaders: string[], xfoHeaders: string[]): {
|
|
25
|
+
score: number;
|
|
26
|
+
results: LH.Audit.Details.TableItem[];
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* @param {LH.Artifacts} artifacts
|
|
30
|
+
* @param {LH.Audit.Context} context
|
|
31
|
+
* @return {Promise<LH.Audit.Product>}
|
|
32
|
+
*/
|
|
33
|
+
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
34
|
+
}
|
|
35
|
+
export namespace UIStrings {
|
|
36
|
+
let title: string;
|
|
37
|
+
let description: string;
|
|
38
|
+
let noClickjackingMitigation: string;
|
|
39
|
+
let columnSeverity: string;
|
|
40
|
+
}
|
|
41
|
+
import { Audit } from './audit.js';
|
|
42
|
+
//# sourceMappingURL=clickjacking-mitigation.d.ts.map
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2024 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {Audit} from './audit.js';
|
|
8
|
+
import {MainResource} from '../computed/main-resource.js';
|
|
9
|
+
import * as i18n from '../lib/i18n/i18n.js';
|
|
10
|
+
|
|
11
|
+
const UIStrings = {
|
|
12
|
+
/** Title of a Lighthouse audit that evaluates whether the set CSP or XFO header is mitigating clickjacking attacks. "XFO" stands for "X-Frame-Options" and should not be translated. "CSP" stands for "Content-Security-Policy" and should not be translated. "clickjacking" should not be translated. */
|
|
13
|
+
title: 'Mitigate clickjacking with XFO or CSP',
|
|
14
|
+
/** Description of a Lighthouse audit that evaluates whether the set CSP or XFO header is mitigating clickjacking attacks. This is displayed after a user expands the section to see more. "clickjacking" should not be translated. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. "XFO" stands for "X-Frame-Options" and should not be translated. "CSP" stands for "Content-Security-Policy" and should not be translated. */
|
|
15
|
+
description: 'The `X-Frame-Options` (XFO) header or the `frame-ancestors` directive in the `Content-Security-Policy` (CSP) header control where a page can be embedded. These can mitigate clickjacking attacks by blocking some or all sites from embedding the page. [Learn more about mitigating clickjacking](https://developer.chrome.com/docs/lighthouse/best-practices/clickjacking-mitigation).',
|
|
16
|
+
/** Summary text for the results of a Lighthouse audit that evaluates whether the page is mitigating clickjacking attacks with a frame control policy. This text is displayed if the page does not control how it can be embedded on other pages. */
|
|
17
|
+
noClickjackingMitigation: 'No frame control policy found',
|
|
18
|
+
/** Label for a column in a data table; entries will be the severity of an issue with the page's frame control policy. */
|
|
19
|
+
columnSeverity: 'Severity',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
23
|
+
|
|
24
|
+
class ClickjackingMitigation extends Audit {
|
|
25
|
+
/**
|
|
26
|
+
* @return {LH.Audit.Meta}
|
|
27
|
+
*/
|
|
28
|
+
static get meta() {
|
|
29
|
+
return {
|
|
30
|
+
id: 'clickjacking-mitigation',
|
|
31
|
+
scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
|
|
32
|
+
title: str_(UIStrings.title),
|
|
33
|
+
description: str_(UIStrings.description),
|
|
34
|
+
requiredArtifacts: ['devtoolsLogs', 'URL'],
|
|
35
|
+
supportedModes: ['navigation'],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {LH.Artifacts} artifacts
|
|
41
|
+
* @param {LH.Audit.Context} context
|
|
42
|
+
* @return {Promise<{cspHeaders: string[], xfoHeaders: string[]}>}
|
|
43
|
+
*/
|
|
44
|
+
static async getRawCspsAndXfo(artifacts, context) {
|
|
45
|
+
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
|
|
46
|
+
const mainResource =
|
|
47
|
+
await MainResource.request({devtoolsLog, URL: artifacts.URL}, context);
|
|
48
|
+
|
|
49
|
+
const cspHeaders = mainResource.responseHeaders
|
|
50
|
+
.filter(h => {
|
|
51
|
+
return h.name.toLowerCase() === 'content-security-policy';
|
|
52
|
+
})
|
|
53
|
+
.flatMap(h => h.value.split(','))
|
|
54
|
+
.filter(rawCsp => rawCsp.replace(/\s/g, ''));
|
|
55
|
+
let xfoHeaders = mainResource.responseHeaders
|
|
56
|
+
.filter(h => {
|
|
57
|
+
return h.name.toLowerCase() === 'x-frame-options';
|
|
58
|
+
})
|
|
59
|
+
.flatMap(h => h.value);
|
|
60
|
+
|
|
61
|
+
// Sanitize the XFO header value.
|
|
62
|
+
xfoHeaders = xfoHeaders.map(v => v.toLowerCase().replace(/\s/g, ''));
|
|
63
|
+
|
|
64
|
+
return {cspHeaders, xfoHeaders};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {string | undefined} directive
|
|
69
|
+
* @param {LH.IcuMessage | string} findingDescription
|
|
70
|
+
* @param {LH.IcuMessage=} severity
|
|
71
|
+
* @return {LH.Audit.Details.TableItem}
|
|
72
|
+
*/
|
|
73
|
+
static findingToTableItem(directive, findingDescription, severity) {
|
|
74
|
+
return {
|
|
75
|
+
description: findingDescription,
|
|
76
|
+
severity,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {string[]} cspHeaders
|
|
82
|
+
* @param {string[]} xfoHeaders
|
|
83
|
+
* @return {{score: number, results: LH.Audit.Details.TableItem[]}}
|
|
84
|
+
*/
|
|
85
|
+
static constructResults(cspHeaders, xfoHeaders) {
|
|
86
|
+
const allowedDirectives = ['deny', 'sameorigin'];
|
|
87
|
+
|
|
88
|
+
// Check for frame-ancestors in CSP.
|
|
89
|
+
for (const cspHeader of cspHeaders) {
|
|
90
|
+
if (cspHeader.includes('frame-ancestors')) {
|
|
91
|
+
// Pass the audit if frame-ancestors is present.
|
|
92
|
+
return {score: 1, results: []};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const actualDirective of xfoHeaders) {
|
|
97
|
+
if (allowedDirectives.includes(actualDirective)) {
|
|
98
|
+
// DENY or SAMEORIGIN are present.
|
|
99
|
+
return {score: 1, results: []};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
score: 0,
|
|
105
|
+
results: [{
|
|
106
|
+
severity: str_(i18n.UIStrings.itemSeverityHigh),
|
|
107
|
+
description: str_(UIStrings.noClickjackingMitigation),
|
|
108
|
+
}],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @param {LH.Artifacts} artifacts
|
|
114
|
+
* @param {LH.Audit.Context} context
|
|
115
|
+
* @return {Promise<LH.Audit.Product>}
|
|
116
|
+
*/
|
|
117
|
+
static async audit(artifacts, context) {
|
|
118
|
+
const {cspHeaders, xfoHeaders} = await this.getRawCspsAndXfo(artifacts, context);
|
|
119
|
+
const {score, results} = this.constructResults(cspHeaders, xfoHeaders);
|
|
120
|
+
|
|
121
|
+
/** @type {LH.Audit.Details.Table['headings']} */
|
|
122
|
+
const headings = [
|
|
123
|
+
/* eslint-disable max-len */
|
|
124
|
+
{key: 'description', valueType: 'text', subItemsHeading: {key: 'description'}, label: str_(i18n.UIStrings.columnDescription)},
|
|
125
|
+
{key: 'severity', valueType: 'text', subItemsHeading: {key: 'severity'}, label: str_(UIStrings.columnSeverity)},
|
|
126
|
+
/* eslint-enable max-len */
|
|
127
|
+
];
|
|
128
|
+
const details = Audit.makeTableDetails(headings, results);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
score,
|
|
132
|
+
notApplicable: !results.length,
|
|
133
|
+
details,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export default ClickjackingMitigation;
|
|
139
|
+
export {UIStrings};
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
import {Audit} from '../audit.js';
|
|
15
15
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
16
16
|
import {TBTImpactTasks} from '../../computed/tbt-impact-tasks.js';
|
|
17
|
-
import {Util} from '../../../shared/util.js';
|
|
18
17
|
|
|
19
18
|
const UIStrings = {
|
|
20
19
|
/** Title of a diagnostic audit that provides detail on the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
|
|
@@ -168,7 +167,6 @@ class DOMSize extends Audit {
|
|
|
168
167
|
|
|
169
168
|
return {
|
|
170
169
|
score,
|
|
171
|
-
scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
|
|
172
170
|
numericValue: stats.totalBodyElements,
|
|
173
171
|
numericUnit: 'element',
|
|
174
172
|
displayValue: str_(UIStrings.displayValue, {itemCount: stats.totalBodyElements}),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export default CLSCulpritsInsight;
|
|
2
|
+
export type SubItem = {
|
|
3
|
+
extra?: LH.Audit.Details.NodeValue | LH.Audit.Details.UrlValue;
|
|
4
|
+
cause: LH.IcuMessage;
|
|
5
|
+
};
|
|
6
|
+
declare class CLSCulpritsInsight extends Audit {
|
|
7
|
+
/**
|
|
8
|
+
* @param {import('@paulirish/trace_engine/models/trace/insights/CLSCulprits.js').CLSCulpritsInsightModel} insight
|
|
9
|
+
* @param {import('../../lib/trace-engine.js').SaneSyntheticLayoutShift} event
|
|
10
|
+
* @param {LH.Artifacts.TraceElement[]} TraceElements
|
|
11
|
+
* @return {LH.Audit.Details.TableSubItems|undefined}
|
|
12
|
+
*/
|
|
13
|
+
static getCulpritSubItems(insight: import("@paulirish/trace_engine/models/trace/insights/CLSCulprits.js").CLSCulpritsInsightModel, event: import("../../lib/trace-engine.js").SaneSyntheticLayoutShift, TraceElements: LH.Artifacts.TraceElement[]): LH.Audit.Details.TableSubItems | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* @param {LH.Artifacts} artifacts
|
|
16
|
+
* @param {LH.Audit.Context} context
|
|
17
|
+
* @return {Promise<LH.Audit.Product>}
|
|
18
|
+
*/
|
|
19
|
+
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
20
|
+
}
|
|
21
|
+
export namespace UIStrings {
|
|
22
|
+
let columnScore: string;
|
|
23
|
+
}
|
|
24
|
+
import { Audit } from '../audit.js';
|
|
25
|
+
//# sourceMappingURL=cls-culprits-insight.d.ts.map
|