lighthouse 13.5.0 → 13.6.0-dev.20261027
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/.agents/skills/update-ard-port/SKILL.md +171 -0
- package/.agents/skills/update-trace-engine/SKILL.md +154 -0
- package/cli/bin.d.ts +2 -2
- package/cli/bin.js +5 -4
- package/cli/cli-flags.d.ts +16 -1
- package/cli/cli-flags.js +53 -2
- package/cli/printer.js +5 -8
- package/cli/run.d.ts +5 -5
- package/cli/run.js +97 -47
- package/cli/sentry-prompt.js +3 -4
- package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +1 -1
- package/cli/test/smokehouse/config/exclusions.js +3 -1
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +5 -3
- package/cli/test/smokehouse/report-assert-test.js +65 -0
- package/cli/test/smokehouse/report-assert.js +24 -39
- package/cli/test/smokehouse/smokehouse-test.d.ts +2 -0
- package/cli/test/smokehouse/smokehouse-test.js +120 -0
- package/cli/test/smokehouse/smokehouse.js +37 -15
- package/cli/test/smokehouse/version-check-test.js +5 -0
- package/cli/test/smokehouse/version-check.d.ts +1 -1
- package/cli/test/smokehouse/version-check.js +1 -1
- package/commitlint.config.js +1 -1
- package/core/audits/accessibility/accesskeys.js +1 -1
- package/core/audits/accessibility/aria-allowed-attr.js +1 -1
- package/core/audits/accessibility/aria-allowed-role.js +1 -1
- package/core/audits/accessibility/aria-command-name.js +1 -1
- package/core/audits/accessibility/aria-conditional-attr.js +1 -1
- package/core/audits/accessibility/aria-deprecated-role.js +1 -1
- package/core/audits/accessibility/aria-dialog-name.js +1 -1
- package/core/audits/accessibility/aria-hidden-body.js +1 -1
- package/core/audits/accessibility/aria-hidden-focus.js +1 -1
- package/core/audits/accessibility/aria-input-field-name.js +1 -1
- package/core/audits/accessibility/aria-meter-name.js +1 -1
- package/core/audits/accessibility/aria-progressbar-name.js +1 -1
- package/core/audits/accessibility/aria-prohibited-attr.js +1 -1
- package/core/audits/accessibility/aria-required-attr.js +1 -1
- package/core/audits/accessibility/aria-required-children.js +1 -1
- package/core/audits/accessibility/aria-required-parent.js +1 -1
- package/core/audits/accessibility/aria-roles.js +1 -1
- package/core/audits/accessibility/aria-text.js +1 -1
- package/core/audits/accessibility/aria-toggle-field-name.js +1 -1
- package/core/audits/accessibility/aria-tooltip-name.js +1 -1
- package/core/audits/accessibility/aria-treeitem-name.js +1 -1
- package/core/audits/accessibility/aria-valid-attr-value.js +1 -1
- package/core/audits/accessibility/aria-valid-attr.js +1 -1
- package/core/audits/accessibility/autocomplete-valid.js +1 -1
- package/core/audits/accessibility/button-name.js +1 -1
- package/core/audits/accessibility/bypass.js +1 -1
- package/core/audits/accessibility/color-contrast.js +1 -1
- package/core/audits/accessibility/definition-list.js +1 -1
- package/core/audits/accessibility/dlitem.js +1 -1
- package/core/audits/accessibility/document-title.js +1 -1
- package/core/audits/accessibility/duplicate-id-aria.js +1 -1
- package/core/audits/accessibility/empty-heading.js +1 -1
- package/core/audits/accessibility/form-field-multiple-labels.js +1 -1
- package/core/audits/accessibility/frame-title.js +1 -1
- package/core/audits/accessibility/heading-order.js +1 -1
- package/core/audits/accessibility/html-has-lang.js +1 -1
- package/core/audits/accessibility/html-lang-valid.js +1 -1
- package/core/audits/accessibility/html-xml-lang-mismatch.js +1 -1
- package/core/audits/accessibility/identical-links-same-purpose.js +1 -1
- package/core/audits/accessibility/image-alt.js +1 -1
- package/core/audits/accessibility/image-redundant-alt.js +1 -1
- package/core/audits/accessibility/input-button-name.js +1 -1
- package/core/audits/accessibility/input-image-alt.js +1 -1
- package/core/audits/accessibility/label-content-name-mismatch.js +1 -1
- package/core/audits/accessibility/label.js +1 -1
- package/core/audits/accessibility/landmark-one-main.js +1 -1
- package/core/audits/accessibility/link-in-text-block.js +1 -1
- package/core/audits/accessibility/link-name.js +1 -1
- package/core/audits/accessibility/list.js +1 -1
- package/core/audits/accessibility/listitem.js +1 -1
- package/core/audits/accessibility/meta-refresh.js +1 -1
- package/core/audits/accessibility/meta-viewport.js +1 -1
- package/core/audits/accessibility/object-alt.js +1 -1
- package/core/audits/accessibility/presentation-role-conflict.js +1 -1
- package/core/audits/accessibility/select-name.js +1 -1
- package/core/audits/accessibility/skip-link.js +1 -1
- package/core/audits/accessibility/svg-img-alt.js +1 -1
- package/core/audits/accessibility/tabindex.js +1 -1
- package/core/audits/accessibility/table-duplicate-name.js +1 -1
- package/core/audits/accessibility/table-fake-caption.js +1 -1
- package/core/audits/accessibility/target-size.js +1 -1
- package/core/audits/accessibility/td-has-header.js +1 -1
- package/core/audits/accessibility/td-headers-attr.js +1 -1
- package/core/audits/accessibility/th-has-data-cells.js +1 -1
- package/core/audits/accessibility/valid-lang.js +1 -1
- package/core/audits/accessibility/video-caption.js +1 -1
- package/core/audits/agentic/ard-schema.d.ts +13 -0
- package/core/audits/agentic/ard-schema.js +81 -33
- package/core/audits/agentic/llms-txt.js +5 -2
- package/core/audits/baseline.d.ts +29 -7
- package/core/audits/baseline.js +19 -6
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +2 -2
- package/core/audits/insights/insight-audit.d.ts +9 -0
- package/core/audits/insights/insight-audit.js +35 -28
- package/core/audits/long-tasks.js +2 -1
- package/core/audits/predictive-perf.js +2 -2
- package/core/audits/screenshot-thumbnails.d.ts +0 -13
- package/core/audits/screenshot-thumbnails.js +0 -45
- package/core/audits/script-treemap-data.js +26 -6
- package/core/audits/seo/robots-txt.js +3 -8
- package/core/audits/unsized-images.d.ts +0 -7
- package/core/audits/unsized-images.js +7 -26
- package/core/computed/lcp-image-record.d.ts +2 -23
- package/core/computed/lcp-image-record.js +3 -67
- package/core/computed/lcp-network-record.d.ts +24 -0
- package/core/computed/lcp-network-record.js +74 -0
- package/core/computed/metrics/lantern-metric.js +1 -1
- package/core/computed/metrics/lcp-breakdown.js +6 -6
- package/core/computed/metrics/time-to-first-byte.js +5 -3
- package/core/computed/navigation-insights.js +3 -2
- package/core/computed/page-dependency-graph.js +55 -5
- package/core/computed/speedline.js +20 -5
- package/core/computed/trace-engine-result.js +25 -5
- package/core/computed/unused-css.js +15 -2
- package/core/config/config-helpers.d.ts +5 -0
- package/core/config/config-helpers.js +8 -28
- package/core/config/config.js +1 -2
- package/core/config/constants.d.ts +2 -28
- package/core/config/lr-desktop-config.js +13 -0
- package/core/config/lr-mobile-config.js +13 -0
- package/core/gather/base-artifacts.js +7 -1
- package/core/gather/driver/storage.js +3 -2
- package/core/gather/gatherers/agentic/ard.d.ts +59 -4
- package/core/gather/gatherers/agentic/ard.js +218 -56
- package/core/gather/gatherers/full-page-screenshot.js +2 -2
- package/core/gather/gatherers/image-elements.d.ts +7 -0
- package/core/gather/gatherers/image-elements.js +75 -24
- package/core/gather/gatherers/inspector-issues.js +2 -0
- package/core/gather/gatherers/js-usage.js +2 -0
- package/core/gather/gatherers/scripts.d.ts +16 -3
- package/core/gather/gatherers/scripts.js +157 -14
- package/core/gather/gatherers/stylesheets.js +2 -0
- package/core/gather/gatherers/trace-elements.js +2 -1
- package/core/gather/gatherers/trace.d.ts +6 -0
- package/core/gather/gatherers/trace.js +56 -16
- package/core/lib/arbitrary-equality-map.d.ts +14 -3
- package/core/lib/arbitrary-equality-map.js +113 -6
- package/core/lib/baseline/web-features-data.json +32 -11
- package/core/lib/baseline/web-features-metadata.json +1 -1
- package/core/lib/bf-cache-strings.js +237 -254
- package/core/lib/cdt/Common.d.ts +1 -1
- package/core/lib/cdt/Common.js +2 -2
- package/core/lib/cdt/Platform.d.ts +7 -7
- package/core/lib/cdt/Platform.js +11 -8
- package/core/lib/cdt/SDK.d.ts +5 -1
- package/core/lib/cdt/SDK.js +4 -2
- package/core/lib/cdt/generated/ParsedURL.d.ts +0 -1
- package/core/lib/cdt/generated/ParsedURL.js +3 -9
- package/core/lib/cdt/generated/SourceMap.d.ts +24 -25
- package/core/lib/cdt/generated/SourceMap.js +7 -15
- package/core/lib/deprecations-strings.d.ts +93 -88
- package/core/lib/deprecations-strings.js +20 -14
- package/core/lib/i18n/i18n.d.ts +0 -1
- package/core/lib/i18n/i18n.js +17 -11
- package/core/lib/legacy-javascript/legacy-javascript.d.ts +3 -2
- package/core/lib/legacy-javascript/legacy-javascript.js +235 -111
- package/core/lib/legacy-javascript/polyfill-graph-data.json +94 -89
- package/core/lib/legacy-javascript/polyfill-module-data.json +48 -7
- package/core/lib/minification-estimator.js +10 -10
- package/core/lib/network-request.d.ts +2 -0
- package/core/lib/network-request.js +21 -0
- package/core/lib/page-functions.js +2 -5
- package/core/lib/sentry.d.ts +1 -0
- package/core/lib/sentry.js +3 -0
- package/core/lib/trace-engine.d.ts +1 -0
- package/core/lib/trace-engine.js +2 -0
- package/core/runner.js +9 -3
- package/dist/report/bundle.esm.js +10 -10
- package/dist/report/flow.js +13 -13
- package/dist/report/standalone.js +5 -5
- package/flow-report/src/common.tsx +5 -2
- package/flow-report/src/i18n/i18n.d.ts +2 -0
- package/flow-report/src/summary/summary.tsx +9 -1
- package/flow-report/src/util.d.ts +1 -1
- package/package.json +62 -98
- package/readme.md +13 -18
- package/report/generator/file-namer.d.ts +1 -1
- package/report/generator/file-namer.js +5 -4
- package/report/generator/flow-report-assets.js +1 -3
- package/report/generator/report-assets.js +1 -2
- package/report/renderer/category-renderer.js +2 -2
- package/report/renderer/details-renderer.js +3 -2
- package/report/renderer/dom.d.ts +8 -2
- package/report/renderer/dom.js +29 -1
- package/report/renderer/element-screenshot-renderer.js +3 -0
- package/report/renderer/performance-category-renderer.js +3 -1
- package/report/renderer/report-renderer.js +4 -0
- package/report/renderer/report-utils.d.ts +1 -0
- package/report/renderer/report-utils.js +2 -0
- package/report/renderer/text-encoding.js +2 -2
- package/report/types/augment-dom.d.ts +4 -0
- package/shared/esm-utils.d.ts +0 -8
- package/shared/esm-utils.js +0 -18
- package/shared/localization/format.js +1 -2
- package/shared/localization/locales/ar-XB.json +157 -142
- package/shared/localization/locales/ar.json +157 -142
- package/shared/localization/locales/bg.json +154 -139
- package/shared/localization/locales/ca.json +157 -142
- package/shared/localization/locales/cs.json +148 -133
- package/shared/localization/locales/da.json +153 -138
- package/shared/localization/locales/de.json +152 -137
- package/shared/localization/locales/el.json +153 -138
- package/shared/localization/locales/en-GB.json +160 -145
- package/shared/localization/locales/en-US.json +239 -218
- package/shared/localization/locales/en-XL.json +239 -218
- package/shared/localization/locales/es-419.json +150 -135
- package/shared/localization/locales/es.json +149 -134
- package/shared/localization/locales/fi.json +151 -136
- package/shared/localization/locales/fil.json +154 -139
- package/shared/localization/locales/fr.json +150 -135
- package/shared/localization/locales/he.json +160 -145
- package/shared/localization/locales/hi.json +156 -141
- package/shared/localization/locales/hr.json +154 -139
- package/shared/localization/locales/hu.json +111 -96
- package/shared/localization/locales/id.json +153 -138
- package/shared/localization/locales/it.json +153 -138
- package/shared/localization/locales/ja.json +150 -135
- package/shared/localization/locales/ko.json +42 -27
- package/shared/localization/locales/lt.json +152 -137
- package/shared/localization/locales/lv.json +93 -78
- package/shared/localization/locales/nl.json +149 -134
- package/shared/localization/locales/no.json +152 -137
- package/shared/localization/locales/pl.json +153 -138
- package/shared/localization/locales/pt-PT.json +152 -137
- package/shared/localization/locales/pt.json +157 -142
- package/shared/localization/locales/ro.json +149 -134
- package/shared/localization/locales/ru.json +76 -61
- package/shared/localization/locales/sk.json +153 -138
- package/shared/localization/locales/sl.json +149 -134
- package/shared/localization/locales/sr-Latn.json +151 -136
- package/shared/localization/locales/sr.json +151 -136
- package/shared/localization/locales/sv.json +152 -137
- package/shared/localization/locales/ta.json +156 -141
- package/shared/localization/locales/te.json +157 -142
- package/shared/localization/locales/th.json +111 -96
- package/shared/localization/locales/tr.json +153 -138
- package/shared/localization/locales/uk.json +149 -134
- package/shared/localization/locales/vi.json +162 -147
- package/shared/localization/locales/zh-HK.json +150 -135
- package/shared/localization/locales/zh-TW.json +154 -139
- package/shared/localization/locales/zh.json +152 -137
- package/shared/localization/swap-locale.js +10 -5
- package/shared/root.js +1 -3
- package/third-party/ard/README.md +19 -10
- package/third-party/ard/ard-test.js +189 -266
- package/third-party/ard/ard.d.ts +18 -1
- package/third-party/ard/ard.js +282 -45
- package/third-party/ard/schema-validator.d.ts +14 -5
- package/third-party/ard/schema-validator.js +921 -1177
- package/third-party/ard/spec/schemas/ard-entry.schema.json +176 -0
- package/tsconfig.json +0 -2
- package/types/artifacts.d.ts +43 -7
- package/types/externs.d.ts +4 -0
- package/types/internal/test.d.ts +1 -0
- package/build-tracker.config.js +0 -16
- package/core/lib/cdt/package.json +0 -4
- package/eslint-local-rules.d.cts +0 -9
- package/eslint.config.mjs +0 -242
- package/third-party/ard/spec/schemas/ai-catalog.schema.json +0 -292
- package/third-party/esbuild-plugins-polyfills/LICENSE +0 -3
- package/third-party/esbuild-plugins-polyfills/README.md +0 -7
- package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.d.ts +0 -9
- package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.js +0 -129
- package/types/internal/lookup-closest-locale.d.ts +0 -13
|
@@ -72,6 +72,10 @@ export const UIStrings = {
|
|
|
72
72
|
* @description Translation is not needed, this will never be exposed in production code.
|
|
73
73
|
*/
|
|
74
74
|
ExampleBrowserProcessDeprecation: "This is an example for showing the code required for a browser process reported deprecation.",
|
|
75
|
+
/**
|
|
76
|
+
* @description Warning displayed to developers that they are using the Fenced Frame API which has been deprecated and is scheduled to be removed.
|
|
77
|
+
*/
|
|
78
|
+
FencedFrame: "Fenced Frame API is deprecated and scheduled for removal.",
|
|
75
79
|
/**
|
|
76
80
|
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when one of the Protected Audience APIs like `navigator.joinAdInterestGroup`, `navigator.getInterestGroupAdAuctionData` or `navigator.runAdAuction` are called.
|
|
77
81
|
*/
|
|
@@ -240,6 +244,10 @@ export const UIStrings = {
|
|
|
240
244
|
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when a video conferencing website uses a non-standard API for controlling the crypto method used, but is not having an effect because the desired behavior is already enabled-by-default.
|
|
241
245
|
*/
|
|
242
246
|
RTCConstraintEnableDtlsSrtpTrue: "The constraint `DtlsSrtpKeyAgreement` is removed. You have specified a `true` value for this constraint, which had no effect, but you can remove this constraint for tidiness.",
|
|
247
|
+
/**
|
|
248
|
+
* @description Warning displayed to developers when the non-standard RTCPeerConnection.createDTMFSender() method is used. Developers should use the standard RTCRtpSender.dtmf attribute instead.
|
|
249
|
+
*/
|
|
250
|
+
RTCPeerConnectionCreateDTMFSender: "RTCPeerConnection.createDTMFSender() is deprecated and will be removed. Please use RTCRtpSender.dtmf instead.",
|
|
243
251
|
/**
|
|
244
252
|
* @description WebRTC is set of JavaScript APIs for sending and receiving data, audio and video. getStats() is a method used to obtain network and quality metrics. There are two versions of this method, one is being deprecated because it is non-standard.
|
|
245
253
|
*/
|
|
@@ -252,14 +260,6 @@ export const UIStrings = {
|
|
|
252
260
|
* @description A deprecation warning shown in the DevTools Issues tab. The placeholder is always the noun 'SharedArrayBuffer' which refers to a JavaScript construct.
|
|
253
261
|
*/
|
|
254
262
|
SharedArrayBufferConstructedWithoutIsolation: "`SharedArrayBuffer` will require cross-origin isolation. See https://developer.chrome.com/blog/enabling-shared-array-buffer/ for more details.",
|
|
255
|
-
/**
|
|
256
|
-
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when one of the Shared Storage APIs like `sharedStorage.set()`, `sharedStorage.worklet.addModule()`, `sharedStorage.selectURL()`, etc., along with `<img sharedstoragewritable>`, `<iframe sharedstoragewritable>`, or `fetch(url, {sharedStorageWritable: true})` are used.
|
|
257
|
-
*/
|
|
258
|
-
SharedStorage: "The Shared Storage API is deprecated and will be removed in a future release.",
|
|
259
|
-
/**
|
|
260
|
-
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when the `document.requestStorageAccessFor` API is called. The placeholder will always be the string `document.requestStorageAccessFor`.
|
|
261
|
-
*/
|
|
262
|
-
StorageAccessAPI_requestStorageAccessFor_Method: "`document.requestStorageAccessFor` is deprecated and will be removed. See https://privacysandbox.com/news/update-on-plans-for-privacy-sandbox-technologies/ for more details.",
|
|
263
263
|
/**
|
|
264
264
|
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when the speech synthesis API is called before the page receives a user activation.
|
|
265
265
|
*/
|
|
@@ -276,6 +276,10 @@ export const UIStrings = {
|
|
|
276
276
|
* @description A deprecation warning shown in the DevTools Issues tab. The placeholder is always the noun 'SharedArrayBuffer' which refers to a JavaScript construct. 'Extensions' refers to Chrome extensions. The warning is shown when Chrome Extensions attempt to use 'SharedArrayBuffer's under insecure circumstances.
|
|
277
277
|
*/
|
|
278
278
|
V8SharedArrayBufferConstructedInExtensionWithoutIsolation: "Extensions should opt into cross-origin isolation to continue using `SharedArrayBuffer`. See https://developer.chrome.com/docs/extensions/mv3/cross-origin-isolation/.",
|
|
279
|
+
/**
|
|
280
|
+
* @description Warning displayed to developers when an SVG filter is applied to view transition content, which is disallowed because the content may contain cross-origin iframes or plugins. `::view-transition-old()` and `::view-transition-new()` are CSS pseudo-element names and should not be translated.
|
|
281
|
+
*/
|
|
282
|
+
ViewTransitionPreventSvgFilterPaint: "SVG filters cannot be applied to view transition content, such as `::view-transition-old()` and `::view-transition-new()`, as it may contain cross-origin iframes or plugins.",
|
|
279
283
|
/**
|
|
280
284
|
* @description This warning occurs when the deprecated `BluetoothRemoteGATTCharacteristic.writeValue()` method is used. Developers should use `writeValueWithResponse()` or `writeValueWithoutResponse()` instead.
|
|
281
285
|
*/
|
|
@@ -350,6 +354,10 @@ export const DEPRECATIONS_METADATA = {
|
|
|
350
354
|
"chromeStatusFeature": 5095987863486464,
|
|
351
355
|
"milestone": 151
|
|
352
356
|
},
|
|
357
|
+
"FencedFrame": {
|
|
358
|
+
"chromeStatusFeature": 6366274495053824,
|
|
359
|
+
"milestone": 156
|
|
360
|
+
},
|
|
353
361
|
"IdentityInCanMakePaymentEvent": {
|
|
354
362
|
"chromeStatusFeature": 5190978431352832
|
|
355
363
|
},
|
|
@@ -420,6 +428,10 @@ export const DEPRECATIONS_METADATA = {
|
|
|
420
428
|
"RTCConstraintEnableDtlsSrtpTrue": {
|
|
421
429
|
"milestone": 97
|
|
422
430
|
},
|
|
431
|
+
"RTCPeerConnectionCreateDTMFSender": {
|
|
432
|
+
"chromeStatusFeature": 5160724576993280,
|
|
433
|
+
"milestone": 160
|
|
434
|
+
},
|
|
423
435
|
"RTCPeerConnectionGetStatsLegacyNonCompliant": {
|
|
424
436
|
"chromeStatusFeature": 4631626228695040,
|
|
425
437
|
"milestone": 117
|
|
@@ -437,12 +449,6 @@ export const DEPRECATIONS_METADATA = {
|
|
|
437
449
|
"SharedArrayBufferConstructedWithoutIsolation": {
|
|
438
450
|
"milestone": 106
|
|
439
451
|
},
|
|
440
|
-
"SharedStorage": {
|
|
441
|
-
"chromeStatusFeature": 5076349064708096
|
|
442
|
-
},
|
|
443
|
-
"StorageAccessAPI_requestStorageAccessFor_Method": {
|
|
444
|
-
"chromeStatusFeature": 5162221567082496
|
|
445
|
-
},
|
|
446
452
|
"TextToSpeech_DisallowedByAutoplay": {
|
|
447
453
|
"chromeStatusFeature": 5687444770914304,
|
|
448
454
|
"milestone": 71
|
package/core/lib/i18n/i18n.d.ts
CHANGED
package/core/lib/i18n/i18n.js
CHANGED
|
@@ -4,18 +4,14 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
/** @typedef {import('../../../shared/localization/locales').LhlMessages} LhlMessages */
|
|
8
|
-
|
|
9
7
|
import path from 'path';
|
|
10
8
|
import url from 'url';
|
|
11
9
|
|
|
12
|
-
import lookupClosestLocale from 'lookup-closest-locale';
|
|
13
10
|
import log from 'lighthouse-logger';
|
|
14
11
|
|
|
15
12
|
import {getAvailableLocales} from '../../../shared/localization/format.js';
|
|
16
13
|
import {LH_ROOT} from '../../../shared/root.js';
|
|
17
14
|
import {isIcuMessage, formatMessage, DEFAULT_LOCALE} from '../../../shared/localization/format.js';
|
|
18
|
-
import {getModulePath} from '../../../shared/esm-utils.js';
|
|
19
15
|
|
|
20
16
|
const UIStrings = {
|
|
21
17
|
/** 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) */
|
|
@@ -145,12 +141,22 @@ function lookupLocale(locales, possibleLocales) {
|
|
|
145
141
|
// Filter by what's available in this runtime.
|
|
146
142
|
const availableLocales = Intl.NumberFormat.supportedLocalesOf(canonicalLocales);
|
|
147
143
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
144
|
+
const localesWithMessages = new Set(possibleLocales || getAvailableLocales());
|
|
145
|
+
|
|
146
|
+
/** @type {LH.Locale|undefined} */
|
|
147
|
+
let closestLocale;
|
|
148
|
+
for (const locale of availableLocales) {
|
|
149
|
+
const parts = locale.split('-');
|
|
150
|
+
while (parts.length) {
|
|
151
|
+
const candidate = /** @type {LH.Locale} */ (parts.join('-'));
|
|
152
|
+
if (localesWithMessages.has(candidate)) {
|
|
153
|
+
closestLocale = candidate;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
parts.pop();
|
|
157
|
+
}
|
|
158
|
+
if (closestLocale) break;
|
|
159
|
+
}
|
|
154
160
|
|
|
155
161
|
if (!closestLocale) {
|
|
156
162
|
// Log extra info if we're pretty sure this version of Node was built with `--with-intl=small-icu`.
|
|
@@ -198,7 +204,7 @@ function createIcuMessageFn(filename, fileStrings = {}) {
|
|
|
198
204
|
// one of the common strings found in `i18n.UIStrings`.
|
|
199
205
|
const filenameToLookup = keyname in fileStrings ?
|
|
200
206
|
filename :
|
|
201
|
-
path.relative(LH_ROOT,
|
|
207
|
+
path.relative(LH_ROOT, import.meta.filename);
|
|
202
208
|
const unixStyleFilename = filenameToLookup.replace(/\\/g, '/');
|
|
203
209
|
const i18nId = `${unixStyleFilename} | ${keyname}`;
|
|
204
210
|
|
|
@@ -2,6 +2,7 @@ export type Pattern = {
|
|
|
2
2
|
name: string;
|
|
3
3
|
expression: string;
|
|
4
4
|
estimateBytes?: (content: string) => number;
|
|
5
|
+
resolveName?: (match: string) => string;
|
|
5
6
|
};
|
|
6
7
|
export type PatternMatchResult = {
|
|
7
8
|
name: string;
|
|
@@ -14,10 +15,10 @@ export type Result = {
|
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
17
|
* @param {string} content
|
|
17
|
-
* @param {import('../cdt/generated/SourceMap.js')|null} map
|
|
18
|
+
* @param {import('../cdt/generated/SourceMap.js').default|null} map
|
|
18
19
|
* @return {Result}
|
|
19
20
|
*/
|
|
20
|
-
export function detectLegacyJavaScript(content: string, map: import("../cdt/generated/SourceMap.js") | null): Result;
|
|
21
|
+
export function detectLegacyJavaScript(content: string, map: import("../cdt/generated/SourceMap.js").default | null): Result;
|
|
21
22
|
/**
|
|
22
23
|
* @return {Pattern[]}
|
|
23
24
|
*/
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* ./core/scripts/legacy-javascript - verification tool.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
/** @typedef {{name: string, expression: string, estimateBytes?: (content: string) => number}} Pattern */
|
|
14
|
+
/** @typedef {{name: string, expression: string, estimateBytes?: (content: string) => number, resolveName?: (match: string) => string}} Pattern */
|
|
15
15
|
/** @typedef {{name: string, line: number, column: number}} PatternMatchResult */
|
|
16
16
|
/** @typedef {{matches: PatternMatchResult[], estimatedByteSavings: number}} Result */
|
|
17
17
|
|
|
@@ -27,7 +27,7 @@ const graph = graph_;
|
|
|
27
27
|
/**
|
|
28
28
|
* Takes a list of patterns (consisting of a name identifier and a RegExp expression string)
|
|
29
29
|
* and via `match` returns match results with line / column information for a given code input.
|
|
30
|
-
* Only returns the first match per pattern
|
|
30
|
+
* Only returns the first match per pattern name.
|
|
31
31
|
*/
|
|
32
32
|
class CodePatternMatcher {
|
|
33
33
|
/**
|
|
@@ -45,12 +45,13 @@ class CodePatternMatcher {
|
|
|
45
45
|
if (!this.re) {
|
|
46
46
|
const patternsExpression =
|
|
47
47
|
this.patterns.map(pattern => `(${pattern.expression})`).join('|');
|
|
48
|
-
this.re = new RegExp(
|
|
48
|
+
this.re = new RegExp(patternsExpression, 'g');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// Reset RegExp state.
|
|
52
52
|
this.re.lastIndex = 0;
|
|
53
53
|
|
|
54
|
+
/** @type {Set<string>} */
|
|
54
55
|
const seen = new Set();
|
|
55
56
|
/** @type {PatternMatchResult[]} */
|
|
56
57
|
const matches = [];
|
|
@@ -58,29 +59,41 @@ class CodePatternMatcher {
|
|
|
58
59
|
let result;
|
|
59
60
|
let line = 0;
|
|
60
61
|
let lineBeginsAtIndex = 0;
|
|
62
|
+
let scannedToIndex = 0;
|
|
61
63
|
// Each pattern maps to one subgroup in the generated regex. For each iteration of RegExp.exec,
|
|
62
64
|
// only one subgroup will be defined. Exec until no more matches.
|
|
63
65
|
while ((result = this.re.exec(code)) !== null) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (isNewline) {
|
|
71
|
-
line++;
|
|
72
|
-
lineBeginsAtIndex = result.index + 1;
|
|
73
|
-
continue;
|
|
66
|
+
let patternIndex = -1;
|
|
67
|
+
for (let i = 1; i < result.length; i++) {
|
|
68
|
+
if (result[i] !== undefined) {
|
|
69
|
+
patternIndex = i - 1;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
74
72
|
}
|
|
75
|
-
|
|
73
|
+
if (patternIndex === -1) continue;
|
|
76
74
|
|
|
77
|
-
|
|
75
|
+
const pattern = this.patterns[patternIndex];
|
|
76
|
+
const name = pattern.resolveName ? pattern.resolveName(result[0]) : pattern.name;
|
|
77
|
+
if (seen.has(name)) {
|
|
78
78
|
continue;
|
|
79
79
|
}
|
|
80
|
-
seen.add(
|
|
80
|
+
seen.add(name);
|
|
81
|
+
|
|
82
|
+
// Lazily advance line and column tracking up to `result.index`.
|
|
83
|
+
// Because `[scannedToIndex, result.index)` includes the text of any previous matches,
|
|
84
|
+
// this also accounts for newlines inside multi-line matches.
|
|
85
|
+
// Scanning for `\n` handles both LF (`\n`) and CRLF (`\r\n`) line endings since
|
|
86
|
+
// the next line always begins at `nlIdx + 1`.
|
|
87
|
+
let nlIdx = code.indexOf('\n', scannedToIndex);
|
|
88
|
+
while (nlIdx !== -1 && nlIdx < result.index) {
|
|
89
|
+
line++;
|
|
90
|
+
lineBeginsAtIndex = nlIdx + 1;
|
|
91
|
+
nlIdx = code.indexOf('\n', lineBeginsAtIndex);
|
|
92
|
+
}
|
|
93
|
+
scannedToIndex = result.index;
|
|
81
94
|
|
|
82
95
|
matches.push({
|
|
83
|
-
name
|
|
96
|
+
name,
|
|
84
97
|
line,
|
|
85
98
|
column: result.index - lineBeginsAtIndex,
|
|
86
99
|
});
|
|
@@ -90,70 +103,6 @@ class CodePatternMatcher {
|
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
105
|
|
|
93
|
-
/**
|
|
94
|
-
* @param {string?} object
|
|
95
|
-
* @param {string} property
|
|
96
|
-
* @param {string} coreJs3Module
|
|
97
|
-
*/
|
|
98
|
-
function buildPolyfillExpression(object, property, coreJs3Module) {
|
|
99
|
-
const qt = (/** @type {string} */ token) =>
|
|
100
|
-
`['"]${token}['"]`; // don't worry about matching string delims
|
|
101
|
-
|
|
102
|
-
let expression = '';
|
|
103
|
-
|
|
104
|
-
if (object) {
|
|
105
|
-
// String.prototype.startsWith =
|
|
106
|
-
expression += `${object}\\.${property}\\s?=[^=]`;
|
|
107
|
-
} else {
|
|
108
|
-
// Promise =
|
|
109
|
-
// window.Promise =// Promise =Z
|
|
110
|
-
// but not: SomePromise =
|
|
111
|
-
expression += `(?:window\\.|[\\s;]+)${property}\\s?=[^=]`;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// String.prototype['startsWith'] =
|
|
115
|
-
if (object) {
|
|
116
|
-
expression += `|${object}\\[${qt(property)}\\]\\s?=[^=]`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Object.defineProperty(String.prototype, 'startsWith'
|
|
120
|
-
expression += `|defineProperty\\(${object || 'window'},\\s?${qt(property)}`;
|
|
121
|
-
|
|
122
|
-
// es-shims
|
|
123
|
-
// no(Object,{entries:r},{entries:function
|
|
124
|
-
if (object) {
|
|
125
|
-
expression += `|\\(${object},\\s*{${property}:.*},\\s*{${property}`;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// core-js
|
|
129
|
-
if (object) {
|
|
130
|
-
const objectWithoutPrototype = object.replace('.prototype', '');
|
|
131
|
-
// e(e.S,"Object",{values
|
|
132
|
-
// Minified + mangled pattern found in CDN babel-polyfill.
|
|
133
|
-
// see https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.min.js
|
|
134
|
-
// TODO: perhaps this is the wrong place to check for a CDN polyfill. Remove?
|
|
135
|
-
// expression += `|;e\\([^,]+,${qt(objectWithoutPrototype)},{${property}:`;
|
|
136
|
-
|
|
137
|
-
// core-js@3 minified pattern.
|
|
138
|
-
// {target:"Array",proto:true},{fill:fill
|
|
139
|
-
// {target:"Array",proto:true,forced:!HAS_SPECIES_SUPPORT||!USES_TO_LENGTH},{filter:
|
|
140
|
-
expression += `|{target:${qt(objectWithoutPrototype)}[^;]*},{${property}:`;
|
|
141
|
-
} else {
|
|
142
|
-
// Detect polyfills for new classes: Map, Set, WeakSet, etc.
|
|
143
|
-
// TODO: so far, no class polyfills are enabled for detection.
|
|
144
|
-
// See `modulesToSkip` in create-polyfill-module-data.js
|
|
145
|
-
|
|
146
|
-
// collection("Map",
|
|
147
|
-
// expression += `|collection\\(${qt(property)},`;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Un-minified code may have module names.
|
|
151
|
-
// core-js/modules/es.object.is-frozen
|
|
152
|
-
expression += `|${coreJs3Module.replaceAll('.', '\\.')}(?:\\.js)?"`;
|
|
153
|
-
|
|
154
|
-
return expression;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
106
|
function getCoreJsPolyfillData() {
|
|
158
107
|
return polyfillModuleData.filter(d => d.corejs).map(d => {
|
|
159
108
|
return {
|
|
@@ -164,34 +113,171 @@ function getCoreJsPolyfillData() {
|
|
|
164
113
|
}
|
|
165
114
|
|
|
166
115
|
/**
|
|
116
|
+
* Builds factored polyfill patterns grouped by receiver object, core-js target, and
|
|
117
|
+
* core-js module prefix so the regex engine evaluates a few shared branches instead
|
|
118
|
+
* of repeating common prefixes (like `defineProperty(`, `{target:`, `Array.prototype.`)
|
|
119
|
+
* once per polyfill.
|
|
120
|
+
*
|
|
167
121
|
* @return {Pattern[]}
|
|
168
122
|
*/
|
|
169
123
|
function getPolyfillPatterns() {
|
|
170
|
-
/** @
|
|
171
|
-
const
|
|
124
|
+
/** @param {string} str */
|
|
125
|
+
const escapeRegExp = str => str.replaceAll('.', '\\.');
|
|
126
|
+
|
|
127
|
+
/** @type {Map<string, string[]>} */
|
|
128
|
+
const byObject = new Map();
|
|
129
|
+
/** @type {Map<string, string[]>} */
|
|
130
|
+
const byTarget = new Map();
|
|
131
|
+
/** @type {Map<string, string>} */
|
|
132
|
+
const targetPropToName = new Map();
|
|
133
|
+
/** @type {Map<string, string>} */
|
|
134
|
+
const coreJsModuleToName = new Map();
|
|
135
|
+
/** @type {Map<string, string[]>} */
|
|
136
|
+
const byModulePrefix = new Map();
|
|
172
137
|
|
|
173
138
|
for (const {name, coreJs3Module} of getCoreJsPolyfillData()) {
|
|
174
139
|
const parts = name.split('.');
|
|
175
|
-
const object = parts.
|
|
140
|
+
const object = parts.slice(0, parts.length - 1).join('.');
|
|
176
141
|
const property = parts[parts.length - 1];
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
142
|
+
|
|
143
|
+
let objProps = byObject.get(object);
|
|
144
|
+
if (!objProps) {
|
|
145
|
+
objProps = [];
|
|
146
|
+
byObject.set(object, objProps);
|
|
147
|
+
}
|
|
148
|
+
objProps.push(property);
|
|
149
|
+
|
|
150
|
+
const target = object.replace('.prototype', '');
|
|
151
|
+
let targetProps = byTarget.get(target);
|
|
152
|
+
if (!targetProps) {
|
|
153
|
+
targetProps = [];
|
|
154
|
+
byTarget.set(target, targetProps);
|
|
155
|
+
}
|
|
156
|
+
targetProps.push(property);
|
|
157
|
+
targetPropToName.set(`${target}.${property}`, name);
|
|
158
|
+
|
|
159
|
+
coreJsModuleToName.set(coreJs3Module, name);
|
|
160
|
+
const modParts = coreJs3Module.split('.');
|
|
161
|
+
const modPrefix = modParts.slice(0, 2).join('.');
|
|
162
|
+
const modRest = modParts.slice(2).join('.');
|
|
163
|
+
let modRests = byModulePrefix.get(modPrefix);
|
|
164
|
+
if (!modRests) {
|
|
165
|
+
modRests = [];
|
|
166
|
+
byModulePrefix.set(modPrefix, modRests);
|
|
167
|
+
}
|
|
168
|
+
modRests.push(modRest);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 1. Direct property assignment: `String.prototype.startsWith =`
|
|
172
|
+
const directBranches = [];
|
|
173
|
+
for (const [object, props] of byObject) {
|
|
174
|
+
directBranches.push(`${escapeRegExp(object)}\\.(?:${props.join('|')})\\s?=[^=]`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 2. Bracket property assignment: `String.prototype['startsWith'] =`
|
|
178
|
+
const bracketBranches = [];
|
|
179
|
+
for (const [object, props] of byObject) {
|
|
180
|
+
bracketBranches.push(`${escapeRegExp(object)}\\[['"](?:${props.join('|')})['"]\\]\\s?=[^=]`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// 3. Object.defineProperty: `Object.defineProperty(String.prototype, 'startsWith'`
|
|
184
|
+
const definePropBranches = [];
|
|
185
|
+
for (const [object, props] of byObject) {
|
|
186
|
+
definePropBranches.push(`${escapeRegExp(object)},\\s?['"](?:${props.join('|')})['"]`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 4. es-shims: `no(Object,{entries:r},{entries:function`
|
|
190
|
+
const esShimsBranches = [];
|
|
191
|
+
for (const [object, props] of byObject) {
|
|
192
|
+
const propBranches = props.map(p => `${p}:[^};]*},\\s*{${p}\\b`).join('|');
|
|
193
|
+
esShimsBranches.push(`${escapeRegExp(object)},\\s*{(?:${propBranches})`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 5. core-js@3 minified pattern:
|
|
197
|
+
// `{target:"Array",proto:true},{fill:fill`
|
|
198
|
+
// `{target:"Array",proto:true,forced:!HAS_SPECIES_SUPPORT||!USES_TO_LENGTH},{filter:`
|
|
199
|
+
const targetBranches = [];
|
|
200
|
+
for (const [target, props] of byTarget) {
|
|
201
|
+
targetBranches.push(`['"]${escapeRegExp(target)}['"][^;]*?},{(?:${props.join('|')}):`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// 6. Un-minified core-js module names: `core-js/modules/es.object.is-frozen`
|
|
205
|
+
const moduleBranches = [];
|
|
206
|
+
for (const [prefix, rests] of byModulePrefix) {
|
|
207
|
+
moduleBranches.push(
|
|
208
|
+
`${escapeRegExp(prefix)}\\.(?:${rests.map(escapeRegExp).join('|')})`
|
|
209
|
+
);
|
|
181
210
|
}
|
|
182
211
|
|
|
183
|
-
return
|
|
212
|
+
return [
|
|
213
|
+
{
|
|
214
|
+
name: 'direct-assignment',
|
|
215
|
+
expression: directBranches.join('|'),
|
|
216
|
+
resolveName: match => match.slice(0, match.indexOf('=')).trimEnd(),
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'bracket-assignment',
|
|
220
|
+
expression: bracketBranches.join('|'),
|
|
221
|
+
resolveName: match => {
|
|
222
|
+
const bracketIdx = match.indexOf('[');
|
|
223
|
+
const closeIdx = match.indexOf(']', bracketIdx);
|
|
224
|
+
return `${match.slice(0, bracketIdx)}.${match.slice(bracketIdx + 2, closeIdx - 1)}`;
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
name: 'defineProperty',
|
|
229
|
+
expression: `defineProperty\\((?:${definePropBranches.join('|')})`,
|
|
230
|
+
resolveName: match => {
|
|
231
|
+
const openIdx = match.indexOf('(');
|
|
232
|
+
const commaIdx = match.indexOf(',', openIdx);
|
|
233
|
+
const obj = match.slice(openIdx + 1, commaIdx);
|
|
234
|
+
const prop = match.slice(commaIdx + 1).trimStart().slice(1, -1);
|
|
235
|
+
return `${obj}.${prop}`;
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: 'es-shims',
|
|
240
|
+
expression: `\\((?:${esShimsBranches.join('|')})`,
|
|
241
|
+
resolveName: match => {
|
|
242
|
+
const commaIdx = match.indexOf(',');
|
|
243
|
+
const obj = match.slice(1, commaIdx);
|
|
244
|
+
const braceIdx = match.indexOf('{', commaIdx);
|
|
245
|
+
const colonIdx = match.indexOf(':', braceIdx);
|
|
246
|
+
const prop = match.slice(braceIdx + 1, colonIdx);
|
|
247
|
+
return `${obj}.${prop}`;
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'core-js-target',
|
|
252
|
+
expression: `{target:(?:${targetBranches.join('|')})`,
|
|
253
|
+
resolveName: match => {
|
|
254
|
+
const targetEnd = match.indexOf(match[8], 9);
|
|
255
|
+
const target = match.slice(9, targetEnd);
|
|
256
|
+
const lastBrace = match.lastIndexOf('{');
|
|
257
|
+
const prop = match.slice(lastBrace + 1, -1);
|
|
258
|
+
return /** @type {string} */ (targetPropToName.get(`${target}.${prop}`));
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'core-js-module',
|
|
263
|
+
expression: `(?:${moduleBranches.join('|')})(?:\\.js)?"`,
|
|
264
|
+
resolveName: match => {
|
|
265
|
+
const mod = match.endsWith('.js"') ? match.slice(0, -4) : match.slice(0, -1);
|
|
266
|
+
return /** @type {string} */ (coreJsModuleToName.get(mod));
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
];
|
|
184
270
|
}
|
|
185
271
|
|
|
186
272
|
/**
|
|
187
273
|
* @return {Pattern[]}
|
|
188
274
|
*/
|
|
189
275
|
function getTransformPatterns() {
|
|
190
|
-
/**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
276
|
+
/**
|
|
277
|
+
* @param {string} content
|
|
278
|
+
* @param {RegExp|string} pattern
|
|
279
|
+
* @return {number}
|
|
280
|
+
*/
|
|
195
281
|
const count = (content, pattern) => {
|
|
196
282
|
// Split is slightly faster than match.
|
|
197
283
|
if (typeof pattern === 'string') {
|
|
@@ -259,6 +345,17 @@ function getTransformPatterns() {
|
|
|
259
345
|
];
|
|
260
346
|
}
|
|
261
347
|
|
|
348
|
+
const transformPatterns = getTransformPatterns();
|
|
349
|
+
const transformPatternsByName = new Map(transformPatterns.map(p => [p.name, p]));
|
|
350
|
+
|
|
351
|
+
/** @type {Map<string, string>} */
|
|
352
|
+
const moduleToPolyfillName = new Map();
|
|
353
|
+
for (const {name, modules} of polyfillModuleData) {
|
|
354
|
+
for (const mod of modules) {
|
|
355
|
+
moduleToPolyfillName.set(mod, name);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
262
359
|
/**
|
|
263
360
|
* @param {string} content
|
|
264
361
|
* @param {PatternMatchResult[]} matches
|
|
@@ -287,7 +384,7 @@ function estimateWastedBytes(content, matches) {
|
|
|
287
384
|
let estimatedWastedBytesFromTransforms = 0;
|
|
288
385
|
|
|
289
386
|
for (const result of transformResults) {
|
|
290
|
-
const pattern =
|
|
387
|
+
const pattern = transformPatternsByName.get(result.name);
|
|
291
388
|
if (!pattern || !pattern.estimateBytes || !content) continue;
|
|
292
389
|
estimatedWastedBytesFromTransforms += pattern.estimateBytes(content);
|
|
293
390
|
}
|
|
@@ -299,12 +396,12 @@ function estimateWastedBytes(content, matches) {
|
|
|
299
396
|
|
|
300
397
|
const matcher = new CodePatternMatcher([
|
|
301
398
|
...getPolyfillPatterns(),
|
|
302
|
-
...
|
|
399
|
+
...transformPatterns,
|
|
303
400
|
]);
|
|
304
401
|
|
|
305
402
|
/**
|
|
306
403
|
* @param {string} content
|
|
307
|
-
* @param {import('../cdt/generated/SourceMap.js')|null} map
|
|
404
|
+
* @param {import('../cdt/generated/SourceMap.js').default|null} map
|
|
308
405
|
* @return {Result}
|
|
309
406
|
*/
|
|
310
407
|
function detectLegacyJavaScript(content, map) {
|
|
@@ -315,20 +412,47 @@ function detectLegacyJavaScript(content, map) {
|
|
|
315
412
|
|
|
316
413
|
// If it's a bundle with source maps, add in the polyfill modules by name too.
|
|
317
414
|
if (map) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
415
|
+
const matchedNames = new Set(matches.map(m => m.name));
|
|
416
|
+
/** @type {Array<{name: string, source: string}>} */
|
|
417
|
+
const foundInMap = [];
|
|
418
|
+
|
|
419
|
+
for (const source of map.sourceURLs()) {
|
|
420
|
+
if (source.endsWith('.js')) {
|
|
421
|
+
const slashIdx = source.lastIndexOf('/');
|
|
422
|
+
if (slashIdx !== -1) {
|
|
423
|
+
const polyfillName = moduleToPolyfillName.get(source.slice(slashIdx + 1, -3));
|
|
424
|
+
if (polyfillName && !matchedNames.has(polyfillName)) {
|
|
425
|
+
matchedNames.add(polyfillName);
|
|
426
|
+
foundInMap.push({name: polyfillName, source});
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (source.includes('node_modules/')) {
|
|
431
|
+
let nmIdx = source.indexOf('node_modules/');
|
|
432
|
+
while (nmIdx !== -1) {
|
|
433
|
+
const modStart = nmIdx + 13; // 'node_modules/'.length
|
|
434
|
+
const nextSlash = source.indexOf('/', modStart);
|
|
435
|
+
if (nextSlash !== -1) {
|
|
436
|
+
const polyfillName = moduleToPolyfillName.get(source.slice(modStart, nextSlash));
|
|
437
|
+
if (polyfillName && !matchedNames.has(polyfillName)) {
|
|
438
|
+
matchedNames.add(polyfillName);
|
|
439
|
+
foundInMap.push({name: polyfillName, source});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
nmIdx = source.indexOf('node_modules/', modStart);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (foundInMap.length > 0) {
|
|
448
|
+
const mappings = map.mappings();
|
|
449
|
+
for (const {name, source} of foundInMap) {
|
|
450
|
+
const mapping = mappings.find(m => m.sourceURL === source);
|
|
451
|
+
if (mapping) {
|
|
452
|
+
matches.push({name, line: mapping.lineNumber, column: mapping.columnNumber});
|
|
453
|
+
} else {
|
|
454
|
+
matches.push({name, line: 0, column: 0});
|
|
455
|
+
}
|
|
332
456
|
}
|
|
333
457
|
}
|
|
334
458
|
}
|