chrome-devtools-frontend 1.0.1703574 → 1.0.1705227
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/AUTHORS +2 -0
- package/docs/architecture_of_devtools.md +1 -1
- package/docs/cookbook/localization.md +2 -2
- package/front_end/core/common/ParsedURL.ts +54 -0
- package/front_end/core/common/README.md +4 -3
- package/front_end/core/platform/StringUtilities.ts +65 -0
- package/front_end/core/sdk/CPUThrottlingManager.ts +3 -3
- package/front_end/core/sdk/SourceMap.ts +3 -3
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +4 -3
- package/front_end/core/sdk/SourceMapScopesInfo.ts +17 -5
- package/front_end/entrypoints/formatter_actions/formatter_actions.ts +18 -0
- package/front_end/entrypoints/formatter_worker/Substitute.ts +9 -8
- package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +2 -2
- package/front_end/entrypoints/main/MainImpl.ts +3 -3
- package/front_end/foundation/Universe.ts +9 -0
- package/front_end/generated/InspectorBackendCommands.ts +3 -2
- package/front_end/generated/protocol.ts +16 -0
- package/front_end/models/bindings/CompilerScriptMapping.ts +1 -1
- package/front_end/models/formatter/FormatterWorkerPool.ts +8 -3
- package/front_end/models/har/HARFormat.ts +7 -2
- package/front_end/models/source_map_scopes/NamesResolver.ts +75 -38
- package/front_end/models/source_map_scopes/ScopeChainModel.ts +13 -45
- package/front_end/models/source_map_scopes/ScopeChainResolver.ts +101 -0
- package/front_end/models/source_map_scopes/source_map_scopes.ts +2 -0
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingListView.ts +33 -1
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +4 -12
- package/front_end/panels/application/ApplicationPanelSidebar.ts +58 -60
- package/front_end/panels/application/BackForwardCacheTreeElement.ts +1 -1
- package/front_end/panels/application/FrameDetailsView.ts +64 -82
- package/front_end/panels/application/OpenedWindowDetailsView.ts +20 -21
- package/front_end/panels/application/PreloadingTreeElement.ts +3 -3
- package/front_end/panels/common/CommentsOverlayWidget.ts +145 -72
- package/front_end/panels/common/commentsOverlay.css +34 -23
- package/front_end/panels/console/ConsolePrompt.ts +2 -1
- package/front_end/panels/elements/DOMTreeWidget.ts +29 -10
- package/front_end/panels/network/RequestPayloadView.ts +7 -2
- package/front_end/panels/network/ShowMoreDetailsWidget.ts +12 -9
- package/front_end/panels/sources/DebuggerPlugin.ts +52 -20
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +2 -2
- package/front_end/panels/sources/SourcesPanel.ts +1 -1
- package/front_end/panels/sources/SourcesView.ts +3 -12
- package/front_end/panels/sources/TabbedEditorContainer.ts +0 -3
- package/front_end/panels/sources/components/HeadersView.ts +193 -123
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +5 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +24 -32
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/ElementHandle.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/ElementHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/ElementHandle.js +15 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js +8 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts +0 -8
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js +0 -24
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts +12 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +79 -17
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node-env-setup.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node-env-setup.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +5 -0
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/api/ElementHandle.ts +15 -2
- package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +10 -1
- package/front_end/third_party/puppeteer/package/src/common/Debug.ts +0 -27
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +96 -17
- package/front_end/third_party/puppeteer/package/src/node-env-setup.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/comments/CommentAnchorResolver.ts +60 -22
- package/front_end/ui/comments/CommentOverlayManager.ts +78 -25
- package/front_end/ui/legacy/README.md +12 -12
- package/front_end/ui/legacy/components/data_grid/DataGridExporter.ts +7 -13
- package/front_end/ui/legacy/components/inline_editor/PositionAreaEditor.ts +51 -57
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +101 -42
- package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +7 -0
- package/package.json +1 -1
package/AUTHORS
CHANGED
|
@@ -99,6 +99,7 @@ Ryuhei Shima <shimaryuhei@gmail.com>
|
|
|
99
99
|
Samuel Maddock <samuelmaddock@electronjs.org>
|
|
100
100
|
Satvic Dhawan <satvicdhawan14@gmail.com>
|
|
101
101
|
Sebastian Markbåge <sebastian@calyptus.eu>
|
|
102
|
+
Semih Dogan <semih702do@gmail.com>
|
|
102
103
|
Serg Kryvonos <sergeikrivonos@gmail.com>
|
|
103
104
|
Sergio Avalos <sergio.avalos@gmail.com>
|
|
104
105
|
Shelley Vohr <shelley.vohr@gmail.com>
|
|
@@ -123,6 +124,7 @@ Yoichiro Hibara <hibarayoichiro871@gmail.com>
|
|
|
123
124
|
Yoni Feigelson <yfeigelson@gmail.com>
|
|
124
125
|
Young Min Kim <y@ylem.kim>
|
|
125
126
|
Yuan Zhuang <joann.yuanzhuang@gmail.com>
|
|
127
|
+
Zeeshan Ahmad <zeeshanahmad125114@gmail.com>
|
|
126
128
|
Zuyao Chen <zuyaocat@gmail.com>
|
|
127
129
|
# Please DO NOT APPEND here. See comments at the top of the file.
|
|
128
130
|
# END individuals section.
|
|
@@ -121,7 +121,7 @@ There are multiple variants of the DevTools application.
|
|
|
121
121
|
The main DevTools application is [devtools_app.ts](../front_end/entrypoints/devtools_app/devtools_app.ts), which developers can open via F12 or "Right click -> Inspect element" in their Chromium browser.
|
|
122
122
|
Other application entrypoints are a dedicated tool for debugging Node on which multiple targets can be inspected ([node_app.ts](../front_end/entrypoints/node_app/node_app.ts)), a non-browser context debugger for V8 targets ([js_app.ts](../front_end/entrypoints/js_app/js_app.ts)), a (service) worker context ([worker_app.ts](../front_end/entrypoints/worker_app/worker_app.ts)), remote debugging of (Android) devices ([inspector.ts](../front_end/entrypoints/inspector/inspector.ts)) and a basic version of DevTools which was initially intended for non-browser targets but doesn't have any particular use case that differentiates it from the other variants ([ndb_app.ts](../front_end/entrypoints/ndb_app/ndb_app.ts)).
|
|
123
123
|
|
|
124
|
-
Each application entrypoint has a corresponding `.html` file with the same name, that is automatically in the frontend
|
|
124
|
+
Each application entrypoint has a corresponding `.html` file with the same name, that is automatically generated in the frontend and can be loaded by the Chromium DevTools backend.
|
|
125
125
|
The JavaScript files import the relevant "meta" files containing the declarations of DevTools features.
|
|
126
126
|
|
|
127
127
|
## Upfront declaration of DevTools features
|
|
@@ -286,8 +286,8 @@ const UIStrings = {
|
|
|
286
286
|
|
|
287
287
|
## How to prevent a term being localized
|
|
288
288
|
|
|
289
|
-
Any text within the backticks will not be translated. For example,
|
|
290
|
-
'robots.txt' in string 'Requesting for robots.txt …' should not be translated:
|
|
289
|
+
Any text within the backticks will not be translated. For example,
|
|
290
|
+
'robots.txt' in the string 'Requesting for robots.txt …' should not be translated:
|
|
291
291
|
|
|
292
292
|
```ts
|
|
293
293
|
// in example.js file
|
|
@@ -46,6 +46,60 @@ export function schemeIs(url: Platform.DevToolsPath.UrlString|URL, scheme: strin
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Schemes safe for unprivileged web contexts (matching ChildProcessSecurityPolicyImpl::RegisterDefaultSchemes).
|
|
51
|
+
*/
|
|
52
|
+
const WEB_SAFE_SCHEMES = new Set([
|
|
53
|
+
'http:',
|
|
54
|
+
'https:',
|
|
55
|
+
'ws:',
|
|
56
|
+
'wss:',
|
|
57
|
+
'data:',
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns true if the URL uses an unprivileged web-safe scheme (or is a `blob:` URL wrapping one).
|
|
62
|
+
*/
|
|
63
|
+
export function hasWebSafeScheme(url: Platform.DevToolsPath.UrlString|URL|string): boolean {
|
|
64
|
+
try {
|
|
65
|
+
const parsed = new URL(url);
|
|
66
|
+
if (parsed.protocol === 'blob:') {
|
|
67
|
+
return hasWebSafeScheme(parsed.pathname);
|
|
68
|
+
}
|
|
69
|
+
return WEB_SAFE_SCHEMES.has(parsed.protocol);
|
|
70
|
+
} catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Privileged browser and local schemes that must not be opened via external/new-tab links by default.
|
|
77
|
+
*/
|
|
78
|
+
const PRIVILEGED_SCHEMES = new Set([
|
|
79
|
+
'chrome:',
|
|
80
|
+
'chrome-extension:',
|
|
81
|
+
'chrome-search:',
|
|
82
|
+
'chrome-untrusted:',
|
|
83
|
+
'devtools:',
|
|
84
|
+
'file:',
|
|
85
|
+
'isolated-app:',
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns true if the URL uses a privileged scheme (or is a `blob:` URL wrapping one).
|
|
90
|
+
*/
|
|
91
|
+
export function isPrivilegedScheme(url: Platform.DevToolsPath.UrlString|URL|string): boolean {
|
|
92
|
+
try {
|
|
93
|
+
const parsed = new URL(url);
|
|
94
|
+
if (parsed.protocol === 'blob:') {
|
|
95
|
+
return isPrivilegedScheme(parsed.pathname);
|
|
96
|
+
}
|
|
97
|
+
return PRIVILEGED_SCHEMES.has(parsed.protocol);
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
49
103
|
/**
|
|
50
104
|
* File paths in DevTools that are represented either as unencoded absolute or relative paths, or encoded paths, or URLs.
|
|
51
105
|
* @example
|
|
@@ -6,14 +6,15 @@ A settings registration is represented by the `SettingRegistration` interface, d
|
|
|
6
6
|
|
|
7
7
|
All settings have to be registered using the function `Common.Settings.registerSettingExtension` which expects an object of type `SettingRegistration` as parameter.
|
|
8
8
|
|
|
9
|
-
As an example, take the registration of the `
|
|
9
|
+
As an example, take the registration of the `show-html-comments` setting, which allows users to determine if HTML comments are shown in the Elements tree:
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
Common.Settings.registerSettingExtension({
|
|
13
13
|
category: Common.Settings.SettingCategory.ELEMENTS,
|
|
14
|
+
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
14
15
|
order: 3,
|
|
15
|
-
title: ls`
|
|
16
|
-
settingName: '
|
|
16
|
+
title: ls`HTML comments`,
|
|
17
|
+
settingName: 'show-html-comments',
|
|
17
18
|
settingType: Common.Settings.SettingType.BOOLEAN,
|
|
18
19
|
defaultValue: true,
|
|
19
20
|
options: [
|
|
@@ -740,3 +740,68 @@ export const concatBase64 = function(lhs: string, rhs: string): string {
|
|
|
740
740
|
const lhsToDecode = lhs.substring(lhs.length - 4);
|
|
741
741
|
return lhsLeaveAsIs + globalThis.btoa(globalThis.atob(lhsToDecode) + globalThis.atob(rhs));
|
|
742
742
|
};
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Characters that cause spreadsheet viewers (Excel, Google Sheets, LibreOffice
|
|
746
|
+
* Calc) to evaluate a cell as a formula rather than rendering it as plain text
|
|
747
|
+
* when they appear at the start of a cell.
|
|
748
|
+
*/
|
|
749
|
+
const CSV_FORMULA_TRIGGERS = new Set(['=', '+', '-', '@', '\t', '\r']);
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Matches plain numeric literals (e.g. `-42`, `+3.14`, `-1e-3`).
|
|
753
|
+
* Even though negative/signed numbers start with `-` or `+`, spreadsheets parse
|
|
754
|
+
* them as numbers rather than formulas, so we exempt them from `'` prefixing to
|
|
755
|
+
* keep numeric columns usable.
|
|
756
|
+
*/
|
|
757
|
+
const CSV_PLAIN_NUMBER = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Returns true if a spreadsheet viewer could interpret `value` as a formula
|
|
761
|
+
* (for example `=SUM(A1:A2)`, `"- Loading..."`, or `"@alice"`).
|
|
762
|
+
*/
|
|
763
|
+
function isCsvFormula(value: string): boolean {
|
|
764
|
+
// Check both the raw string and the leading-whitespace-trimmed string, since
|
|
765
|
+
// some spreadsheet parsers ignore leading spaces before `=`, `+`, `-`, or `@`.
|
|
766
|
+
const trimmed = value.trimStart();
|
|
767
|
+
if (!CSV_FORMULA_TRIGGERS.has(value[0]) && !CSV_FORMULA_TRIGGERS.has(trimmed[0])) {
|
|
768
|
+
return false;
|
|
769
|
+
}
|
|
770
|
+
return !CSV_PLAIN_NUMBER.test(trimmed.trimEnd());
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* Formats and escapes `value` so it can be safely written as a single CSV cell.
|
|
775
|
+
*
|
|
776
|
+
* This handles two separate layers of escaping:
|
|
777
|
+
* 1. Spreadsheet formula escaping (CWE-1236 & viewer fidelity):
|
|
778
|
+
* RFC 4180 double-quoting (`"=1+1"` or `"- Loading..."`) only groups text
|
|
779
|
+
* into a single CSV column; spreadsheet apps strip the outer `"` and still
|
|
780
|
+
* evaluate cells starting with `=`, `+`, `-`, or `@` as formulas (often
|
|
781
|
+
* resulting in `#NAME?` errors or unintended formula execution). Prefixing
|
|
782
|
+
* the value with a single quote (`'`) tells spreadsheet apps to treat the
|
|
783
|
+
* cell as literal text (and they hide the leading `'` when displaying it).
|
|
784
|
+
* - Example without commas: `=SUM(A1:A2)` -> `'=SUM(A1:A2)`
|
|
785
|
+
* 2. RFC 4180 structural CSV quoting:
|
|
786
|
+
* If the cell also contains commas (`,`), double quotes (`"`), or newlines,
|
|
787
|
+
* it is wrapped in `"..."` (with inner `"` doubled to `""`) so CSV parsers
|
|
788
|
+
* do not split the cell across columns or rows.
|
|
789
|
+
* - Example with commas: `=SUM(1,2)` -> `"'=SUM(1,2)"`
|
|
790
|
+
* - Example starting with a literal quote: `"=SUM(1,2)"` -> `"""=SUM(1,2)"""`
|
|
791
|
+
* (not treated as a formula since the first character is `"`, not `=`).
|
|
792
|
+
*/
|
|
793
|
+
export const escapeCsvCell = function(value: string): string {
|
|
794
|
+
// Step 1: Prefix formula-like text with `'` so spreadsheets render it as literal text.
|
|
795
|
+
let escaped = isCsvFormula(value) ? `'${value}` : value;
|
|
796
|
+
|
|
797
|
+
// Step 2: Apply standard RFC 4180 double-quoting if the cell contains quotes,
|
|
798
|
+
// commas, or line breaks so the CSV structure stays intact.
|
|
799
|
+
if (escaped.includes('"')) {
|
|
800
|
+
escaped = escaped.replace(/"/g, '""');
|
|
801
|
+
return `"${escaped}"`;
|
|
802
|
+
}
|
|
803
|
+
if (escaped.includes(',') || escaped.includes('\n') || escaped.includes('\r')) {
|
|
804
|
+
return `"${escaped}"`;
|
|
805
|
+
}
|
|
806
|
+
return escaped;
|
|
807
|
+
};
|
|
@@ -282,9 +282,9 @@ export class CPUThrottlingManager extends Common.ObjectWrapper.ObjectWrapper<Eve
|
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
async updateHostDefaultCPUPerformanceTier(): Promise<void> {
|
|
285
|
-
if (this.#
|
|
286
|
-
// We do not want to update the host default tier when it is
|
|
287
|
-
//
|
|
285
|
+
if (this.#isCPUPerformanceOverrideActive()) {
|
|
286
|
+
// We do not want to update the host default tier when it is overridden
|
|
287
|
+
// (in which case, `navigator.cpuPerformance` would return the override).
|
|
288
288
|
return;
|
|
289
289
|
}
|
|
290
290
|
const target = this.#targetManager.primaryPageTarget();
|
|
@@ -12,7 +12,7 @@ import {scopeTreeForScript} from './ScopeTreeCache.js';
|
|
|
12
12
|
import type {Script} from './Script.js';
|
|
13
13
|
import {buildOriginalScopes, decodePastaRanges, type NamedFunctionRange} from './SourceMapFunctionRanges.js';
|
|
14
14
|
import {decodeRangeMappings} from './SourceMapRangeMappings.js';
|
|
15
|
-
import {SourceMapScopesInfo, type TranslatedFrame} from './SourceMapScopesInfo.js';
|
|
15
|
+
import {scriptRelativePosition, SourceMapScopesInfo, type TranslatedFrame} from './SourceMapScopesInfo.js';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Type of the base source map JSON object, which contains the sources and the mappings at the very least, plus
|
|
@@ -850,8 +850,8 @@ export class SourceMap {
|
|
|
850
850
|
return null;
|
|
851
851
|
}
|
|
852
852
|
|
|
853
|
-
|
|
854
|
-
|
|
853
|
+
const {line, column} = scriptRelativePosition(location);
|
|
854
|
+
return this.#scopesInfo.resolveMappedVariablesAtPosition(line, column, ignoreInnerBlockScopes);
|
|
855
855
|
}
|
|
856
856
|
|
|
857
857
|
findOriginalFunctionName(position: ScopesCodec.Position): string|null {
|
|
@@ -8,7 +8,7 @@ import * as i18n from '../i18n/i18n.js';
|
|
|
8
8
|
|
|
9
9
|
import type {CallFrame, LocationRange, ScopeChainEntry} from './DebuggerModel.js';
|
|
10
10
|
import {type GetPropertiesResult, type RemoteObject, RemoteObjectImpl, RemoteObjectProperty} from './RemoteObject.js';
|
|
11
|
-
import {findExpression} from './SourceMapScopesInfo.js';
|
|
11
|
+
import {findExpression, scriptRelativePosition} from './SourceMapScopesInfo.js';
|
|
12
12
|
|
|
13
13
|
const UIStrings = {
|
|
14
14
|
/**
|
|
@@ -263,8 +263,9 @@ class SourceMapScopeRemoteObject extends RemoteObjectImpl {
|
|
|
263
263
|
|
|
264
264
|
/** @returns null if the variable is unavailable at the current paused location */
|
|
265
265
|
#findExpression(index: number): string|null {
|
|
266
|
-
const
|
|
267
|
-
|
|
266
|
+
const pausedLocation = this.#callFrame.location();
|
|
267
|
+
const pausedPosition = pausedLocation ? scriptRelativePosition(pausedLocation) : undefined;
|
|
268
|
+
return findExpression(this.#range, index, pausedPosition?.line, pausedPosition?.column);
|
|
268
269
|
}
|
|
269
270
|
|
|
270
271
|
static #unavailableProperty(name: string): RemoteObjectProperty {
|
|
@@ -8,7 +8,7 @@ import type * as ScopesCodec from '../../third_party/source-map-scopes-codec/sou
|
|
|
8
8
|
import type * as Platform from '../platform/platform.js';
|
|
9
9
|
import type * as TextUtils from '../text_utils/text_utils.js';
|
|
10
10
|
|
|
11
|
-
import type {CallFrame, Scope, ScopeChainEntry} from './DebuggerModel.js';
|
|
11
|
+
import type {CallFrame, Location, Scope, ScopeChainEntry} from './DebuggerModel.js';
|
|
12
12
|
import type {SourceMap} from './SourceMap.js';
|
|
13
13
|
import {SourceMapScopeChainEntry} from './SourceMapScopeChainEntry.js';
|
|
14
14
|
|
|
@@ -389,8 +389,8 @@ export class SourceMapScopesInfo {
|
|
|
389
389
|
|
|
390
390
|
/** Similar to #findGeneratedRangeChain, but takes inlineFrameIndex of virtual call frames into account */
|
|
391
391
|
#findGeneratedRangeChainForFrame(callFrame: CallFrame): ScopesCodec.GeneratedRange[] {
|
|
392
|
-
const
|
|
393
|
-
|
|
392
|
+
const {line, column} = scriptRelativePosition(callFrame.location());
|
|
393
|
+
const rangeChain = this.#findGeneratedRangeChain(line, column);
|
|
394
394
|
if (callFrame.inlineFrameIndex === 0) {
|
|
395
395
|
return rangeChain;
|
|
396
396
|
}
|
|
@@ -611,6 +611,18 @@ export function comparePositions(a: ScopesCodec.Position, b: ScopesCodec.Positio
|
|
|
611
611
|
return a.column - b.column;
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
+
/**
|
|
615
|
+
* Converts a raw V8 {@link location} into a generated position relative to the start of its script.
|
|
616
|
+
*
|
|
617
|
+
* Positions in source maps (mappings and generated ranges) are relative to the start of the script,
|
|
618
|
+
* while V8 reports locations in inline `<script>`s (without `//# sourceURL`) relative to the start of
|
|
619
|
+
* the surrounding document.
|
|
620
|
+
*/
|
|
621
|
+
export function scriptRelativePosition(location: Location): ScopesCodec.Position {
|
|
622
|
+
const {lineNumber, columnNumber} = location.script()?.rawLocationToRelativeLocation(location) ?? location;
|
|
623
|
+
return {line: lineNumber, column: columnNumber};
|
|
624
|
+
}
|
|
625
|
+
|
|
614
626
|
function positionRange(callFrame: CallFrame, scope: Scope): {start: ScopesCodec.Position, end: ScopesCodec.Position}|
|
|
615
627
|
null {
|
|
616
628
|
const range = scope.range();
|
|
@@ -619,8 +631,8 @@ function positionRange(callFrame: CallFrame, scope: Scope): {start: ScopesCodec.
|
|
|
619
631
|
return null;
|
|
620
632
|
}
|
|
621
633
|
return {
|
|
622
|
-
start:
|
|
623
|
-
end:
|
|
634
|
+
start: scriptRelativePosition(range.start),
|
|
635
|
+
end: scriptRelativePosition(range.end),
|
|
624
636
|
};
|
|
625
637
|
}
|
|
626
638
|
|
|
@@ -51,6 +51,24 @@ export const enum ScopeKind {
|
|
|
51
51
|
ARROW_FUNCTION = 4,
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Describes a single scope for `javaScriptSubstitute`.
|
|
56
|
+
*/
|
|
57
|
+
export interface ScopeVariableMapping {
|
|
58
|
+
/**
|
|
59
|
+
* Authored variable name -> generated binding expression, or `null` if the variable is unavailable.
|
|
60
|
+
*/
|
|
61
|
+
bindings: Map<string, string|null>;
|
|
62
|
+
/**
|
|
63
|
+
* Generated identifiers declared by this scope. Together with the free identifiers of `bindings`, these
|
|
64
|
+
* shadow bindings of outer scopes that refer to the same generated identifiers.
|
|
65
|
+
*
|
|
66
|
+
* This is needed when a generated identifier doesn't show up in any binding expression, e.g. because
|
|
67
|
+
* multiple generated identifiers map to the same authored name, or the authored name is unknown.
|
|
68
|
+
*/
|
|
69
|
+
generatedNames: string[];
|
|
70
|
+
}
|
|
71
|
+
|
|
54
72
|
export interface ScopeTreeNode {
|
|
55
73
|
variables: Array<{name: string, kind: DefinitionKind, offsets: number[]}>;
|
|
56
74
|
start: number;
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Acorn from '../../third_party/acorn/acorn.js';
|
|
6
|
-
import {DefinitionKind} from '../formatter_actions/formatter_actions.js';
|
|
6
|
+
import {DefinitionKind, type ScopeVariableMapping} from '../formatter_actions/formatter_actions.js';
|
|
7
7
|
|
|
8
8
|
import {ECMA_VERSION} from './AcornTokenizer.js';
|
|
9
9
|
import {ScopeVariableAnalysis, type VariableUses} from './ScopeParser.js';
|
|
10
10
|
|
|
11
|
-
export function substituteExpression(expression: string,
|
|
12
|
-
const replacements = computeSubstitution(expression,
|
|
11
|
+
export function substituteExpression(expression: string, scopes: ScopeVariableMapping[]): string {
|
|
12
|
+
const replacements = computeSubstitution(expression, scopes);
|
|
13
13
|
return applySubstitution(expression, replacements);
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -52,12 +52,12 @@ function parseBindingExpression(expression: string): {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* Given an |expression| and a
|
|
55
|
+
* Given an |expression| and a list of |scopes| (from inner-most to outer-most), the |computeSubstitution|
|
|
56
56
|
* function returns a list of replacements sorted by the offset. The function throws if
|
|
57
57
|
* it cannot parse the expression or the substitution is impossible to perform (for example
|
|
58
58
|
* if the substitution target is 'this' within a function, it would become bound there).
|
|
59
59
|
**/
|
|
60
|
-
function computeSubstitution(expression: string,
|
|
60
|
+
function computeSubstitution(expression: string, scopes: ScopeVariableMapping[]): Replacement[] {
|
|
61
61
|
// Parse the expression and find variables and scopes.
|
|
62
62
|
const root = Acorn.parse(expression, {
|
|
63
63
|
ecmaVersion: ECMA_VERSION,
|
|
@@ -75,10 +75,11 @@ function computeSubstitution(expression: string, nameMaps: Array<Map<string, str
|
|
|
75
75
|
const allNames = scopeVariables.getAllNames();
|
|
76
76
|
const nameMap = new Map<string, string|null>();
|
|
77
77
|
const parsedBindings = new Map<string, ReturnType<typeof parseBindingExpression>>();
|
|
78
|
+
// Generated identifiers declared by the scopes visited so far. Outer bindings referring to them are shadowed.
|
|
78
79
|
const shadowedNames = new Set<string>();
|
|
79
|
-
for (const
|
|
80
|
-
const scopeNames = new Set<string>();
|
|
81
|
-
for (const [name, rename] of
|
|
80
|
+
for (const {bindings, generatedNames} of scopes) {
|
|
81
|
+
const scopeNames = new Set<string>(generatedNames);
|
|
82
|
+
for (const [name, rename] of bindings.entries()) {
|
|
82
83
|
let parsed: ReturnType<typeof parseBindingExpression>|undefined;
|
|
83
84
|
if (rename !== null) {
|
|
84
85
|
try {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Platform from '../../core/platform/platform.js';
|
|
6
|
-
import {FormatterActions} from '../formatter_actions/formatter_actions.js';
|
|
6
|
+
import {FormatterActions, type ScopeVariableMapping} from '../formatter_actions/formatter_actions.js';
|
|
7
7
|
|
|
8
8
|
import * as FormatterWorker from './formatter_worker.js';
|
|
9
9
|
|
|
@@ -13,7 +13,7 @@ Platform.HostRuntime.HOST_RUNTIME.workerScope.onmessage = function(event): void
|
|
|
13
13
|
indentString: string,
|
|
14
14
|
content: string,
|
|
15
15
|
mimeType: string,
|
|
16
|
-
mapping:
|
|
16
|
+
mapping: ScopeVariableMapping[],
|
|
17
17
|
sourceType: 'module'|'script',
|
|
18
18
|
} = event.data.params;
|
|
19
19
|
if (!method) {
|
|
@@ -121,9 +121,9 @@ const UIStrings = {
|
|
|
121
121
|
*/
|
|
122
122
|
aiModelDownloaded: 'AI model downloaded',
|
|
123
123
|
/**
|
|
124
|
-
* @description Title of the menu item in the customize and control menu leading to the DevTools
|
|
124
|
+
* @description Title of the menu item in the customize and control menu leading to the Chrome DevTools for agents repository.
|
|
125
125
|
*/
|
|
126
|
-
|
|
126
|
+
getChromeDevToolsForAgents: 'Give your agent access to `DevTools`',
|
|
127
127
|
} as const;
|
|
128
128
|
const str_ = i18n.i18n.registerUIStrings('entrypoints/main/MainImpl.ts', UIStrings);
|
|
129
129
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -893,7 +893,7 @@ export class MainMenuItem implements UI.Toolbar.Provider {
|
|
|
893
893
|
|
|
894
894
|
contextMenu.defaultSection().appendAction('freestyler.main-menu', undefined, /* optional */ true);
|
|
895
895
|
|
|
896
|
-
contextMenu.defaultSection().appendItem(i18nString(UIStrings.
|
|
896
|
+
contextMenu.defaultSection().appendItem(i18nString(UIStrings.getChromeDevToolsForAgents), () => {
|
|
897
897
|
UIHelpers.openInNewTab('https://github.com/ChromeDevTools/chrome-devtools-mcp');
|
|
898
898
|
}, {
|
|
899
899
|
additionalElement: UI.UIUtils.maybeCreateNewBadge('get-devtools-mcp'),
|
|
@@ -21,6 +21,7 @@ import * as LiveMetrics from '../models/live-metrics/live-metrics.js';
|
|
|
21
21
|
import * as Logs from '../models/logs/logs.js';
|
|
22
22
|
import * as Persistence from '../models/persistence/persistence.js';
|
|
23
23
|
import * as ProjectSettings from '../models/project_settings/project_settings.js';
|
|
24
|
+
import * as SourceMapScopes from '../models/source_map_scopes/source_map_scopes.js';
|
|
24
25
|
import * as Workspace from '../models/workspace/workspace.js';
|
|
25
26
|
import * as WorkspaceDiff from '../models/workspace_diff/workspace_diff.js';
|
|
26
27
|
|
|
@@ -160,6 +161,10 @@ export class Universe {
|
|
|
160
161
|
resourceMapping, targetManager, ignoreListManager, workspace);
|
|
161
162
|
context.set(Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding, debuggerWorkspaceBinding);
|
|
162
163
|
|
|
164
|
+
const scopeChainResolver =
|
|
165
|
+
new SourceMapScopes.ScopeChainResolver.ScopeChainResolver(targetManager, debuggerWorkspaceBinding);
|
|
166
|
+
context.set(SourceMapScopes.ScopeChainResolver.ScopeChainResolver, scopeChainResolver);
|
|
167
|
+
|
|
163
168
|
const presentationConsoleMessageManager =
|
|
164
169
|
new Bindings.PresentationConsoleMessageHelper.PresentationConsoleMessageManager(
|
|
165
170
|
targetManager, workspace, debuggerWorkspaceBinding, cssWorkspaceBinding);
|
|
@@ -383,6 +388,10 @@ export class Universe {
|
|
|
383
388
|
null;
|
|
384
389
|
}
|
|
385
390
|
|
|
391
|
+
get scopeChainResolver(): SourceMapScopes.ScopeChainResolver.ScopeChainResolver {
|
|
392
|
+
return this.context.get(SourceMapScopes.ScopeChainResolver.ScopeChainResolver);
|
|
393
|
+
}
|
|
394
|
+
|
|
386
395
|
get settings(): Common.Settings.Settings {
|
|
387
396
|
return this.context.get(Common.Settings.Settings);
|
|
388
397
|
}
|
|
@@ -545,7 +545,8 @@ inspectorBackend.registerCommand("Emulation.setSafeAreaInsetsOverride", [{"name"
|
|
|
545
545
|
inspectorBackend.registerCommand("Emulation.setVirtualKeyboardGeometryOverride", [{"name": "keyboardRect", "type": "object", "optional": true, "description": "", "typeRef": "DOM.Rect"}], [], "Overrides virtual keyboard geometry in CSS pixels, relative to the top-level viewport. The provided rect is used for navigator.virtualKeyboard.boundingRect, geometrychange events, and env(keyboard-inset-*) values on the inspected frame. The override applies independently of navigator.virtualKeyboard.overlaysContent so clients can preview overlay geometry without mutating page state. Values are rounded to the nearest CSS pixel. Omitting the rect clears the override.");
|
|
546
546
|
inspectorBackend.registerEnum("Emulation.SetDeviceMetricsOverrideRequestScrollbarType", {Overlay: "overlay", Default: "default"});
|
|
547
547
|
inspectorBackend.registerEnum("Emulation.SetDeviceMetricsOverrideRequestViewportMeta", {Enable: "enable", Default: "default"});
|
|
548
|
-
inspectorBackend.
|
|
548
|
+
inspectorBackend.registerEnum("Emulation.SetDeviceMetricsOverrideRequestTextLayoutMode", {Mobile: "mobile", Default: "default"});
|
|
549
|
+
inspectorBackend.registerCommand("Emulation.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false, "description": "Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.", "typeRef": null}, {"name": "height", "type": "number", "optional": false, "description": "Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override.", "typeRef": null}, {"name": "deviceScaleFactor", "type": "number", "optional": false, "description": "Overriding device scale factor value. 0 disables the override.", "typeRef": null}, {"name": "mobile", "type": "boolean", "optional": false, "description": "Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more.", "typeRef": null}, {"name": "scale", "type": "number", "optional": true, "description": "Scale to apply to resulting view image.", "typeRef": null}, {"name": "screenWidth", "type": "number", "optional": true, "description": "Overriding screen width value in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "screenHeight", "type": "number", "optional": true, "description": "Overriding screen height value in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "positionX", "type": "number", "optional": true, "description": "Overriding view X position on screen in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "positionY", "type": "number", "optional": true, "description": "Overriding view Y position on screen in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "dontSetVisibleSize", "type": "boolean", "optional": true, "description": "Do not set visible view size, rely upon explicit setVisibleSize call.", "typeRef": null}, {"name": "screenOrientation", "type": "object", "optional": true, "description": "Screen orientation override.", "typeRef": "Emulation.ScreenOrientation"}, {"name": "viewport", "type": "object", "optional": true, "description": "If set, the visible area of the page will be overridden to this viewport. This viewport change is not observed by the page, e.g. viewport-relative elements do not change positions.", "typeRef": "Page.Viewport"}, {"name": "displayFeature", "type": "object", "optional": true, "description": "If set, the display feature of a multi-segment screen. If not set, multi-segment support is turned-off. Deprecated, use Emulation.setDisplayFeaturesOverride.", "typeRef": "Emulation.DisplayFeature"}, {"name": "devicePosture", "type": "object", "optional": true, "description": "If set, the posture of a foldable device. If not set the posture is set to continuous. Deprecated, use Emulation.setDevicePostureOverride.", "typeRef": "Emulation.DevicePosture"}, {"name": "scrollbarType", "type": "string", "optional": true, "description": "Scrollbar type. Default: `default`.", "typeRef": "Emulation.SetDeviceMetricsOverrideRequestScrollbarType"}, {"name": "screenOrientationLockEmulation", "type": "boolean", "optional": true, "description": "If set to true, enables screen orientation lock emulation, which intercepts screen.orientation.lock() calls from the page and reports orientation changes via screenOrientationLockChanged events. This is useful for emulating mobile device orientation lock behavior in responsive design mode.", "typeRef": null}, {"name": "viewportMeta", "type": "string", "optional": true, "description": "Viewport meta tag behavior. Default: `default`. Note: if `mobile` is `true`, the viewport meta tag is always enabled.", "typeRef": "Emulation.SetDeviceMetricsOverrideRequestViewportMeta"}, {"name": "textLayoutMode", "type": "string", "optional": true, "description": "Text layout mode. Default: `default`. Note: if `mobile` is `true`, mobile text layout mode (text autosizing) is always enabled.", "typeRef": "Emulation.SetDeviceMetricsOverrideRequestTextLayoutMode"}], [], "Overrides the values of device screen dimensions (window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and \"device-width\"/\"device-height\"-related CSS media query results).");
|
|
549
550
|
inspectorBackend.registerCommand("Emulation.setDevicePostureOverride", [{"name": "posture", "type": "object", "optional": false, "description": "", "typeRef": "Emulation.DevicePosture"}], [], "Start reporting the given posture value to the Device Posture API. This override can also be set in setDeviceMetricsOverride().");
|
|
550
551
|
inspectorBackend.registerCommand("Emulation.clearDevicePostureOverride", [], [], "Clears a device posture override set with either setDeviceMetricsOverride() or setDevicePostureOverride() and starts using posture information from the platform again. Does nothing if no override is set.");
|
|
551
552
|
inspectorBackend.registerCommand("Emulation.setDisplayFeaturesOverride", [{"name": "features", "type": "array", "optional": false, "description": "", "typeRef": "Emulation.DisplayFeature"}], [], "Start using the given display features to pupulate the Viewport Segments API. This override can also be set in setDeviceMetricsOverride().");
|
|
@@ -1240,7 +1241,7 @@ inspectorBackend.registerEvent("Preload.ruleSetUpdated", ["ruleSet"]);
|
|
|
1240
1241
|
inspectorBackend.registerEvent("Preload.ruleSetRemoved", ["id"]);
|
|
1241
1242
|
inspectorBackend.registerEvent("Preload.preloadEnabledStateUpdated", ["disabledByPreference", "disabledByDataSaver", "disabledByBatterySaver", "disabledByHoldbackPrefetchSpeculationRules", "disabledByHoldbackPrerenderSpeculationRules"]);
|
|
1242
1243
|
inspectorBackend.registerEvent("Preload.prefetchStatusUpdated", ["key", "pipelineId", "initiatingFrameId", "prefetchUrl", "status", "prefetchStatus", "requestId"]);
|
|
1243
|
-
inspectorBackend.registerEvent("Preload.prerenderStatusUpdated", ["key", "pipelineId", "status", "prerenderStatus", "disallowedMojoInterface", "mismatchedHeaders"]);
|
|
1244
|
+
inspectorBackend.registerEvent("Preload.prerenderStatusUpdated", ["key", "pipelineId", "status", "effectiveAction", "prerenderStatus", "disallowedMojoInterface", "mismatchedHeaders"]);
|
|
1244
1245
|
inspectorBackend.registerEvent("Preload.preloadingAttemptSourcesUpdated", ["loaderId", "preloadingAttemptSources"]);
|
|
1245
1246
|
inspectorBackend.registerCommand("Preload.enable", [], [], "");
|
|
1246
1247
|
inspectorBackend.registerCommand("Preload.disable", [], [], "");
|
|
@@ -7517,6 +7517,11 @@ export namespace Emulation {
|
|
|
7517
7517
|
Default = 'default',
|
|
7518
7518
|
}
|
|
7519
7519
|
|
|
7520
|
+
export const enum SetDeviceMetricsOverrideRequestTextLayoutMode {
|
|
7521
|
+
Mobile = 'mobile',
|
|
7522
|
+
Default = 'default',
|
|
7523
|
+
}
|
|
7524
|
+
|
|
7520
7525
|
export interface SetDeviceMetricsOverrideRequest {
|
|
7521
7526
|
/**
|
|
7522
7527
|
* Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.
|
|
@@ -7599,6 +7604,11 @@ export namespace Emulation {
|
|
|
7599
7604
|
* the viewport meta tag is always enabled.
|
|
7600
7605
|
*/
|
|
7601
7606
|
viewportMeta?: SetDeviceMetricsOverrideRequestViewportMeta;
|
|
7607
|
+
/**
|
|
7608
|
+
* Text layout mode. Default: `default`. Note: if `mobile` is `true`,
|
|
7609
|
+
* mobile text layout mode (text autosizing) is always enabled.
|
|
7610
|
+
*/
|
|
7611
|
+
textLayoutMode?: SetDeviceMetricsOverrideRequestTextLayoutMode;
|
|
7602
7612
|
}
|
|
7603
7613
|
|
|
7604
7614
|
export interface SetDevicePostureOverrideRequest {
|
|
@@ -17557,6 +17567,12 @@ export namespace Preload {
|
|
|
17557
17567
|
key: PreloadingAttemptKey;
|
|
17558
17568
|
pipelineId: PreloadPipelineId;
|
|
17559
17569
|
status: PreloadingStatus;
|
|
17570
|
+
/**
|
|
17571
|
+
* The action currently performed by this attempt. This differs from
|
|
17572
|
+
* `key.action` after a prerender-until-script attempt is upgraded in place
|
|
17573
|
+
* to a full prerender.
|
|
17574
|
+
*/
|
|
17575
|
+
effectiveAction?: SpeculationAction;
|
|
17560
17576
|
prerenderStatus?: PrerenderFinalStatus;
|
|
17561
17577
|
/**
|
|
17562
17578
|
* This is used to give users more information about the name of Mojo interface
|
|
@@ -348,7 +348,7 @@ export class CompilerScriptMapping implements DebuggerSourceMapping {
|
|
|
348
348
|
return false;
|
|
349
349
|
}
|
|
350
350
|
const {sourceMap, script} = sourceMapAndScript;
|
|
351
|
-
const {lineNumber, columnNumber} = script.
|
|
351
|
+
const {lineNumber, columnNumber} = script.rawLocationToRelativeLocation(frame);
|
|
352
352
|
|
|
353
353
|
if (!sourceMap.isOutlinedFrame(lineNumber, columnNumber)) {
|
|
354
354
|
const frames = sourceMap.translateCallSite(lineNumber, columnNumber);
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
import * as Platform from '../../core/platform/platform.js';
|
|
6
6
|
import * as FormatterActions from '../../entrypoints/formatter_actions/formatter_actions.js';
|
|
7
7
|
|
|
8
|
-
export {
|
|
8
|
+
export {
|
|
9
|
+
DefinitionKind,
|
|
10
|
+
ScopeKind,
|
|
11
|
+
type ScopeTreeNode,
|
|
12
|
+
type ScopeVariableMapping,
|
|
13
|
+
} from '../../entrypoints/formatter_actions/formatter_actions.js';
|
|
9
14
|
|
|
10
15
|
let formatterWorkerPoolInstance: FormatterWorkerPool|undefined;
|
|
11
16
|
|
|
@@ -134,8 +139,8 @@ export class FormatterWorkerPool {
|
|
|
134
139
|
return this.runTask(FormatterActions.FormatterActions.FORMAT, parameters) as Promise<FormatterActions.FormatResult>;
|
|
135
140
|
}
|
|
136
141
|
|
|
137
|
-
javaScriptSubstitute(expression: string, mapping:
|
|
138
|
-
if (mapping.every(
|
|
142
|
+
javaScriptSubstitute(expression: string, mapping: FormatterActions.ScopeVariableMapping[]): Promise<string> {
|
|
143
|
+
if (mapping.every(scope => scope.bindings.size === 0)) {
|
|
139
144
|
return Promise.resolve(expression);
|
|
140
145
|
}
|
|
141
146
|
return this.runTask(FormatterActions.FormatterActions.JAVASCRIPT_SUBSTITUTE, {content: expression, mapping})
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
+
import * as Common from '../../core/common/common.js';
|
|
5
6
|
import type * as Platform from '../../core/platform/platform.js';
|
|
6
7
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
7
8
|
import type * as Protocol from '../../generated/protocol.js';
|
|
@@ -420,7 +421,9 @@ export class HARInitiator extends HARBase {
|
|
|
420
421
|
super(data);
|
|
421
422
|
this.type = (HARBase.optionalString(data['type']) ?? SDK.NetworkRequest.InitiatorType.OTHER) as
|
|
422
423
|
Protocol.Network.InitiatorType;
|
|
423
|
-
|
|
424
|
+
const url = HARBase.optionalString(data['url']);
|
|
425
|
+
// Ignore privileged/non-web schemes in imported HARs.
|
|
426
|
+
this.url = url && Common.ParsedURL.hasWebSafeScheme(url) ? url : undefined;
|
|
424
427
|
this.lineNumber = HARBase.optionalNumber(data['lineNumber']);
|
|
425
428
|
this.requestId = HARBase.optionalString(data['requestId']) as Protocol.Network.RequestId;
|
|
426
429
|
if (data['stack']) {
|
|
@@ -477,7 +480,9 @@ export class HARCallFrame extends HARBase {
|
|
|
477
480
|
|
|
478
481
|
this.functionName = HARBase.optionalString(data['functionName']) ?? '';
|
|
479
482
|
this.scriptId = (HARBase.optionalString(data['scriptId']) ?? '') as Protocol.Runtime.ScriptId;
|
|
480
|
-
|
|
483
|
+
const url = HARBase.optionalString(data['url']) ?? '';
|
|
484
|
+
// Ignore privileged/non-web schemes in imported HARs.
|
|
485
|
+
this.url = Common.ParsedURL.hasWebSafeScheme(url) ? url : '';
|
|
481
486
|
this.lineNumber = HARBase.optionalNumber(data['lineNumber']) ?? -1;
|
|
482
487
|
this.columnNumber = HARBase.optionalNumber(data['columnNumber']) ?? -1;
|
|
483
488
|
}
|