chrome-devtools-frontend 1.0.1642899 → 1.0.1643855
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/eslint.config.mjs +3 -1
- package/extension-api/ExtensionAPI.d.ts +83 -12
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/ConsoleModel.ts +4 -0
- package/front_end/core/sdk/NetworkRequest.ts +12 -0
- package/front_end/core/sdk/SourceMap.ts +15 -18
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -2
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +4 -5
- package/front_end/entrypoints/main/MainImpl.ts +0 -6
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/protocol.ts +7 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +24 -5
- package/front_end/models/ai_assistance/AiConversation.ts +15 -12
- package/front_end/models/ai_assistance/AiUtils.ts +71 -0
- package/front_end/models/ai_assistance/ChangeManager.ts +2 -5
- package/front_end/models/ai_assistance/{agents/ConversationSummaryAgent.ts → ConversationSummary.ts} +29 -66
- package/front_end/models/ai_assistance/ExtensionScope.ts +1 -4
- package/front_end/models/ai_assistance/{agents/PerformanceAnnotationsAgent.ts → PerformanceAnnotations.ts} +47 -89
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +47 -31
- package/front_end/models/ai_assistance/agents/AiAgent.ts +40 -12
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +11 -0
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +58 -8
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -92
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +25 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +94 -79
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +101 -39
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -2
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +27 -21
- package/front_end/models/ai_assistance/ai_assistance.ts +6 -4
- package/front_end/models/ai_assistance/skills/styling.md +12 -4
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +134 -0
- package/front_end/models/ai_assistance/tools/GetStyles.ts +6 -2
- package/front_end/models/ai_assistance/tools/Tool.ts +16 -1
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +2 -0
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +6 -9
- package/front_end/models/bindings/DefaultScriptMapping.ts +2 -1
- package/front_end/models/bindings/SymbolizedError.ts +45 -35
- package/front_end/models/extensions/ExtensionAPI.ts +138 -47
- package/front_end/models/har/Importer.ts +1 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +5 -7
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +12 -2
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +44 -51
- package/front_end/models/stack_trace/StackTrace.ts +7 -0
- package/front_end/models/stack_trace/StackTraceImpl.ts +13 -4
- package/front_end/models/stack_trace/StackTraceModel.ts +9 -8
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +2 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -8
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +96 -4
- package/front_end/panels/ai_assistance/components/chatMessage.css +6 -0
- package/front_end/panels/application/ApplicationPanelSidebar.ts +39 -0
- package/front_end/panels/application/ApplicationPanelTreeElement.ts +39 -0
- package/front_end/panels/application/CookieItemsView.ts +2 -2
- package/front_end/panels/application/components/AdsView.ts +219 -0
- package/front_end/panels/application/components/adsView.css +54 -0
- package/front_end/panels/application/components/components.ts +2 -0
- package/front_end/panels/application/resourcesSidebar.css +11 -0
- package/front_end/panels/console/SymbolizedErrorWidget.ts +79 -25
- package/front_end/panels/network/NetworkLogView.ts +5 -1
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -0
- package/front_end/panels/sources/SourcesPanel.ts +2 -1
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +5 -4
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1607 -5733
- package/front_end/third_party/lighthouse/locales/ar-XB.json +290 -65
- package/front_end/third_party/lighthouse/locales/ar.json +290 -65
- package/front_end/third_party/lighthouse/locales/bg.json +290 -65
- package/front_end/third_party/lighthouse/locales/ca.json +295 -70
- package/front_end/third_party/lighthouse/locales/cs.json +290 -65
- package/front_end/third_party/lighthouse/locales/da.json +294 -69
- package/front_end/third_party/lighthouse/locales/de.json +295 -70
- package/front_end/third_party/lighthouse/locales/el.json +290 -65
- package/front_end/third_party/lighthouse/locales/en-GB.json +290 -65
- package/front_end/third_party/lighthouse/locales/en-US.json +79 -67
- package/front_end/third_party/lighthouse/locales/en-XA.json +253 -64
- package/front_end/third_party/lighthouse/locales/en-XL.json +79 -67
- package/front_end/third_party/lighthouse/locales/es-419.json +290 -65
- package/front_end/third_party/lighthouse/locales/es.json +298 -73
- package/front_end/third_party/lighthouse/locales/fi.json +290 -65
- package/front_end/third_party/lighthouse/locales/fil.json +290 -65
- package/front_end/third_party/lighthouse/locales/fr.json +294 -69
- package/front_end/third_party/lighthouse/locales/he.json +293 -68
- package/front_end/third_party/lighthouse/locales/hi.json +291 -66
- package/front_end/third_party/lighthouse/locales/hr.json +290 -65
- package/front_end/third_party/lighthouse/locales/hu.json +290 -65
- package/front_end/third_party/lighthouse/locales/id.json +290 -65
- package/front_end/third_party/lighthouse/locales/it.json +294 -69
- package/front_end/third_party/lighthouse/locales/ja.json +290 -65
- package/front_end/third_party/lighthouse/locales/ko.json +290 -65
- package/front_end/third_party/lighthouse/locales/lt.json +290 -65
- package/front_end/third_party/lighthouse/locales/lv.json +290 -65
- package/front_end/third_party/lighthouse/locales/nl.json +290 -65
- package/front_end/third_party/lighthouse/locales/no.json +290 -65
- package/front_end/third_party/lighthouse/locales/pl.json +290 -65
- package/front_end/third_party/lighthouse/locales/pt-PT.json +291 -66
- package/front_end/third_party/lighthouse/locales/pt.json +290 -65
- package/front_end/third_party/lighthouse/locales/ro.json +290 -65
- package/front_end/third_party/lighthouse/locales/ru.json +301 -76
- package/front_end/third_party/lighthouse/locales/sk.json +291 -66
- package/front_end/third_party/lighthouse/locales/sl.json +290 -65
- package/front_end/third_party/lighthouse/locales/sr-Latn.json +290 -65
- package/front_end/third_party/lighthouse/locales/sr.json +290 -65
- package/front_end/third_party/lighthouse/locales/sv.json +297 -72
- package/front_end/third_party/lighthouse/locales/ta.json +291 -66
- package/front_end/third_party/lighthouse/locales/te.json +293 -68
- package/front_end/third_party/lighthouse/locales/th.json +291 -66
- package/front_end/third_party/lighthouse/locales/tr.json +290 -65
- package/front_end/third_party/lighthouse/locales/uk.json +290 -65
- package/front_end/third_party/lighthouse/locales/vi.json +291 -66
- package/front_end/third_party/lighthouse/locales/zh-HK.json +292 -67
- package/front_end/third_party/lighthouse/locales/zh-TW.json +291 -66
- package/front_end/third_party/lighthouse/locales/zh.json +291 -66
- package/front_end/third_party/lighthouse/report/bundle.d.ts +6 -6
- package/front_end/third_party/lighthouse/report/bundle.js +4 -7
- package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
- package/front_end/ui/legacy/StackedPane.ts +229 -0
- package/front_end/ui/legacy/ViewManager.ts +59 -169
- package/front_end/ui/legacy/Widget.ts +32 -8
- package/front_end/ui/legacy/legacy.ts +3 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
isErrorLike,
|
|
25
25
|
type SymbolizedError,
|
|
26
26
|
SymbolizedErrorObject,
|
|
27
|
-
SymbolizedSyntaxError,
|
|
28
27
|
UnparsableError,
|
|
29
28
|
} from './SymbolizedError.js';
|
|
30
29
|
|
|
@@ -238,14 +237,6 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
|
|
|
238
237
|
]);
|
|
239
238
|
fetchedExceptionDetails = details;
|
|
240
239
|
causeRemoteObject = causeRemote;
|
|
241
|
-
|
|
242
|
-
if (remoteObject.className === 'SyntaxError' && fetchedExceptionDetails) {
|
|
243
|
-
const syntaxError = await SymbolizedSyntaxError.fromExceptionDetails(
|
|
244
|
-
remoteObject.runtimeModel().target(), this, fetchedExceptionDetails);
|
|
245
|
-
if (syntaxError) {
|
|
246
|
-
return syntaxError;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
240
|
} else if (remoteObject.type === 'string') {
|
|
250
241
|
errorStack = remoteObject.description || '';
|
|
251
242
|
if (!isErrorLike(errorStack)) {
|
|
@@ -271,6 +262,12 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
|
|
|
271
262
|
}
|
|
272
263
|
|
|
273
264
|
const message = StackTraceImpl.DetailedErrorStackParser.parseMessage(errorStack);
|
|
265
|
+
|
|
266
|
+
if (remoteObject.subtype === 'error' && remoteObject.className === 'SyntaxError' && fetchedExceptionDetails) {
|
|
267
|
+
return await SymbolizedErrorObject.createForSyntaxError(remoteObject.runtimeModel().target(), this, message,
|
|
268
|
+
fetchedExceptionDetails, stackTrace, cause);
|
|
269
|
+
}
|
|
270
|
+
|
|
274
271
|
return new SymbolizedErrorObject(message, stackTrace, cause);
|
|
275
272
|
}
|
|
276
273
|
|
|
@@ -107,7 +107,8 @@ export class DefaultScriptMapping implements DebuggerSourceMapping {
|
|
|
107
107
|
}
|
|
108
108
|
this.#uiSourceCodeToScript.set(uiSourceCode, script);
|
|
109
109
|
this.#scriptToUISourceCode.set(script, uiSourceCode);
|
|
110
|
-
|
|
110
|
+
const mimeType = script.isWasm() ? 'application/wasm' : 'text/javascript';
|
|
111
|
+
this.#project.addUISourceCodeWithProvider(uiSourceCode, script, null, mimeType);
|
|
111
112
|
void this.#debuggerWorkspaceBinding.updateLocations(script);
|
|
112
113
|
}
|
|
113
114
|
|
|
@@ -15,7 +15,7 @@ export function isErrorLike(stack: string): boolean {
|
|
|
15
15
|
return /\n\s*at\s/.test(stack) || stack.startsWith('SyntaxError:');
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export type SymbolizedError = SymbolizedErrorObject|
|
|
18
|
+
export type SymbolizedError = SymbolizedErrorObject|UnparsableError;
|
|
19
19
|
|
|
20
20
|
export class UnparsableError extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
21
21
|
readonly errorStack: string;
|
|
@@ -45,6 +45,7 @@ export class SymbolizedErrorObject extends Common.ObjectWrapper.ObjectWrapper<Ev
|
|
|
45
45
|
readonly message: string;
|
|
46
46
|
readonly stackTrace: StackTrace.StackTrace.ParsedErrorStackTrace;
|
|
47
47
|
readonly cause: SymbolizedError|null;
|
|
48
|
+
#syntaxErrorLocation: Workspace.UISourceCode.UILocation|null = null;
|
|
48
49
|
|
|
49
50
|
constructor(message: string, stackTrace: StackTrace.StackTrace.ParsedErrorStackTrace, cause: SymbolizedError|null) {
|
|
50
51
|
super();
|
|
@@ -64,53 +65,62 @@ export class SymbolizedErrorObject extends Common.ObjectWrapper.ObjectWrapper<Ev
|
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
this
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export class SymbolizedSyntaxError extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
73
|
-
readonly message: string;
|
|
74
|
-
#uiLocation: Workspace.UISourceCode.UILocation|null = null;
|
|
75
|
-
|
|
76
|
-
constructor(message: string) {
|
|
77
|
-
super();
|
|
78
|
-
this.message = message;
|
|
68
|
+
get syntaxErrorLocation(): Workspace.UISourceCode.UILocation|null {
|
|
69
|
+
return this.#syntaxErrorLocation;
|
|
79
70
|
}
|
|
80
71
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Evaluates if we should populate the `syntaxErrorLocation` based on the provided exception details.
|
|
74
|
+
*
|
|
75
|
+
* There are three primary cases for SyntaxError:
|
|
76
|
+
* 1. Programmatic `SyntaxError`: Thrown via `throw new SyntaxError('...', {cause: ...})`. Has a full stack trace,
|
|
77
|
+
* and an optional cause. The exception details point to the `throw` statement, which is identical to the top frame.
|
|
78
|
+
* We do NOT want to populate `syntaxErrorLocation` here to avoid redundant location rendering in the UI.
|
|
79
|
+
* 2. Script parse failure: Failed to parse a script. Has no stack trace but possesses a compile-time location.
|
|
80
|
+
* We DO want to populate `syntaxErrorLocation` to highlight where the parse failed.
|
|
81
|
+
* 3. `eval` parse failure: Failed to parse an eval string. Has a stack trace pointing to the `eval` call site
|
|
82
|
+
* and a compile-time location of the parse failure within the string. The exception details location differs
|
|
83
|
+
* from the top frame. We DO want to populate `syntaxErrorLocation` here.
|
|
84
|
+
*/
|
|
85
|
+
static async createForSyntaxError(target: SDK.Target.Target, debuggerWorkspaceBinding: DebuggerWorkspaceBinding,
|
|
86
|
+
message: string, exceptionDetails: Protocol.Runtime.ExceptionDetails,
|
|
87
|
+
stackTrace: StackTrace.StackTrace.ParsedErrorStackTrace,
|
|
88
|
+
cause: SymbolizedError|null): Promise<SymbolizedErrorObject> {
|
|
88
89
|
const {exception, scriptId, lineNumber, columnNumber} = exceptionDetails;
|
|
89
90
|
if (!exception || exception.subtype !== 'error' || exception.className !== 'SyntaxError') {
|
|
90
|
-
throw new Error('
|
|
91
|
+
throw new Error('SymbolizedErrorObject.createForSyntaxError expects a SyntaxError');
|
|
91
92
|
}
|
|
93
|
+
|
|
94
|
+
const symbolizedError = new SymbolizedErrorObject(message, stackTrace, cause);
|
|
95
|
+
|
|
92
96
|
if (!scriptId) {
|
|
93
|
-
return
|
|
97
|
+
return symbolizedError;
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
const topFrame = exceptionDetails.stackTrace?.callFrames[0];
|
|
101
|
+
const isProgrammaticThrow = topFrame && topFrame.scriptId === scriptId && topFrame.lineNumber === lineNumber &&
|
|
102
|
+
topFrame.columnNumber === columnNumber;
|
|
103
|
+
|
|
104
|
+
if (!isProgrammaticThrow) {
|
|
105
|
+
const debuggerModel = target.model(SDK.DebuggerModel.DebuggerModel);
|
|
106
|
+
if (debuggerModel) {
|
|
107
|
+
const rawLocation = debuggerModel.createRawLocationByScriptId(scriptId, lineNumber, columnNumber);
|
|
108
|
+
// We don't implement dispose here. We won't create many of these so a couple
|
|
109
|
+
// LiveLocationPools and SymbolizedErrorObject instances leaking is fine.
|
|
110
|
+
await debuggerWorkspaceBinding.createLiveLocation(
|
|
111
|
+
rawLocation, symbolizedError.#updateSyntaxErrorLocation.bind(symbolizedError), new LiveLocationPool());
|
|
112
|
+
}
|
|
99
113
|
}
|
|
100
114
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// We don't implement dispose here. We won't create many of these so a couple
|
|
105
|
-
// LiveLocationPools and SymbolizedSyntaxError instances leaking is fine.
|
|
106
|
-
await debuggerWorkspaceBinding.createLiveLocation(
|
|
107
|
-
rawLocation, symbolizedSyntaxError.#update.bind(symbolizedSyntaxError), new LiveLocationPool());
|
|
115
|
+
return symbolizedError;
|
|
116
|
+
}
|
|
108
117
|
|
|
109
|
-
|
|
118
|
+
async #updateSyntaxErrorLocation(liveLocation: LiveLocation): Promise<void> {
|
|
119
|
+
this.#syntaxErrorLocation = await liveLocation.uiLocation();
|
|
120
|
+
this.dispatchEventToListeners(Events.UPDATED);
|
|
110
121
|
}
|
|
111
122
|
|
|
112
|
-
|
|
113
|
-
this.#uiLocation = await liveLocation.uiLocation();
|
|
123
|
+
#fireUpdated(): void {
|
|
114
124
|
this.dispatchEventToListeners(Events.UPDATED);
|
|
115
125
|
}
|
|
116
126
|
}
|
|
@@ -1067,6 +1067,46 @@ self.injectedExtensionAPI = function(
|
|
|
1067
1067
|
return typeof lastArgument === 'function' ? lastArgument as (...args: unknown[]) => unknown : undefined;
|
|
1068
1068
|
}
|
|
1069
1069
|
|
|
1070
|
+
/**
|
|
1071
|
+
* Helper to support both callback and Promise-based APIs.
|
|
1072
|
+
*
|
|
1073
|
+
* @param args The arguments object of the calling function.
|
|
1074
|
+
* @returns An object containing either the `callback` function, or the
|
|
1075
|
+
* `promise` and its `resolve`/`reject` functions.
|
|
1076
|
+
*/
|
|
1077
|
+
function callbackOrPromise<ResolveT, CallbackArgsT extends unknown[] = [ResolveT]>(args: IArguments): {
|
|
1078
|
+
callback?: (...args: CallbackArgsT) => void,
|
|
1079
|
+
promise?: Promise<ResolveT>,
|
|
1080
|
+
resolve?: (value: ResolveT) => void,
|
|
1081
|
+
reject?: (error: unknown) => void,
|
|
1082
|
+
} {
|
|
1083
|
+
const callback = extractCallbackArgument(args);
|
|
1084
|
+
if (callback) {
|
|
1085
|
+
return {callback: callback as (...args: CallbackArgsT) => void};
|
|
1086
|
+
}
|
|
1087
|
+
const {promise, resolve, reject} = Promise.withResolvers<ResolveT>();
|
|
1088
|
+
return {promise, resolve, reject};
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Checks if the `response` from the ExtensionServer indicates an error. If an
|
|
1093
|
+
* error occurred and a `Promise` `reject` function is provided, this function
|
|
1094
|
+
* will reject the promise with a generic 'DevTools API encountered an error' Error.
|
|
1095
|
+
*
|
|
1096
|
+
* @param response The response object from the ExtensionServer.
|
|
1097
|
+
* @param reject The promise reject function, if applicable.
|
|
1098
|
+
* @returns `true` if an error occurred and the promise was rejected, `false`
|
|
1099
|
+
* otherwise.
|
|
1100
|
+
*/
|
|
1101
|
+
function checkErrorAndReject(response: unknown, reject?: (error: Error) => void): boolean {
|
|
1102
|
+
const res = response as {isError?: boolean, description?: string, details?: unknown[]};
|
|
1103
|
+
if (res.isError && reject) {
|
|
1104
|
+
reject(new Error('DevTools API encountered an error'));
|
|
1105
|
+
return true;
|
|
1106
|
+
}
|
|
1107
|
+
return false;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1070
1110
|
const LanguageServicesAPI = declareInterfaceClass(LanguageServicesAPIImpl);
|
|
1071
1111
|
const RecorderServicesAPI = declareInterfaceClass(RecorderServicesAPIImpl);
|
|
1072
1112
|
const Performance = declareInterfaceClass(PerformanceImpl);
|
|
@@ -1247,43 +1287,68 @@ self.injectedExtensionAPI = function(
|
|
|
1247
1287
|
extensionServer.sendRequest({command: PrivateAPI.Commands.Reload, options});
|
|
1248
1288
|
},
|
|
1249
1289
|
|
|
1250
|
-
eval: function(
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1290
|
+
eval: function<E = unknown>(this: PublicAPI.Chrome.DevTools.InspectedWindow, expression: string,
|
|
1291
|
+
optionsOrCallback?: unknown,
|
|
1292
|
+
_callback?: (result: unknown, exceptionInfo: object) => void): Promise<E>|
|
|
1293
|
+
void {
|
|
1294
|
+
const options = (typeof optionsOrCallback === 'object' && optionsOrCallback !== null) ?
|
|
1295
|
+
optionsOrCallback as PrivateAPI.EvaluateOptions :
|
|
1296
|
+
undefined;
|
|
1297
|
+
|
|
1298
|
+
const {callback: callbackArg, promise, resolve, reject} = callbackOrPromise<E, [unknown, object?]>(arguments);
|
|
1299
|
+
|
|
1256
1300
|
function callbackWrapper(result: unknown): void {
|
|
1257
|
-
|
|
1258
|
-
|
|
1301
|
+
if (checkErrorAndReject(result, reject)) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
const res = result as {
|
|
1306
|
+
value?: unknown,
|
|
1259
1307
|
isError?: boolean,
|
|
1260
1308
|
isException?: boolean,
|
|
1261
1309
|
};
|
|
1262
|
-
|
|
1263
|
-
|
|
1310
|
+
|
|
1311
|
+
if (res.isException) {
|
|
1312
|
+
reject?.(res);
|
|
1313
|
+
} else {
|
|
1314
|
+
resolve?.(res.value as E);
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
if (res.isError || res.isException) {
|
|
1318
|
+
callbackArg?.(undefined, res);
|
|
1264
1319
|
} else {
|
|
1265
|
-
|
|
1320
|
+
callbackArg?.(res.value);
|
|
1266
1321
|
}
|
|
1267
1322
|
}
|
|
1268
1323
|
extensionServer.sendRequest(
|
|
1269
|
-
{
|
|
1270
|
-
|
|
1271
|
-
expression,
|
|
1272
|
-
evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : undefined),
|
|
1273
|
-
},
|
|
1274
|
-
callback && callbackWrapper);
|
|
1275
|
-
return null;
|
|
1276
|
-
},
|
|
1324
|
+
{command: PrivateAPI.Commands.EvaluateOnInspectedPage, expression, evaluateOptions: options},
|
|
1325
|
+
callbackWrapper);
|
|
1277
1326
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1327
|
+
return promise;
|
|
1328
|
+
} as PublicAPI.Chrome.DevTools.InspectedWindow['eval'],
|
|
1329
|
+
|
|
1330
|
+
getResources: function(this: PublicAPI.Chrome.DevTools.InspectedWindow,
|
|
1331
|
+
_callback?: (resources: PublicAPI.Chrome.DevTools.Resource[]) => void):
|
|
1332
|
+
Promise<PublicAPI.Chrome.DevTools.Resource[]>|
|
|
1333
|
+
void {
|
|
1334
|
+
const {callback: callbackArg, promise, resolve, reject} =
|
|
1335
|
+
callbackOrPromise<PublicAPI.Chrome.DevTools.Resource[]>(arguments);
|
|
1336
|
+
|
|
1337
|
+
function callbackWrapper(response: unknown): void {
|
|
1338
|
+
if (checkErrorAndReject(response, reject)) {
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
const wrappedResources =
|
|
1343
|
+
((response || []) as APIImpl.ResourceData[]).map(r => new (Constructor(Resource))(r));
|
|
1344
|
+
resolve?.(wrappedResources);
|
|
1345
|
+
callbackArg?.(wrappedResources);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
extensionServer.sendRequest({command: PrivateAPI.Commands.GetPageResources}, callbackWrapper);
|
|
1349
|
+
|
|
1350
|
+
return promise;
|
|
1351
|
+
} as PublicAPI.Chrome.DevTools.InspectedWindow['getResources'],
|
|
1287
1352
|
};
|
|
1288
1353
|
|
|
1289
1354
|
function ResourceImpl(this: APIImpl.Resource, resourceData: APIImpl.ResourceData): void {
|
|
@@ -1292,9 +1357,9 @@ self.injectedExtensionAPI = function(
|
|
|
1292
1357
|
this._buildId = resourceData.buildId;
|
|
1293
1358
|
}
|
|
1294
1359
|
|
|
1295
|
-
(ResourceImpl.prototype as
|
|
1296
|
-
|
|
1297
|
-
|
|
1360
|
+
(ResourceImpl.prototype as
|
|
1361
|
+
Pick<APIImpl.Resource,
|
|
1362
|
+
'url'|'type'|'buildId'|'getContent'|'setContent'|'setFunctionRangesForScript'|'attachSourceMapURL'>) = {
|
|
1298
1363
|
get url(): string {
|
|
1299
1364
|
return (this as APIImpl.Resource)._url;
|
|
1300
1365
|
},
|
|
@@ -1307,25 +1372,51 @@ self.injectedExtensionAPI = function(
|
|
|
1307
1372
|
return (this as APIImpl.Resource)._buildId;
|
|
1308
1373
|
},
|
|
1309
1374
|
|
|
1310
|
-
getContent: function(this: APIImpl.Resource,
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1375
|
+
getContent: function(this: APIImpl.Resource, _callback?: (content: string, encoding: string) => void): Promise<{
|
|
1376
|
+
content: string, encoding: string,
|
|
1377
|
+
}>|
|
|
1378
|
+
void {
|
|
1379
|
+
const {callback: callbackArg, promise, resolve, reject} =
|
|
1380
|
+
callbackOrPromise<{content: string, encoding: string}, [string, string]>(arguments);
|
|
1315
1381
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1382
|
+
function callbackWrapper(response: unknown): void {
|
|
1383
|
+
if (checkErrorAndReject(response, reject)) {
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1319
1386
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1387
|
+
const {content, encoding} = response as {content: string, encoding: string};
|
|
1388
|
+
resolve?.({content, encoding});
|
|
1389
|
+
callbackArg?.(content, encoding);
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
extensionServer.sendRequest({command: PrivateAPI.Commands.GetResourceContent, url: this._url},
|
|
1393
|
+
callbackWrapper);
|
|
1394
|
+
|
|
1395
|
+
return promise;
|
|
1396
|
+
} as PublicAPI.Chrome.DevTools.Resource['getContent'],
|
|
1397
|
+
|
|
1398
|
+
setContent: function(this: APIImpl.Resource, content: string, commit: boolean,
|
|
1399
|
+
_callback?: (status?: object) => void): Promise<void>|
|
|
1400
|
+
void {
|
|
1401
|
+
const {callback: callbackArg, promise, resolve, reject} = callbackOrPromise<void, [object]>(arguments);
|
|
1402
|
+
|
|
1403
|
+
function callbackWrapper(response: unknown): void {
|
|
1404
|
+
if (checkErrorAndReject(response, reject)) {
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
resolve?.();
|
|
1409
|
+
callbackArg?.(response as object);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
extensionServer.sendRequest(
|
|
1413
|
+
{command: PrivateAPI.Commands.SetResourceContent, url: this._url, content, commit}, callbackWrapper);
|
|
1414
|
+
|
|
1415
|
+
return promise;
|
|
1416
|
+
} as PublicAPI.Chrome.DevTools.Resource['setContent'],
|
|
1326
1417
|
|
|
1327
|
-
setFunctionRangesForScript: function(
|
|
1328
|
-
|
|
1418
|
+
setFunctionRangesForScript: function(this: APIImpl.Resource,
|
|
1419
|
+
ranges: PublicAPI.Chrome.DevTools.NamedFunctionRange[]): Promise<void> {
|
|
1329
1420
|
return new Promise(
|
|
1330
1421
|
(resolve, reject) => extensionServer.sendRequest(
|
|
1331
1422
|
{
|
|
@@ -40,6 +40,7 @@ export class Importer {
|
|
|
40
40
|
}
|
|
41
41
|
const request = SDK.NetworkRequest.NetworkRequest.createWithoutBackendRequest(
|
|
42
42
|
'har-' + requests.length, entry.request.url, documentURL, initiator);
|
|
43
|
+
request.setIsImportedHar(true);
|
|
43
44
|
const page = pageref ? pages.get(pageref) : undefined;
|
|
44
45
|
if (!pageLoad && pageref && page) {
|
|
45
46
|
pageLoad = Importer.buildPageLoad(page, request);
|
|
@@ -244,8 +244,6 @@ export class HeapSnapshotLoaderProxy extends HeapSnapshotProxyObject implements
|
|
|
244
244
|
const snapshotProxy = await this.callFactoryMethodPromise('buildSnapshot', HeapSnapshotProxy, [channel.port1]);
|
|
245
245
|
secondWorker.dispose();
|
|
246
246
|
this.dispose();
|
|
247
|
-
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
|
248
|
-
// @ts-expect-error
|
|
249
247
|
snapshotProxy.setProfileUid(this.profileUid);
|
|
250
248
|
await snapshotProxy.updateStaticData();
|
|
251
249
|
this.snapshotReceivedCallback(snapshotProxy);
|
|
@@ -254,7 +252,7 @@ export class HeapSnapshotLoaderProxy extends HeapSnapshotProxyObject implements
|
|
|
254
252
|
|
|
255
253
|
export class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
256
254
|
staticData: HeapSnapshotModel.StaticData|null;
|
|
257
|
-
profileUid?:
|
|
255
|
+
profileUid?: number;
|
|
258
256
|
|
|
259
257
|
constructor(worker: HeapSnapshotWorkerProxy, objectId: number) {
|
|
260
258
|
super(worker, objectId);
|
|
@@ -279,7 +277,7 @@ export class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
|
279
277
|
}
|
|
280
278
|
|
|
281
279
|
calculateSnapshotDiff(
|
|
282
|
-
baseSnapshotId:
|
|
280
|
+
baseSnapshotId: number,
|
|
283
281
|
baseSnapshotAggregates: Record<string, HeapSnapshotModel.AggregateForDiff>,
|
|
284
282
|
): Promise<Record<string, HeapSnapshotModel.Diff>> {
|
|
285
283
|
return this.callMethodPromise('calculateSnapshotDiff', baseSnapshotId, baseSnapshotAggregates);
|
|
@@ -301,7 +299,7 @@ export class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
|
301
299
|
return this.callFactoryMethod('createRetainingEdgesProvider', HeapSnapshotProviderProxy, nodeIndex);
|
|
302
300
|
}
|
|
303
301
|
|
|
304
|
-
createAddedNodesProvider(baseSnapshotId:
|
|
302
|
+
createAddedNodesProvider(baseSnapshotId: number, classKey: string): HeapSnapshotProviderProxy {
|
|
305
303
|
return this.callFactoryMethod('createAddedNodesProvider', HeapSnapshotProviderProxy, baseSnapshotId, classKey);
|
|
306
304
|
}
|
|
307
305
|
|
|
@@ -391,11 +389,11 @@ export class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
|
391
389
|
return this.staticData.totalSize;
|
|
392
390
|
}
|
|
393
391
|
|
|
394
|
-
get uid():
|
|
392
|
+
get uid(): number|undefined {
|
|
395
393
|
return this.profileUid;
|
|
396
394
|
}
|
|
397
395
|
|
|
398
|
-
setProfileUid(profileUid:
|
|
396
|
+
setProfileUid(profileUid: number): void {
|
|
399
397
|
this.profileUid = profileUid;
|
|
400
398
|
}
|
|
401
399
|
|
|
@@ -203,7 +203,14 @@ function createFunctionCode(
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
|
-
*
|
|
206
|
+
* Resolves the function code and its surrounding context for a given location.
|
|
207
|
+
*
|
|
208
|
+
* The input location (line, column) may be either an authored (source-mapped)
|
|
209
|
+
* location or a raw location. The function will attempt to resolve it to a
|
|
210
|
+
* raw location regardless. This is necessary because callers (such as AI
|
|
211
|
+
* assistance) may work with either format.
|
|
212
|
+
*
|
|
213
|
+
* We filter projects by `target` to prevent cross-origin leaks.
|
|
207
214
|
*/
|
|
208
215
|
export async function getFunctionCodeFromLocation(
|
|
209
216
|
target: SDK.Target.Target, url: Platform.DevToolsPath.UrlString, line: number, column: number,
|
|
@@ -213,10 +220,13 @@ export async function getFunctionCodeFromLocation(
|
|
|
213
220
|
throw new Error('missing debugger model');
|
|
214
221
|
}
|
|
215
222
|
|
|
216
|
-
let uiSourceCode;
|
|
223
|
+
let uiSourceCode: Workspace.UISourceCode.UISourceCode|null = null;
|
|
217
224
|
const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
|
|
218
225
|
const projects = debuggerWorkspaceBinding.workspace.projectsForType(Workspace.Workspace.projectTypes.Network);
|
|
219
226
|
for (const project of projects) {
|
|
227
|
+
if (Bindings.NetworkProject.NetworkProject.getTargetForProject(project) !== target) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
220
230
|
uiSourceCode = project.uiSourceCodeForURL(url);
|
|
221
231
|
if (uiSourceCode) {
|
|
222
232
|
break;
|
|
@@ -62,57 +62,56 @@ export function parseRawFramesFromErrorStack(stack: string): RawFrame[]|null {
|
|
|
62
62
|
let evalOrigin: RawFrame|undefined;
|
|
63
63
|
|
|
64
64
|
const openParenIndex = lineContent.indexOf(' (');
|
|
65
|
+
let location = '';
|
|
65
66
|
if (lineContent.endsWith(')') && openParenIndex !== -1) {
|
|
66
67
|
functionName = lineContent.substring(0, openParenIndex).trim();
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
evalOriginStr = evalOriginStr.substring(8);
|
|
82
|
-
}
|
|
83
|
-
const innerOpenParen = evalOriginStr.indexOf(' (');
|
|
84
|
-
let evalFunctionName = evalOriginStr;
|
|
85
|
-
let evalLocation = '';
|
|
86
|
-
if (innerOpenParen !== -1) {
|
|
87
|
-
evalFunctionName = evalOriginStr.substring(0, innerOpenParen).trim();
|
|
88
|
-
evalLocation = evalOriginStr.substring(innerOpenParen + 2, evalOriginStr.length - 1);
|
|
89
|
-
evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName} (${evalLocation})`)?.[0];
|
|
90
|
-
} else {
|
|
91
|
-
evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName}`)?.[0];
|
|
92
|
-
}
|
|
68
|
+
location = lineContent.substring(openParenIndex + 2, lineContent.length - 1);
|
|
69
|
+
} else {
|
|
70
|
+
location = lineContent;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (location.startsWith('eval at ')) {
|
|
74
|
+
isEval = true;
|
|
75
|
+
const commaIndex = location.lastIndexOf(', ');
|
|
76
|
+
let evalOriginStr = location;
|
|
77
|
+
if (commaIndex !== -1) {
|
|
78
|
+
evalOriginStr = location.substring(0, commaIndex);
|
|
79
|
+
location = location.substring(commaIndex + 2);
|
|
80
|
+
} else {
|
|
81
|
+
location = '';
|
|
93
82
|
}
|
|
94
83
|
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
wasmFunctionIndex = parseInt(wasmMatch[2], 10);
|
|
106
|
-
columnNumber = parseInt(wasmMatch[3], 16);
|
|
107
|
-
}
|
|
84
|
+
if (evalOriginStr.startsWith('eval at ')) {
|
|
85
|
+
evalOriginStr = evalOriginStr.substring(8);
|
|
86
|
+
}
|
|
87
|
+
const innerOpenParen = evalOriginStr.indexOf(' (');
|
|
88
|
+
let evalFunctionName = evalOriginStr;
|
|
89
|
+
let evalLocation = '';
|
|
90
|
+
if (innerOpenParen !== -1) {
|
|
91
|
+
evalFunctionName = evalOriginStr.substring(0, innerOpenParen).trim();
|
|
92
|
+
evalLocation = evalOriginStr.substring(innerOpenParen + 2, evalOriginStr.length - 1);
|
|
93
|
+
evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName} (${evalLocation})`)?.[0];
|
|
108
94
|
} else {
|
|
109
|
-
|
|
110
|
-
url = splitResult.url;
|
|
111
|
-
lineNumber = splitResult.lineNumber ?? -1;
|
|
112
|
-
columnNumber = splitResult.columnNumber ?? -1;
|
|
95
|
+
evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName}`)?.[0];
|
|
113
96
|
}
|
|
114
|
-
}
|
|
115
|
-
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (location.startsWith('index ')) {
|
|
100
|
+
promiseIndex = parseInt(location.substring(6), 10);
|
|
101
|
+
url = '';
|
|
102
|
+
} else if (location === '<anonymous>' || location === 'native') {
|
|
103
|
+
url = '';
|
|
104
|
+
} else if (location.includes(':wasm-function[')) {
|
|
105
|
+
isWasm = true;
|
|
106
|
+
const wasmMatch = /^(.*):wasm-function\[(\d+)\]:(0x[0-9a-fA-F]+)$/.exec(location);
|
|
107
|
+
if (wasmMatch) {
|
|
108
|
+
url = wasmMatch[1];
|
|
109
|
+
wasmFunctionIndex = parseInt(wasmMatch[2], 10);
|
|
110
|
+
columnNumber = parseInt(wasmMatch[3], 16);
|
|
111
|
+
lineNumber = 0;
|
|
112
|
+
}
|
|
113
|
+
} else if (location) {
|
|
114
|
+
const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(location);
|
|
116
115
|
url = splitResult.url;
|
|
117
116
|
lineNumber = splitResult.lineNumber ?? -1;
|
|
118
117
|
columnNumber = splitResult.columnNumber ?? -1;
|
|
@@ -181,13 +180,7 @@ export function parseMessage(stack: string): string {
|
|
|
181
180
|
export function augmentRawFramesWithScriptIds(
|
|
182
181
|
rawFrames: RawFrame[], protocolStackTrace: Protocol.Runtime.StackTrace): void {
|
|
183
182
|
function augmentFrame(rawFrame: RawFrame): void {
|
|
184
|
-
const isWasm = rawFrame.isWasm;
|
|
185
183
|
const protocolFrame = protocolStackTrace.callFrames.find(frame => {
|
|
186
|
-
if (isWasm) {
|
|
187
|
-
// The parser parses Wasm offsets into the `columnNumber` field. The `lineNumber` is always -1.
|
|
188
|
-
// In the protocol trace, the `lineNumber` is 0 (for Wasm) and `columnNumber` is the bytecode offset.
|
|
189
|
-
return rawFrame.url === frame.url && rawFrame.columnNumber === frame.columnNumber;
|
|
190
|
-
}
|
|
191
184
|
return rawFrame.url === frame.url && rawFrame.lineNumber === frame.lineNumber &&
|
|
192
185
|
rawFrame.columnNumber === frame.columnNumber;
|
|
193
186
|
});
|
|
@@ -48,6 +48,13 @@ export interface Frame {
|
|
|
48
48
|
* Whether the corresponding raw frame is JS or WASM.
|
|
49
49
|
*/
|
|
50
50
|
readonly isWasm?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Whether this frame is an inlined frame. Used by SymbolizedErrorWidget
|
|
53
|
+
* to render the translated name (i.e. `name`) for inlined frames, and
|
|
54
|
+
* the physical name (i.e. `rawName`) for normal frames to preserve existing
|
|
55
|
+
* behavior.
|
|
56
|
+
*/
|
|
57
|
+
readonly isInline?: boolean;
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
export interface ParsedErrorStackFrame extends Frame {
|
|
@@ -89,11 +89,12 @@ export class FrameImpl implements StackTrace.StackTrace.Frame {
|
|
|
89
89
|
readonly missingDebugInfo?: StackTrace.StackTrace.MissingDebugInfo;
|
|
90
90
|
readonly rawName?: string;
|
|
91
91
|
readonly isWasm?: boolean;
|
|
92
|
+
readonly isInline?: boolean;
|
|
92
93
|
|
|
93
|
-
constructor(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
constructor(url: string|undefined, uiSourceCode: Workspace.UISourceCode.UISourceCode|undefined,
|
|
95
|
+
name: string|undefined, line: number, column: number,
|
|
96
|
+
missingDebugInfo?: StackTrace.StackTrace.MissingDebugInfo, rawName?: string, isWasm?: boolean,
|
|
97
|
+
isInline?: boolean) {
|
|
97
98
|
this.url = url;
|
|
98
99
|
this.uiSourceCode = uiSourceCode;
|
|
99
100
|
this.name = name;
|
|
@@ -102,6 +103,7 @@ export class FrameImpl implements StackTrace.StackTrace.Frame {
|
|
|
102
103
|
this.missingDebugInfo = missingDebugInfo;
|
|
103
104
|
this.rawName = rawName;
|
|
104
105
|
this.isWasm = isWasm;
|
|
106
|
+
this.isInline = isInline;
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -197,6 +199,9 @@ export class ParsedErrorStackFrameImpl implements StackTrace.StackTrace.ParsedEr
|
|
|
197
199
|
get isWasm(): boolean|undefined {
|
|
198
200
|
return this.#frame.isWasm;
|
|
199
201
|
}
|
|
202
|
+
get isInline(): boolean|undefined {
|
|
203
|
+
return this.#frame.isInline;
|
|
204
|
+
}
|
|
200
205
|
get wasmModuleName(): string|undefined {
|
|
201
206
|
return this.#parsedFrameInfo?.wasmModuleName;
|
|
202
207
|
}
|
|
@@ -291,6 +296,10 @@ export class DebuggableFrameImpl implements StackTrace.StackTrace.DebuggableFram
|
|
|
291
296
|
return this.#frame.isWasm;
|
|
292
297
|
}
|
|
293
298
|
|
|
299
|
+
get isInline(): boolean|undefined {
|
|
300
|
+
return this.#frame.isInline;
|
|
301
|
+
}
|
|
302
|
+
|
|
294
303
|
get sdkFrame(): SDK.DebuggerModel.CallFrame {
|
|
295
304
|
return this.#sdkFrame;
|
|
296
305
|
}
|