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.
Files changed (125) hide show
  1. package/eslint.config.mjs +3 -1
  2. package/extension-api/ExtensionAPI.d.ts +83 -12
  3. package/front_end/core/host/UserMetrics.ts +0 -1
  4. package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
  5. package/front_end/core/root/ExperimentNames.ts +0 -1
  6. package/front_end/core/sdk/ConsoleModel.ts +4 -0
  7. package/front_end/core/sdk/NetworkRequest.ts +12 -0
  8. package/front_end/core/sdk/SourceMap.ts +15 -18
  9. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -2
  10. package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
  11. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +4 -5
  12. package/front_end/entrypoints/main/MainImpl.ts +0 -6
  13. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  14. package/front_end/generated/protocol.ts +7 -0
  15. package/front_end/models/ai_assistance/AiAgent2.ts +24 -5
  16. package/front_end/models/ai_assistance/AiConversation.ts +15 -12
  17. package/front_end/models/ai_assistance/AiUtils.ts +71 -0
  18. package/front_end/models/ai_assistance/ChangeManager.ts +2 -5
  19. package/front_end/models/ai_assistance/{agents/ConversationSummaryAgent.ts → ConversationSummary.ts} +29 -66
  20. package/front_end/models/ai_assistance/ExtensionScope.ts +1 -4
  21. package/front_end/models/ai_assistance/{agents/PerformanceAnnotationsAgent.ts → PerformanceAnnotations.ts} +47 -89
  22. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +47 -31
  23. package/front_end/models/ai_assistance/agents/AiAgent.ts +40 -12
  24. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +11 -0
  25. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +58 -8
  26. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -92
  27. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +25 -0
  28. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +94 -79
  29. package/front_end/models/ai_assistance/agents/StorageAgent.ts +101 -39
  30. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -2
  31. package/front_end/models/ai_assistance/agents/StylingAgent.ts +27 -21
  32. package/front_end/models/ai_assistance/ai_assistance.ts +6 -4
  33. package/front_end/models/ai_assistance/skills/styling.md +12 -4
  34. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +134 -0
  35. package/front_end/models/ai_assistance/tools/GetStyles.ts +6 -2
  36. package/front_end/models/ai_assistance/tools/Tool.ts +16 -1
  37. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +2 -0
  38. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +6 -9
  39. package/front_end/models/bindings/DefaultScriptMapping.ts +2 -1
  40. package/front_end/models/bindings/SymbolizedError.ts +45 -35
  41. package/front_end/models/extensions/ExtensionAPI.ts +138 -47
  42. package/front_end/models/har/Importer.ts +1 -0
  43. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +5 -7
  44. package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +12 -2
  45. package/front_end/models/stack_trace/DetailedErrorStackParser.ts +44 -51
  46. package/front_end/models/stack_trace/StackTrace.ts +7 -0
  47. package/front_end/models/stack_trace/StackTraceImpl.ts +13 -4
  48. package/front_end/models/stack_trace/StackTraceModel.ts +9 -8
  49. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +2 -1
  50. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -8
  51. package/front_end/panels/ai_assistance/components/ChatMessage.ts +96 -4
  52. package/front_end/panels/ai_assistance/components/chatMessage.css +6 -0
  53. package/front_end/panels/application/ApplicationPanelSidebar.ts +39 -0
  54. package/front_end/panels/application/ApplicationPanelTreeElement.ts +39 -0
  55. package/front_end/panels/application/CookieItemsView.ts +2 -2
  56. package/front_end/panels/application/components/AdsView.ts +219 -0
  57. package/front_end/panels/application/components/adsView.css +54 -0
  58. package/front_end/panels/application/components/components.ts +2 -0
  59. package/front_end/panels/application/resourcesSidebar.css +11 -0
  60. package/front_end/panels/console/SymbolizedErrorWidget.ts +79 -25
  61. package/front_end/panels/network/NetworkLogView.ts +5 -1
  62. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -0
  63. package/front_end/panels/sources/SourcesPanel.ts +2 -1
  64. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +5 -4
  65. package/front_end/third_party/chromium/README.chromium +1 -1
  66. package/front_end/third_party/lighthouse/README.chromium +2 -2
  67. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1607 -5733
  68. package/front_end/third_party/lighthouse/locales/ar-XB.json +290 -65
  69. package/front_end/third_party/lighthouse/locales/ar.json +290 -65
  70. package/front_end/third_party/lighthouse/locales/bg.json +290 -65
  71. package/front_end/third_party/lighthouse/locales/ca.json +295 -70
  72. package/front_end/third_party/lighthouse/locales/cs.json +290 -65
  73. package/front_end/third_party/lighthouse/locales/da.json +294 -69
  74. package/front_end/third_party/lighthouse/locales/de.json +295 -70
  75. package/front_end/third_party/lighthouse/locales/el.json +290 -65
  76. package/front_end/third_party/lighthouse/locales/en-GB.json +290 -65
  77. package/front_end/third_party/lighthouse/locales/en-US.json +79 -67
  78. package/front_end/third_party/lighthouse/locales/en-XA.json +253 -64
  79. package/front_end/third_party/lighthouse/locales/en-XL.json +79 -67
  80. package/front_end/third_party/lighthouse/locales/es-419.json +290 -65
  81. package/front_end/third_party/lighthouse/locales/es.json +298 -73
  82. package/front_end/third_party/lighthouse/locales/fi.json +290 -65
  83. package/front_end/third_party/lighthouse/locales/fil.json +290 -65
  84. package/front_end/third_party/lighthouse/locales/fr.json +294 -69
  85. package/front_end/third_party/lighthouse/locales/he.json +293 -68
  86. package/front_end/third_party/lighthouse/locales/hi.json +291 -66
  87. package/front_end/third_party/lighthouse/locales/hr.json +290 -65
  88. package/front_end/third_party/lighthouse/locales/hu.json +290 -65
  89. package/front_end/third_party/lighthouse/locales/id.json +290 -65
  90. package/front_end/third_party/lighthouse/locales/it.json +294 -69
  91. package/front_end/third_party/lighthouse/locales/ja.json +290 -65
  92. package/front_end/third_party/lighthouse/locales/ko.json +290 -65
  93. package/front_end/third_party/lighthouse/locales/lt.json +290 -65
  94. package/front_end/third_party/lighthouse/locales/lv.json +290 -65
  95. package/front_end/third_party/lighthouse/locales/nl.json +290 -65
  96. package/front_end/third_party/lighthouse/locales/no.json +290 -65
  97. package/front_end/third_party/lighthouse/locales/pl.json +290 -65
  98. package/front_end/third_party/lighthouse/locales/pt-PT.json +291 -66
  99. package/front_end/third_party/lighthouse/locales/pt.json +290 -65
  100. package/front_end/third_party/lighthouse/locales/ro.json +290 -65
  101. package/front_end/third_party/lighthouse/locales/ru.json +301 -76
  102. package/front_end/third_party/lighthouse/locales/sk.json +291 -66
  103. package/front_end/third_party/lighthouse/locales/sl.json +290 -65
  104. package/front_end/third_party/lighthouse/locales/sr-Latn.json +290 -65
  105. package/front_end/third_party/lighthouse/locales/sr.json +290 -65
  106. package/front_end/third_party/lighthouse/locales/sv.json +297 -72
  107. package/front_end/third_party/lighthouse/locales/ta.json +291 -66
  108. package/front_end/third_party/lighthouse/locales/te.json +293 -68
  109. package/front_end/third_party/lighthouse/locales/th.json +291 -66
  110. package/front_end/third_party/lighthouse/locales/tr.json +290 -65
  111. package/front_end/third_party/lighthouse/locales/uk.json +290 -65
  112. package/front_end/third_party/lighthouse/locales/vi.json +291 -66
  113. package/front_end/third_party/lighthouse/locales/zh-HK.json +292 -67
  114. package/front_end/third_party/lighthouse/locales/zh-TW.json +291 -66
  115. package/front_end/third_party/lighthouse/locales/zh.json +291 -66
  116. package/front_end/third_party/lighthouse/report/bundle.d.ts +6 -6
  117. package/front_end/third_party/lighthouse/report/bundle.js +4 -7
  118. package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
  119. package/front_end/ui/legacy/StackedPane.ts +229 -0
  120. package/front_end/ui/legacy/ViewManager.ts +59 -169
  121. package/front_end/ui/legacy/Widget.ts +32 -8
  122. package/front_end/ui/legacy/legacy.ts +3 -1
  123. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  124. package/mcp/mcp.ts +1 -0
  125. 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
