lighthouse 8.3.0-dev.20210904 → 8.3.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/changelog.md +1 -1
- package/dist/report/standalone.js +196 -0
- package/jest.config.js +0 -4
- package/lighthouse-cli/cli-flags.js +6 -14
- package/lighthouse-cli/run.js +1 -1
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +3 -9
- package/lighthouse-cli/test/smokehouse/report-assert.js +16 -36
- package/lighthouse-core/audits/large-javascript-libraries.js +166 -0
- package/lighthouse-core/audits/seo/http-status-code.js +6 -2
- package/lighthouse-core/audits/viewport.js +1 -2
- package/lighthouse-core/config/config-helpers.js +75 -9
- package/lighthouse-core/config/config.js +50 -6
- package/lighthouse-core/config/constants.js +0 -1
- package/lighthouse-core/config/default-config.js +0 -3
- package/lighthouse-core/config/experimental-config.js +8 -0
- package/lighthouse-core/config/metrics-to-audits.js +0 -1
- package/lighthouse-core/fraggle-rock/config/config.js +4 -3
- package/lighthouse-core/fraggle-rock/config/default-config.js +1 -3
- package/lighthouse-core/fraggle-rock/config/validation.js +0 -201
- package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +0 -4
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +8 -16
- package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +0 -4
- package/lighthouse-core/fraggle-rock/gather/session.js +5 -30
- package/lighthouse-core/gather/driver/navigation.js +6 -7
- package/lighthouse-core/gather/driver/wait-for-condition.js +0 -27
- package/lighthouse-core/gather/fetcher.js +7 -17
- package/lighthouse-core/gather/gather-runner.js +0 -1
- package/lighthouse-core/gather/gatherers/seo/robots-txt.js +6 -2
- package/lighthouse-core/gather/gatherers/seo/tap-targets.js +2 -2
- package/lighthouse-core/gather/gatherers/stacks.js +1 -1
- package/lighthouse-core/lib/asset-saver.js +2 -2
- package/lighthouse-core/lib/cdt/SDK.js +0 -1
- package/lighthouse-core/lib/csp-evaluator.js +4 -17
- package/{report/generator → lighthouse-core/lib}/file-namer.js +0 -0
- package/lighthouse-core/lib/i18n/README.md +1 -1
- package/lighthouse-core/lib/i18n/i18n.js +7 -7
- package/lighthouse-core/lib/i18n/locales/ar-XB.json +18 -0
- package/lighthouse-core/lib/i18n/locales/ar.json +18 -0
- package/lighthouse-core/lib/i18n/locales/bg.json +18 -0
- package/lighthouse-core/lib/i18n/locales/ca.json +18 -0
- package/lighthouse-core/lib/i18n/locales/cs.json +18 -0
- package/lighthouse-core/lib/i18n/locales/da.json +18 -0
- package/lighthouse-core/lib/i18n/locales/de.json +18 -0
- package/lighthouse-core/lib/i18n/locales/el.json +18 -0
- package/lighthouse-core/lib/i18n/locales/en-GB.json +18 -0
- package/lighthouse-core/lib/i18n/locales/en-US.json +18 -18
- package/lighthouse-core/lib/i18n/locales/en-XA.json +18 -0
- package/lighthouse-core/lib/i18n/locales/en-XL.json +18 -18
- package/lighthouse-core/lib/i18n/locales/es-419.json +18 -0
- package/lighthouse-core/lib/i18n/locales/es.json +18 -0
- package/lighthouse-core/lib/i18n/locales/fi.json +18 -0
- package/lighthouse-core/lib/i18n/locales/fil.json +18 -0
- package/lighthouse-core/lib/i18n/locales/fr.json +18 -0
- package/lighthouse-core/lib/i18n/locales/he.json +18 -0
- package/lighthouse-core/lib/i18n/locales/hi.json +18 -0
- package/lighthouse-core/lib/i18n/locales/hr.json +18 -0
- package/lighthouse-core/lib/i18n/locales/hu.json +18 -0
- package/lighthouse-core/lib/i18n/locales/id.json +18 -0
- package/lighthouse-core/lib/i18n/locales/it.json +18 -0
- package/lighthouse-core/lib/i18n/locales/ja.json +18 -0
- package/lighthouse-core/lib/i18n/locales/ko.json +18 -0
- package/lighthouse-core/lib/i18n/locales/lt.json +18 -0
- package/lighthouse-core/lib/i18n/locales/lv.json +18 -0
- package/lighthouse-core/lib/i18n/locales/nl.json +18 -0
- package/lighthouse-core/lib/i18n/locales/no.json +18 -0
- package/lighthouse-core/lib/i18n/locales/pl.json +18 -0
- package/lighthouse-core/lib/i18n/locales/pt-PT.json +18 -0
- package/lighthouse-core/lib/i18n/locales/pt.json +18 -0
- package/lighthouse-core/lib/i18n/locales/ro.json +18 -0
- package/lighthouse-core/lib/i18n/locales/ru.json +18 -0
- package/lighthouse-core/lib/i18n/locales/sk.json +18 -0
- package/lighthouse-core/lib/i18n/locales/sl.json +18 -0
- package/lighthouse-core/lib/i18n/locales/sr-Latn.json +18 -0
- package/lighthouse-core/lib/i18n/locales/sr.json +18 -0
- package/lighthouse-core/lib/i18n/locales/sv.json +18 -0
- package/lighthouse-core/lib/i18n/locales/ta.json +18 -0
- package/lighthouse-core/lib/i18n/locales/te.json +18 -0
- package/lighthouse-core/lib/i18n/locales/th.json +18 -0
- package/lighthouse-core/lib/i18n/locales/tr.json +18 -0
- package/lighthouse-core/lib/i18n/locales/uk.json +18 -0
- package/lighthouse-core/lib/i18n/locales/vi.json +18 -0
- package/lighthouse-core/lib/i18n/locales/zh-HK.json +18 -0
- package/lighthouse-core/lib/i18n/locales/zh-TW.json +18 -0
- package/lighthouse-core/lib/i18n/locales/zh.json +18 -0
- package/lighthouse-core/lib/large-javascript-libraries/bundlephobia-database.json +62 -0
- package/lighthouse-core/lib/large-javascript-libraries/library-suggestions.js +20 -0
- package/lighthouse-core/lib/network-request.js +1 -3
- package/lighthouse-core/lib/traces/pwmetrics-events.js +2 -2
- package/lighthouse-core/lib/url-shim.js +1 -7
- package/lighthouse-core/runner.js +1 -4
- package/lighthouse-core/util-commonjs.js +2 -2
- package/now.json +1 -1
- package/package.json +13 -20
- package/report/README.md +2 -2
- package/report/assets/standalone-template.html +1 -0
- package/report/assets/styles.css +27 -23
- package/report/assets/templates.html +40 -37
- package/report/clients/bundle.js +0 -1
- package/report/{package.json → clients/package.json} +0 -0
- package/report/clients/psi.js +3 -13
- package/report/clients/standalone.js +1 -1
- package/report/{types/buffer.d.ts → clients/treemap.js} +13 -11
- package/report/renderer/category-renderer.js +2 -2
- package/report/renderer/components.js +48 -46
- package/report/renderer/crc-details-renderer.js +16 -16
- package/report/renderer/details-renderer.js +1 -1
- package/report/renderer/dom.js +0 -17
- package/report/renderer/element-screenshot-renderer.js +9 -9
- package/{flow-report/test/setup/global-setup.ts → report/renderer/file-namer.js} +2 -5
- package/report/renderer/logger.js +4 -4
- package/report/renderer/package.json +4 -0
- package/report/renderer/report-renderer.js +11 -4
- package/report/renderer/report-ui-features.js +656 -43
- package/report/renderer/text-encoding.js +1 -1
- package/report/renderer/util.js +2 -2
- package/report/{generator/report-assets.js → report-assets.js} +3 -9
- package/report/{generator/report-generator.js → report-generator.js} +9 -37
- package/report/test/clients/package.json +4 -0
- package/report/test/clients/psi-test.js +1 -3
- package/report/test/renderer/category-renderer-test.js +1 -2
- package/report/test/renderer/components-test.js +0 -35
- package/report/test/renderer/crc-details-renderer-test.js +4 -5
- package/report/test/renderer/details-renderer-test.js +1 -3
- package/report/test/renderer/dom-test.js +6 -8
- package/report/test/renderer/i18n-test.js +0 -1
- package/report/test/renderer/package.json +4 -0
- package/report/test/renderer/performance-category-renderer-test.js +2 -3
- package/report/test/renderer/pwa-category-renderer-test.js +1 -2
- package/report/test/renderer/report-renderer-test.js +0 -1
- package/report/test/renderer/report-ui-features-test.js +18 -20
- package/report/test/renderer/snippet-renderer-test.js +0 -1
- package/report/test/renderer/text-encoding-test.js +0 -2
- package/report/test/renderer/util-test.js +0 -1
- package/report/test/{generator/report-generator-test.js → report-generator-test.js} +2 -4
- package/third-party/chromium-synchronization/installability-errors-test.js +27 -28
- package/third-party/snyk/snapshot.json +0 -2
- package/tsconfig.json +5 -24
- package/types/artifacts.d.ts +18 -5
- package/types/{lhr/audit-details.d.ts → audit-details.d.ts} +3 -18
- package/types/audit.d.ts +58 -7
- package/types/{lhr/budget.d.ts → budget.d.ts} +0 -0
- package/types/bundle-phobia-cli/index.d.ts +40 -0
- package/types/config.d.ts +8 -3
- package/types/externs.d.ts +119 -5
- package/types/gatherer.d.ts +2 -3
- package/types/global-lh.d.ts +14 -16
- package/{report/types/report-result.d.ts → types/html-renderer.d.ts} +17 -8
- package/types/{lhr/i18n.d.ts → i18n.d.ts} +25 -2
- package/types/{lhr/lhr.d.ts → lhr.d.ts} +9 -41
- package/types/smokehouse.d.ts +3 -3
- package/types/{lhr/treemap.d.ts → treemap.d.ts} +3 -3
- package/flow-report/assets/standalone-flow-template.html +0 -38
- package/flow-report/assets/styles.css +0 -310
- package/flow-report/jest.config.js +0 -24
- package/flow-report/src/app.tsx +0 -40
- package/flow-report/src/common.tsx +0 -72
- package/flow-report/src/icons.tsx +0 -96
- package/flow-report/src/sidebar/flow.tsx +0 -72
- package/flow-report/src/sidebar/sidebar.tsx +0 -89
- package/flow-report/src/summary/summary.tsx +0 -178
- package/flow-report/src/util.ts +0 -160
- package/flow-report/src/wrappers/gauge.tsx +0 -40
- package/flow-report/src/wrappers/report-renderer.tsx +0 -46
- package/flow-report/src/wrappers/report.tsx +0 -71
- package/flow-report/standalone-flow.tsx +0 -23
- package/flow-report/test/app-test.tsx +0 -48
- package/flow-report/test/common-test.tsx +0 -131
- package/flow-report/test/setup/env-setup.ts +0 -25
- package/flow-report/test/sidebar/flow-test.tsx +0 -71
- package/flow-report/test/sidebar/sidebar-test.tsx +0 -53
- package/flow-report/test/summary/summary-test.tsx +0 -132
- package/flow-report/test/util-test.tsx +0 -109
- package/flow-report/tsconfig.json +0 -39
- package/flow-report/types/flow-report.d.ts +0 -27
- package/lighthouse-core/audits/lcp-lazy-loaded.js +0 -83
- package/report/.eslintrc.cjs +0 -33
- package/report/generator/README.md +0 -9
- package/report/generator/flow-report-assets.js +0 -20
- package/report/generator/package.json +0 -4
- package/report/generator/tsconfig.json +0 -28
- package/report/renderer/drop-down-menu.js +0 -215
- package/report/renderer/features-util.js +0 -26
- package/report/renderer/open-tab.js +0 -137
- package/report/renderer/topbar-features.js +0 -309
- package/report/test/generator/file-namer-test.js +0 -28
- package/report/test/generator/package.json +0 -4
- package/report/test-assets/faux-psi-template.html +0 -126
- package/report/test-assets/faux-psi.js +0 -92
- package/report/tsconfig.json +0 -39
- package/report/types/augment-dom.d.ts +0 -24
- package/report/types/html-renderer.d.ts +0 -28
- package/types/lhr/audit-result.d.ts +0 -59
- package/types/lhr/flow.d.ts +0 -16
- package/types/lhr/settings.d.ts +0 -105
- package/types/lhr/tsconfig.json +0 -24
- package/types/query-selector.d.ts +0 -36
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"composite": true,
|
|
4
|
-
"outDir": "../.tmp/tsbuildinfo/flow-report",
|
|
5
|
-
"emitDeclarationOnly": false,
|
|
6
|
-
"declarationMap": true,
|
|
7
|
-
|
|
8
|
-
// Limit to base JS and DOM defs.
|
|
9
|
-
"lib": ["es2020", "dom", "dom.iterable"],
|
|
10
|
-
// Selectively include types from node_modules.
|
|
11
|
-
"types": ["node", "jest"],
|
|
12
|
-
"target": "es2020",
|
|
13
|
-
"module": "es2020",
|
|
14
|
-
"moduleResolution": "node",
|
|
15
|
-
"esModuleInterop": true,
|
|
16
|
-
|
|
17
|
-
"allowJs": true,
|
|
18
|
-
"checkJs": true,
|
|
19
|
-
"strict": true,
|
|
20
|
-
// TODO: remove the next line to be fully `strict`.
|
|
21
|
-
"useUnknownInCatchVariables": false,
|
|
22
|
-
|
|
23
|
-
// "listFiles": true,
|
|
24
|
-
// "noErrorTruncation": true,
|
|
25
|
-
"extendedDiagnostics": true,
|
|
26
|
-
|
|
27
|
-
"jsx": "react-jsx",
|
|
28
|
-
"jsxImportSource": "preact",
|
|
29
|
-
},
|
|
30
|
-
"include": [
|
|
31
|
-
"**/*.ts",
|
|
32
|
-
"**/*.tsx",
|
|
33
|
-
"./types",
|
|
34
|
-
],
|
|
35
|
-
"references": [
|
|
36
|
-
{"path": "../types/lhr/"},
|
|
37
|
-
{"path": "../report"},
|
|
38
|
-
],
|
|
39
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
-
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import FlowResult_ from '../../types/lhr/flow';
|
|
8
|
-
import * as Settings from '../../types/lhr/settings';
|
|
9
|
-
|
|
10
|
-
// Import to augment querySelector/querySelectorAll with stricter type checking.
|
|
11
|
-
import '../../types/query-selector';
|
|
12
|
-
import '../../report/types/html-renderer';
|
|
13
|
-
|
|
14
|
-
declare global {
|
|
15
|
-
interface Window {
|
|
16
|
-
__LIGHTHOUSE_FLOW_JSON__: FlowResult_;
|
|
17
|
-
__initLighthouseFlowReport__: () => void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Expose global types in LH namespace.
|
|
21
|
-
module LH {
|
|
22
|
-
export type FlowResult = FlowResult_;
|
|
23
|
-
export type ConfigSettings = Settings.ConfigSettings;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export {};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
-
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
-
*/
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const Audit = require('./audit.js');
|
|
9
|
-
const i18n = require('../lib/i18n/i18n.js');
|
|
10
|
-
|
|
11
|
-
const UIStrings = {
|
|
12
|
-
/** Title of a Lighthouse audit that provides detail on whether the largest above-the-fold image was loaded with sufficient priority. This descriptive title is shown to users when the image was loaded properly. */
|
|
13
|
-
title: 'Largest Contentful Paint image was not lazily loaded',
|
|
14
|
-
/** Title of a Lighthouse audit that provides detail on whether the largest above-the-fold image was loaded with sufficient priority. This descriptive title is shown to users when the image was loaded inefficiently using the `loading=lazy` attribute. */
|
|
15
|
-
failureTitle: 'Largest Contentful Paint image was lazily loaded',
|
|
16
|
-
/** Description of a Lighthouse audit that tells the user why the advice is important. This is displayed after a user expands the section to see more. No character length limits. */
|
|
17
|
-
description: 'Above-the-fold images that are lazily loaded render later in the page lifecycle, which can delay the largest contentful paint. [Learn more](https://web.dev/lcp-lazy-loading/).',
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
|
|
21
|
-
|
|
22
|
-
class LargestContentfulPaintLazyLoaded extends Audit {
|
|
23
|
-
/**
|
|
24
|
-
* @return {LH.Audit.Meta}
|
|
25
|
-
*/
|
|
26
|
-
static get meta() {
|
|
27
|
-
return {
|
|
28
|
-
id: 'lcp-lazy-loaded',
|
|
29
|
-
title: str_(UIStrings.title),
|
|
30
|
-
description: str_(UIStrings.description),
|
|
31
|
-
supportedModes: ['navigation'],
|
|
32
|
-
requiredArtifacts: ['TraceElements', 'ViewportDimensions', 'ImageElements'],
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @param {LH.Artifacts.ImageElement} image
|
|
38
|
-
* @param {LH.Artifacts.ViewportDimensions} viewportDimensions
|
|
39
|
-
* @return {boolean}
|
|
40
|
-
*/
|
|
41
|
-
static isImageInViewport(image, viewportDimensions) {
|
|
42
|
-
const imageTop = image.clientRect.top;
|
|
43
|
-
const viewportHeight = viewportDimensions.innerHeight;
|
|
44
|
-
return imageTop < viewportHeight;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @param {LH.Artifacts} artifacts
|
|
49
|
-
* @return {LH.Audit.Product}
|
|
50
|
-
*/
|
|
51
|
-
static audit(artifacts) {
|
|
52
|
-
const lcpElement = artifacts.TraceElements
|
|
53
|
-
.find(element => element.traceEventType === 'largest-contentful-paint');
|
|
54
|
-
const lcpElementImage = lcpElement ? artifacts.ImageElements.find(elem => {
|
|
55
|
-
return elem.node.devtoolsNodePath === lcpElement.node.devtoolsNodePath;
|
|
56
|
-
}) : undefined;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (!lcpElementImage ||
|
|
60
|
-
!this.isImageInViewport(lcpElementImage, artifacts.ViewportDimensions)) {
|
|
61
|
-
return {score: 1, notApplicable: true};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** @type {LH.Audit.Details.Table['headings']} */
|
|
65
|
-
const headings = [
|
|
66
|
-
{key: 'node', itemType: 'node', text: str_(i18n.UIStrings.columnElement)},
|
|
67
|
-
];
|
|
68
|
-
|
|
69
|
-
const details = Audit.makeTableDetails(headings, [
|
|
70
|
-
{
|
|
71
|
-
node: Audit.makeNodeItem(lcpElementImage.node),
|
|
72
|
-
},
|
|
73
|
-
]);
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
score: lcpElementImage.loading === 'lazy' ? 0 : 1,
|
|
77
|
-
details,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
module.exports = LargestContentfulPaintLazyLoaded;
|
|
83
|
-
module.exports.UIStrings = UIStrings;
|
package/report/.eslintrc.cjs
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
-
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
-
*/
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* eslint does not support ESM rc files, so this must be a .cjs file.
|
|
10
|
-
* @see https://eslint.org/docs/user-guide/configuring/configuration-files#configuration-file-formats
|
|
11
|
-
* @see https://github.com/eslint/eslint/issues/13481
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
module.exports = {
|
|
15
|
-
env: {
|
|
16
|
-
browser: true,
|
|
17
|
-
},
|
|
18
|
-
rules: {
|
|
19
|
-
// TODO(esmodules): move to root eslint when all code is ESM
|
|
20
|
-
// or when this is resolved: https://github.com/import-js/eslint-plugin-import/issues/2214
|
|
21
|
-
'import/order': [2, {
|
|
22
|
-
'groups': [
|
|
23
|
-
'builtin',
|
|
24
|
-
'external',
|
|
25
|
-
['sibling', 'parent'],
|
|
26
|
-
'index',
|
|
27
|
-
'object',
|
|
28
|
-
'type',
|
|
29
|
-
],
|
|
30
|
-
'newlines-between': 'always',
|
|
31
|
-
}],
|
|
32
|
-
},
|
|
33
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# Lighthouse Report Generator
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Lighthouse's report generator is the entry point for creating reports from an **LHR** (Lighthouse Result object). It returns results as HTML, JSON, and CSV.
|
|
6
|
-
|
|
7
|
-
It runs natively in Node.js but can run in the browser after a compile step is applied during our bundling pipeline. That compile step uses `brfs`, which takes any `fs.readFileSync()` calls and replaces them with the stringified file content.
|
|
8
|
-
|
|
9
|
-
Because it's shared between core and the report, dependencies (both code and types) should be kept minimal.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
-
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
-
*/
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
|
|
10
|
-
/* eslint-disable max-len */
|
|
11
|
-
const FLOW_REPORT_TEMPLATE = fs.readFileSync(`${__dirname}/../../flow-report/assets/standalone-flow-template.html`, 'utf8');
|
|
12
|
-
const FLOW_REPORT_CSS = fs.readFileSync(`${__dirname}/../../flow-report/assets/styles.css`, 'utf8');
|
|
13
|
-
const FLOW_REPORT_JAVASCRIPT = fs.readFileSync(`${__dirname}/../../dist/report/flow.js`, 'utf8');
|
|
14
|
-
/* eslint-enable max-len */
|
|
15
|
-
|
|
16
|
-
module.exports = {
|
|
17
|
-
FLOW_REPORT_TEMPLATE,
|
|
18
|
-
FLOW_REPORT_CSS,
|
|
19
|
-
FLOW_REPORT_JAVASCRIPT,
|
|
20
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"composite": true,
|
|
4
|
-
"outDir": "../../.tmp/tsbuildinfo/report/generator",
|
|
5
|
-
"emitDeclarationOnly": true,
|
|
6
|
-
"declarationMap": true,
|
|
7
|
-
|
|
8
|
-
"target": "ES2020",
|
|
9
|
-
"module": "commonjs",
|
|
10
|
-
"moduleResolution": "node",
|
|
11
|
-
|
|
12
|
-
"allowJs": true,
|
|
13
|
-
"checkJs": true,
|
|
14
|
-
"strict": true,
|
|
15
|
-
// TODO: remove the next line to be fully `strict`.
|
|
16
|
-
"useUnknownInCatchVariables": false,
|
|
17
|
-
|
|
18
|
-
// "listFiles": true,
|
|
19
|
-
// "noErrorTruncation": true,
|
|
20
|
-
"extendedDiagnostics": true,
|
|
21
|
-
},
|
|
22
|
-
"references": [
|
|
23
|
-
{"path": "../../types/lhr/"},
|
|
24
|
-
],
|
|
25
|
-
"include": [
|
|
26
|
-
"**/*.js",
|
|
27
|
-
],
|
|
28
|
-
}
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
-
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
-
*/
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
/* eslint-env browser */
|
|
9
|
-
|
|
10
|
-
/** @typedef {import('./dom.js').DOM} DOM */
|
|
11
|
-
|
|
12
|
-
export class DropDownMenu {
|
|
13
|
-
/**
|
|
14
|
-
* @param {DOM} dom
|
|
15
|
-
*/
|
|
16
|
-
constructor(dom) {
|
|
17
|
-
/** @type {DOM} */
|
|
18
|
-
this._dom = dom;
|
|
19
|
-
/** @type {HTMLElement} */
|
|
20
|
-
this._toggleEl; // eslint-disable-line no-unused-expressions
|
|
21
|
-
/** @type {HTMLElement} */
|
|
22
|
-
this._menuEl; // eslint-disable-line no-unused-expressions
|
|
23
|
-
|
|
24
|
-
this.onDocumentKeyDown = this.onDocumentKeyDown.bind(this);
|
|
25
|
-
this.onToggleClick = this.onToggleClick.bind(this);
|
|
26
|
-
this.onToggleKeydown = this.onToggleKeydown.bind(this);
|
|
27
|
-
this.onMenuFocusOut = this.onMenuFocusOut.bind(this);
|
|
28
|
-
this.onMenuKeydown = this.onMenuKeydown.bind(this);
|
|
29
|
-
|
|
30
|
-
this._getNextMenuItem = this._getNextMenuItem.bind(this);
|
|
31
|
-
this._getNextSelectableNode = this._getNextSelectableNode.bind(this);
|
|
32
|
-
this._getPreviousMenuItem = this._getPreviousMenuItem.bind(this);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {function(MouseEvent): any} menuClickHandler
|
|
37
|
-
*/
|
|
38
|
-
setup(menuClickHandler) {
|
|
39
|
-
this._toggleEl = this._dom.find('button.lh-tools__button', this._dom.document());
|
|
40
|
-
this._toggleEl.addEventListener('click', this.onToggleClick);
|
|
41
|
-
this._toggleEl.addEventListener('keydown', this.onToggleKeydown);
|
|
42
|
-
|
|
43
|
-
this._menuEl = this._dom.find('div.lh-tools__dropdown', this._dom.document());
|
|
44
|
-
this._menuEl.addEventListener('keydown', this.onMenuKeydown);
|
|
45
|
-
this._menuEl.addEventListener('click', menuClickHandler);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
close() {
|
|
49
|
-
this._toggleEl.classList.remove('lh-active');
|
|
50
|
-
this._toggleEl.setAttribute('aria-expanded', 'false');
|
|
51
|
-
if (this._menuEl.contains(this._dom.document().activeElement)) {
|
|
52
|
-
// Refocus on the tools button if the drop down last had focus
|
|
53
|
-
this._toggleEl.focus();
|
|
54
|
-
}
|
|
55
|
-
this._menuEl.removeEventListener('focusout', this.onMenuFocusOut);
|
|
56
|
-
this._dom.document().removeEventListener('keydown', this.onDocumentKeyDown);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @param {HTMLElement} firstFocusElement
|
|
61
|
-
*/
|
|
62
|
-
open(firstFocusElement) {
|
|
63
|
-
if (this._toggleEl.classList.contains('lh-active')) {
|
|
64
|
-
// If the drop down is already open focus on the element
|
|
65
|
-
firstFocusElement.focus();
|
|
66
|
-
} else {
|
|
67
|
-
// Wait for drop down transition to complete so options are focusable.
|
|
68
|
-
this._menuEl.addEventListener('transitionend', () => {
|
|
69
|
-
firstFocusElement.focus();
|
|
70
|
-
}, {once: true});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
this._toggleEl.classList.add('lh-active');
|
|
74
|
-
this._toggleEl.setAttribute('aria-expanded', 'true');
|
|
75
|
-
this._menuEl.addEventListener('focusout', this.onMenuFocusOut);
|
|
76
|
-
this._dom.document().addEventListener('keydown', this.onDocumentKeyDown);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Click handler for tools button.
|
|
81
|
-
* @param {Event} e
|
|
82
|
-
*/
|
|
83
|
-
onToggleClick(e) {
|
|
84
|
-
e.preventDefault();
|
|
85
|
-
e.stopImmediatePropagation();
|
|
86
|
-
|
|
87
|
-
if (this._toggleEl.classList.contains('lh-active')) {
|
|
88
|
-
this.close();
|
|
89
|
-
} else {
|
|
90
|
-
this.open(this._getNextMenuItem());
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Handler for tool button.
|
|
96
|
-
* @param {KeyboardEvent} e
|
|
97
|
-
*/
|
|
98
|
-
onToggleKeydown(e) {
|
|
99
|
-
switch (e.code) {
|
|
100
|
-
case 'ArrowUp':
|
|
101
|
-
e.preventDefault();
|
|
102
|
-
this.open(this._getPreviousMenuItem());
|
|
103
|
-
break;
|
|
104
|
-
case 'ArrowDown':
|
|
105
|
-
case 'Enter':
|
|
106
|
-
case ' ':
|
|
107
|
-
e.preventDefault();
|
|
108
|
-
this.open(this._getNextMenuItem());
|
|
109
|
-
break;
|
|
110
|
-
default:
|
|
111
|
-
// no op
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Handler for tool DropDown.
|
|
117
|
-
* @param {KeyboardEvent} e
|
|
118
|
-
*/
|
|
119
|
-
onMenuKeydown(e) {
|
|
120
|
-
const el = /** @type {?HTMLElement} */ (e.target);
|
|
121
|
-
|
|
122
|
-
switch (e.code) {
|
|
123
|
-
case 'ArrowUp':
|
|
124
|
-
e.preventDefault();
|
|
125
|
-
this._getPreviousMenuItem(el).focus();
|
|
126
|
-
break;
|
|
127
|
-
case 'ArrowDown':
|
|
128
|
-
e.preventDefault();
|
|
129
|
-
this._getNextMenuItem(el).focus();
|
|
130
|
-
break;
|
|
131
|
-
case 'Home':
|
|
132
|
-
e.preventDefault();
|
|
133
|
-
this._getNextMenuItem().focus();
|
|
134
|
-
break;
|
|
135
|
-
case 'End':
|
|
136
|
-
e.preventDefault();
|
|
137
|
-
this._getPreviousMenuItem().focus();
|
|
138
|
-
break;
|
|
139
|
-
default:
|
|
140
|
-
// no op
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Keydown handler for the document.
|
|
146
|
-
* @param {KeyboardEvent} e
|
|
147
|
-
*/
|
|
148
|
-
onDocumentKeyDown(e) {
|
|
149
|
-
if (e.keyCode === 27) { // ESC
|
|
150
|
-
this.close();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Focus out handler for the drop down menu.
|
|
156
|
-
* @param {FocusEvent} e
|
|
157
|
-
*/
|
|
158
|
-
onMenuFocusOut(e) {
|
|
159
|
-
const focusedEl = /** @type {?HTMLElement} */ (e.relatedTarget);
|
|
160
|
-
|
|
161
|
-
if (!this._menuEl.contains(focusedEl)) {
|
|
162
|
-
this.close();
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* @param {Array<Node>} allNodes
|
|
168
|
-
* @param {?HTMLElement=} startNode
|
|
169
|
-
* @return {HTMLElement}
|
|
170
|
-
*/
|
|
171
|
-
_getNextSelectableNode(allNodes, startNode) {
|
|
172
|
-
const nodes = allNodes.filter(/** @return {node is HTMLElement} */ (node) => {
|
|
173
|
-
if (!(node instanceof HTMLElement)) {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// 'Save as Gist' option may be disabled.
|
|
178
|
-
if (node.hasAttribute('disabled')) {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// 'Save as Gist' option may have display none.
|
|
183
|
-
if (window.getComputedStyle(node).display === 'none') {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return true;
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
let nextIndex = startNode ? (nodes.indexOf(startNode) + 1) : 0;
|
|
191
|
-
if (nextIndex >= nodes.length) {
|
|
192
|
-
nextIndex = 0;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return nodes[nextIndex];
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* @param {?HTMLElement=} startEl
|
|
200
|
-
* @return {HTMLElement}
|
|
201
|
-
*/
|
|
202
|
-
_getNextMenuItem(startEl) {
|
|
203
|
-
const nodes = Array.from(this._menuEl.childNodes);
|
|
204
|
-
return this._getNextSelectableNode(nodes, startEl);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* @param {?HTMLElement=} startEl
|
|
209
|
-
* @return {HTMLElement}
|
|
210
|
-
*/
|
|
211
|
-
_getPreviousMenuItem(startEl) {
|
|
212
|
-
const nodes = Array.from(this._menuEl.childNodes).reverse();
|
|
213
|
-
return this._getNextSelectableNode(nodes, startEl);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
-
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
-
*/
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
/* eslint-env browser */
|
|
9
|
-
|
|
10
|
-
/** @typedef {import('./dom.js').DOM} DOM */
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @param {DOM} dom
|
|
14
|
-
* @param {boolean} [force]
|
|
15
|
-
*/
|
|
16
|
-
export function toggleDarkTheme(dom, force) {
|
|
17
|
-
const el = dom.find('.lh-vars', dom.document());
|
|
18
|
-
// This seems unnecessary, but in DevTools, passing "undefined" as the second
|
|
19
|
-
// parameter acts like passing "false".
|
|
20
|
-
// https://github.com/ChromeDevTools/devtools-frontend/blob/dd6a6d4153647c2a4203c327c595692c5e0a4256/front_end/dom_extension/DOMExtension.js#L809-L819
|
|
21
|
-
if (typeof force === 'undefined') {
|
|
22
|
-
el.classList.toggle('lh-dark');
|
|
23
|
-
} else {
|
|
24
|
-
el.classList.toggle('lh-dark', force);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2021 The Lighthouse Authors. All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
'use strict';
|
|
18
|
-
|
|
19
|
-
import {TextEncoding} from './text-encoding.js';
|
|
20
|
-
|
|
21
|
-
/* eslint-env browser */
|
|
22
|
-
|
|
23
|
-
function getAppsOrigin() {
|
|
24
|
-
const isVercel = window.location.host.endsWith('.vercel.app');
|
|
25
|
-
const isDev = new URLSearchParams(window.location.search).has('dev');
|
|
26
|
-
|
|
27
|
-
if (isVercel) return `https://${window.location.host}/gh-pages`;
|
|
28
|
-
if (isDev) return 'http://localhost:8000';
|
|
29
|
-
return 'https://googlechrome.github.io/lighthouse';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* The popup's window.name is keyed by version+url+fetchTime, so we reuse/select tabs correctly.
|
|
34
|
-
* @param {LH.Result} json
|
|
35
|
-
* @protected
|
|
36
|
-
*/
|
|
37
|
-
function computeWindowNameSuffix(json) {
|
|
38
|
-
// @ts-expect-error - If this is a v2 LHR, use old `generatedTime`.
|
|
39
|
-
const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
|
|
40
|
-
const fetchTime = json.fetchTime || fallbackFetchTime;
|
|
41
|
-
return `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Opens a new tab to an external page and sends data using postMessage.
|
|
46
|
-
* @param {{lhr: LH.Result} | LH.Treemap.Options} data
|
|
47
|
-
* @param {string} url
|
|
48
|
-
* @param {string} windowName
|
|
49
|
-
* @protected
|
|
50
|
-
*/
|
|
51
|
-
function openTabAndSendData(data, url, windowName) {
|
|
52
|
-
const origin = new URL(url).origin;
|
|
53
|
-
// Chrome doesn't allow us to immediately postMessage to a popup right
|
|
54
|
-
// after it's created. Normally, we could also listen for the popup window's
|
|
55
|
-
// load event, however it is cross-domain and won't fire. Instead, listen
|
|
56
|
-
// for a message from the target app saying "I'm open".
|
|
57
|
-
window.addEventListener('message', function msgHandler(messageEvent) {
|
|
58
|
-
if (messageEvent.origin !== origin) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
if (popup && messageEvent.data.opened) {
|
|
62
|
-
popup.postMessage(data, origin);
|
|
63
|
-
window.removeEventListener('message', msgHandler);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const popup = window.open(url, windowName);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Opens a new tab to an external page and sends data via base64 encoded url params.
|
|
72
|
-
* @param {{lhr: LH.Result} | LH.Treemap.Options} data
|
|
73
|
-
* @param {string} url_
|
|
74
|
-
* @param {string} windowName
|
|
75
|
-
* @protected
|
|
76
|
-
*/
|
|
77
|
-
async function openTabWithUrlData(data, url_, windowName) {
|
|
78
|
-
const url = new URL(url_);
|
|
79
|
-
const gzip = Boolean(window.CompressionStream);
|
|
80
|
-
url.hash = await TextEncoding.toBase64(JSON.stringify(data), {
|
|
81
|
-
gzip,
|
|
82
|
-
});
|
|
83
|
-
if (gzip) url.searchParams.set('gzip', '1');
|
|
84
|
-
window.open(url.toString(), windowName);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Opens a new tab to the online viewer and sends the local page's JSON results
|
|
89
|
-
* to the online viewer using URL.fragment
|
|
90
|
-
* @param {LH.Result} lhr
|
|
91
|
-
* @protected
|
|
92
|
-
*/
|
|
93
|
-
export async function openViewer(lhr) {
|
|
94
|
-
const windowName = 'viewer-' + computeWindowNameSuffix(lhr);
|
|
95
|
-
const url = getAppsOrigin() + '/viewer/';
|
|
96
|
-
await openTabWithUrlData({lhr}, url, windowName);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Same as openViewer, but uses postMessage.
|
|
101
|
-
* @param {LH.Result} lhr
|
|
102
|
-
* @protected
|
|
103
|
-
*/
|
|
104
|
-
export async function openViewerAndSendData(lhr) {
|
|
105
|
-
const windowName = 'viewer-' + computeWindowNameSuffix(lhr);
|
|
106
|
-
const url = getAppsOrigin() + '/viewer/';
|
|
107
|
-
openTabAndSendData({lhr}, url, windowName);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Opens a new tab to the treemap app and sends the JSON results using URL.fragment
|
|
112
|
-
* @param {LH.Result} json
|
|
113
|
-
*/
|
|
114
|
-
export function openTreemap(json) {
|
|
115
|
-
const treemapData = json.audits['script-treemap-data'].details;
|
|
116
|
-
if (!treemapData) {
|
|
117
|
-
throw new Error('no script treemap data found');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** @type {LH.Treemap.Options} */
|
|
121
|
-
const treemapOptions = {
|
|
122
|
-
lhr: {
|
|
123
|
-
requestedUrl: json.requestedUrl,
|
|
124
|
-
finalUrl: json.finalUrl,
|
|
125
|
-
audits: {
|
|
126
|
-
'script-treemap-data': json.audits['script-treemap-data'],
|
|
127
|
-
},
|
|
128
|
-
configSettings: {
|
|
129
|
-
locale: json.configSettings.locale,
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
const url = getAppsOrigin() + '/treemap/';
|
|
134
|
-
const windowName = 'treemap-' + computeWindowNameSuffix(json);
|
|
135
|
-
|
|
136
|
-
openTabWithUrlData(treemapOptions, url, windowName);
|
|
137
|
-
}
|