- this.#project.addUISourceCodeWithProvider(uiSourceCode, script, null, 'text/javascript');
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|SymbolizedSyntaxError|UnparsableError;
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
- #fireUpdated(): void {
68
- this.dispatchEventToListeners(Events.UPDATED);
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
- get uiLocation(): Workspace.UISourceCode.UILocation|null {
82
- return this.#uiLocation;
83
- }
84
-
85
- static async fromExceptionDetails(
86
- target: SDK.Target.Target, debuggerWorkspaceBinding: DebuggerWorkspaceBinding,
87
- exceptionDetails: Protocol.Runtime.ExceptionDetails): Promise<SymbolizedSyntaxError|null> {
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('SymbolizedSyntaxError.fromExceptionDetails expects a SyntaxError');
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 null;
97
+ return symbolizedError;
94
98
  }
95
99
 
96
- const debuggerModel = target.model(SDK.DebuggerModel.DebuggerModel);
97
- if (!debuggerModel) {
98
- return null;
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
- const rawLocation = debuggerModel.createRawLocationByScriptId(scriptId, lineNumber, columnNumber);
102
- const symbolizedSyntaxError = new SymbolizedSyntaxError(exception.description || '');
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
- return symbolizedSyntaxError;
118
+ async #updateSyntaxErrorLocation(liveLocation: LiveLocation): Promise<void> {
119
+ this.#syntaxErrorLocation = await liveLocation.uiLocation();
120
+ this.dispatchEventToListeners(Events.UPDATED);
110
121
  }
111
122
 
112
- async #update(liveLocation: LiveLocation): Promise<void> {
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
- expression: string,
1252
- evaluateOptions: {scriptExecutionContext?: string, frameURL?: string, useContentScriptContext?: boolean}):
1253
- Object |
1254
- null {
1255
- const callback = extractCallbackArgument(arguments);
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
- const {isError, isException, value} = result as {
1258
- value: unknown,
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
- if (isError || isException) {
1263
- callback?.(undefined, result);
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
- callback?.(value);
1320
+ callbackArg?.(res.value);
1266
1321
  }
1267
1322
  }
1268
1323
  extensionServer.sendRequest(
1269
- {
1270
- command: PrivateAPI.Commands.EvaluateOnInspectedPage,
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
- getResources: function(callback?: (resources: PublicAPI.Chrome.DevTools.Resource[]) => unknown): void {
1279
- function wrapResource(resourceData: APIImpl.ResourceData): APIImpl.Resource {
1280
- return new (Constructor(Resource))(resourceData);
1281
- }
1282
- function callbackWrapper(resources: unknown): void {
1283
- callback?.((resources as APIImpl.ResourceData[]).map(wrapResource));
1284
- }
1285
- extensionServer.sendRequest({command: PrivateAPI.Commands.GetPageResources}, callback && callbackWrapper);
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 Pick<
1296
- APIImpl.Resource,
1297
- 'url'|'type'|'buildId'|'getContent'|'setContent'|'setFunctionRangesForScript'|'attachSourceMapURL'>) = {
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, callback?: (content: string, encoding: string) => unknown): void {
1311
- function callbackWrapper(response: unknown): void {
1312
- const {content, encoding} = response as {content: string, encoding: string};
1313
- callback?.(content, encoding);
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
- extensionServer.sendRequest(
1317
- {command: PrivateAPI.Commands.GetResourceContent, url: this._url}, callback && callbackWrapper);
1318
- },
1382
+ function callbackWrapper(response: unknown): void {
1383
+ if (checkErrorAndReject(response, reject)) {
1384
+ return;
1385
+ }
1319
1386
 
1320
- setContent: function(
1321
- this: APIImpl.Resource, content: string, commit: boolean, callback: (error?: Object) => unknown): void {
1322
- extensionServer.sendRequest(
1323
- {command: PrivateAPI.Commands.SetResourceContent, url: this._url, content, commit},
1324
- callback as (response: unknown) => unknown);
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
- this: APIImpl.Resource, ranges: PublicAPI.Chrome.DevTools.NamedFunctionRange[]): Promise<void> {
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?: string;
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: string,
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: string, classKey: string): HeapSnapshotProviderProxy {
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(): string|undefined {
392
+ get uid(): number|undefined {
395
393
  return this.profileUid;
396
394
  }
397
395
 
398
- setProfileUid(profileUid: string): void {
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
- * The input location may be a source mapped location or a raw location.
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
- let location = lineContent.substring(openParenIndex + 2, lineContent.length - 1);
68
-
69
- if (location.startsWith('eval at ')) {
70
- isEval = true;
71
- const commaIndex = location.lastIndexOf(', ');
72
- let evalOriginStr = location;
73
- if (commaIndex !== -1) {
74
- evalOriginStr = location.substring(0, commaIndex);
75
- location = location.substring(commaIndex + 2);
76
- } else {
77
- location = '';
78
- }
79
-
80
- if (evalOriginStr.startsWith('eval at ')) {
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 (location.startsWith('index ')) {
96
- promiseIndex = parseInt(location.substring(6), 10);
97
- url = '';
98
- } else if (location === '<anonymous>' || location === 'native') {
99
- url = '';
100
- } else if (location.includes(':wasm-function[')) {
101
- isWasm = true;
102
- const wasmMatch = /^(.*):wasm-function\[(\d+)\]:(0x[0-9a-fA-F]+)$/.exec(location);
103
- if (wasmMatch) {
104
- url = wasmMatch[1];
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
- const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(location);
110
- url = splitResult.url;
111
- lineNumber = splitResult.lineNumber ?? -1;
112
- columnNumber = splitResult.columnNumber ?? -1;
95
+ evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName}`)?.[0];
113
96
  }
114
- } else {
115
- const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(lineContent);
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
- url: string|undefined, uiSourceCode: Workspace.UISourceCode.UISourceCode|undefined, name: string|undefined,
95
- line: number, column: number, missingDebugInfo?: StackTrace.StackTrace.MissingDebugInfo, rawName?: string,
96
- isWasm?: boolean) {
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
  }