chrome-devtools-frontend 1.0.1645245 → 1.0.1646286

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 (42) hide show
  1. package/.agents/skills/devtools-source-maps/SKILL.md +124 -0
  2. package/docs/README.md +1 -0
  3. package/docs/using_source_maps.md +159 -0
  4. package/front_end/core/host/AidaClientTypes.ts +2 -0
  5. package/front_end/core/host/UserMetrics.ts +2 -1
  6. package/front_end/core/root/Runtime.ts +10 -0
  7. package/front_end/core/sdk/DebuggerModel.ts +7 -9
  8. package/front_end/core/sdk/NetworkRequest.ts +0 -24
  9. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  10. package/front_end/generated/SupportedCSSProperties.js +75 -0
  11. package/front_end/generated/protocol.ts +0 -5
  12. package/front_end/models/ai_assistance/AiAgent2.ts +29 -2
  13. package/front_end/models/ai_assistance/AiConversation.ts +4 -2
  14. package/front_end/models/ai_assistance/AiOrigins.ts +63 -2
  15. package/front_end/models/ai_assistance/README.md +15 -4
  16. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +2 -2
  17. package/front_end/models/ai_assistance/agents/FileAgent.ts +9 -42
  18. package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +2 -2
  19. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +9 -133
  20. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +10 -2
  21. package/front_end/models/ai_assistance/agents/README.md +7 -0
  22. package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
  23. package/front_end/models/ai_assistance/contexts/FileContext.ts +45 -0
  24. package/front_end/models/ai_assistance/contexts/RequestContext.snapshot.txt +48 -0
  25. package/front_end/models/ai_assistance/contexts/RequestContext.ts +116 -0
  26. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +2 -1
  27. package/front_end/models/ai_assistance/tools/README.md +1 -1
  28. package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +15 -11
  29. package/front_end/models/web_mcp/WebMCPModel.ts +8 -48
  30. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +13 -13
  31. package/front_end/panels/ai_assistance/components/ChatInput.ts +4 -4
  32. package/front_end/panels/application/ApplicationPanelSidebar.ts +25 -0
  33. package/front_end/panels/application/WebMCPView.ts +40 -70
  34. package/front_end/panels/application/components/AdsView.ts +31 -28
  35. package/front_end/panels/application/components/adsView.css +6 -0
  36. package/front_end/panels/common/ExtensionServer.ts +5 -0
  37. package/front_end/panels/profiler/IsolateSelector.ts +4 -2
  38. package/front_end/panels/profiler/ProfileLauncherView.ts +194 -126
  39. package/front_end/panels/profiler/ProfilesPanel.ts +1 -3
  40. package/front_end/third_party/chromium/README.chromium +1 -1
  41. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  42. package/package.json +1 -1
@@ -576,12 +576,12 @@ function createDOMNodeContext(node: SDK.DOMModel.DOMNode|null): AiAssistanceMode
576
576
  return new AiAssistanceModel.DOMNodeContext.DOMNodeContext(node);
577
577
  }
578
578
 
579
- function createFileContext(file: Workspace.UISourceCode.UISourceCode|null): AiAssistanceModel.FileAgent.FileContext|
579
+ function createFileContext(file: Workspace.UISourceCode.UISourceCode|null): AiAssistanceModel.FileContext.FileContext|
580
580
  null {
581
581
  if (!file) {
582
582
  return null;
583
583
  }
584
- return new AiAssistanceModel.FileAgent.FileContext(file);
584
+ return new AiAssistanceModel.FileContext.FileContext(file);
585
585
  }
586
586
 
587
587
  function createAccessibilityContext(report: LighthousePanel.LighthousePanel.ActiveLighthouseReport|null):
@@ -592,13 +592,13 @@ function createAccessibilityContext(report: LighthousePanel.LighthousePanel.Acti
592
592
  return new AiAssistanceModel.AccessibilityAgent.AccessibilityContext(report.report);
593
593
  }
594
594
 
595
- function createRequestContext(request: SDK.NetworkRequest.NetworkRequest|null):
596
- AiAssistanceModel.NetworkAgent.RequestContext|null {
595
+ function createRequestContext(request: SDK.NetworkRequest.NetworkRequest|
596
+ null): AiAssistanceModel.RequestContext.RequestContext|null {
597
597
  if (!request) {
598
598
  return null;
599
599
  }
600
600
  const calculator = NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
601
- return new AiAssistanceModel.NetworkAgent.RequestContext(request, calculator);
601
+ return new AiAssistanceModel.RequestContext.RequestContext(request, calculator);
602
602
  }
603
603
 
604
604
  function createPerformanceTraceContext(focus: AiAssistanceModel.AIContext.AgentFocus|null):
@@ -666,10 +666,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
666
666
 
667
667
  #conversation?: AiAssistanceModel.AiConversation.AiConversation;
668
668
 
669
- #selectedFile: AiAssistanceModel.FileAgent.FileContext|null = null;
669
+ #selectedFile: AiAssistanceModel.FileContext.FileContext|null = null;
670
670
  #selectedElement: AiAssistanceModel.DOMNodeContext.DOMNodeContext|null = null;
671
671
  #selectedPerformanceTrace: AiAssistanceModel.PerformanceAgent.PerformanceTraceContext|null = null;
672
- #selectedRequest: AiAssistanceModel.NetworkAgent.RequestContext|null = null;
672
+ #selectedRequest: AiAssistanceModel.RequestContext.RequestContext|null = null;
673
673
 
674
674
  #selectedAccessibility: AiAssistanceModel.AccessibilityAgent.AccessibilityContext|null = null;
675
675
  #selectedStorage: AiAssistanceModel.StorageAgent.StorageContext|null = null;
@@ -1254,7 +1254,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1254
1254
 
1255
1255
  if (Boolean(ev.data)) {
1256
1256
  const calculator = NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
1257
- this.#selectedRequest = new AiAssistanceModel.NetworkAgent.RequestContext(ev.data, calculator);
1257
+ this.#selectedRequest = new AiAssistanceModel.RequestContext.RequestContext(ev.data, calculator);
1258
1258
  } else {
1259
1259
  this.#selectedRequest = null;
1260
1260
  }
@@ -1280,7 +1280,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1280
1280
  if (!newFile || this.#selectedFile?.getItem() === newFile) {
1281
1281
  return;
1282
1282
  }
1283
- this.#selectedFile = new AiAssistanceModel.FileAgent.FileContext(ev.data);
1283
+ this.#selectedFile = new AiAssistanceModel.FileContext.FileContext(ev.data);
1284
1284
  this.#updateConversationState(this.#conversation);
1285
1285
  };
1286
1286
 
@@ -1488,12 +1488,12 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1488
1488
  }
1489
1489
 
1490
1490
  const context = this.#conversation.selectedContext;
1491
- if (context instanceof AiAssistanceModel.NetworkAgent.RequestContext) {
1491
+ if (context instanceof AiAssistanceModel.RequestContext.RequestContext) {
1492
1492
  const requestLocation = NetworkForward.UIRequestLocation.UIRequestLocation.tab(
1493
1493
  context.getItem(), NetworkForward.UIRequestLocation.UIRequestTabs.HEADERS_COMPONENT);
1494
1494
  return Common.Revealer.reveal(requestLocation);
1495
1495
  }
1496
- if (context instanceof AiAssistanceModel.FileAgent.FileContext) {
1496
+ if (context instanceof AiAssistanceModel.FileContext.FileContext) {
1497
1497
  return Common.Revealer.reveal(context.getItem().uiLocation(0, 0));
1498
1498
  }
1499
1499
  if (context instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext) {
@@ -1733,11 +1733,11 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1733
1733
  }
1734
1734
 
1735
1735
  #handleConversationContextChange = (data: unknown): void => {
1736
- if (data instanceof AiAssistanceModel.FileAgent.FileContext) {
1736
+ if (data instanceof AiAssistanceModel.FileContext.FileContext) {
1737
1737
  this.#selectedFile = data;
1738
1738
  } else if (data instanceof AiAssistanceModel.DOMNodeContext.DOMNodeContext) {
1739
1739
  this.#selectedElement = data;
1740
- } else if (data instanceof AiAssistanceModel.NetworkAgent.RequestContext) {
1740
+ } else if (data instanceof AiAssistanceModel.RequestContext.RequestContext) {
1741
1741
  this.#selectedRequest = data;
1742
1742
  } else if (data instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext) {
1743
1743
  this.#selectedPerformanceTrace = data;
@@ -171,13 +171,13 @@ export type ViewOutput = undefined;
171
171
 
172
172
  function getContextRemoveLabel(context: AiAssistanceModel.AiAgent.ConversationContext<unknown>):
173
173
  Platform.UIString.LocalizedString {
174
- if (context instanceof AiAssistanceModel.FileAgent.FileContext) {
174
+ if (context instanceof AiAssistanceModel.FileContext.FileContext) {
175
175
  return lockedString(UIStringsNotTranslate.removeContextFile);
176
176
  }
177
177
  if (context instanceof AiAssistanceModel.DOMNodeContext.DOMNodeContext) {
178
178
  return lockedString(UIStringsNotTranslate.removeContextElement);
179
179
  }
180
- if (context instanceof AiAssistanceModel.NetworkAgent.RequestContext) {
180
+ if (context instanceof AiAssistanceModel.RequestContext.RequestContext) {
181
181
  return lockedString(UIStringsNotTranslate.removeContextRequest);
182
182
  }
183
183
  if (context instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext) {
@@ -351,9 +351,9 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
351
351
  })}
352
352
  ></devtools-widget>` :
353
353
  html`
354
- ${input.context instanceof AiAssistanceModel.NetworkAgent.RequestContext ?
354
+ ${input.context instanceof AiAssistanceModel.RequestContext.RequestContext ?
355
355
  PanelUtils.PanelUtils.getIconForNetworkRequest(input.context.getItem()) :
356
- input.context instanceof AiAssistanceModel.FileAgent.FileContext ?
356
+ input.context instanceof AiAssistanceModel.FileContext.FileContext ?
357
357
  PanelUtils.PanelUtils.getIconForSourceFile(input.context.getItem()) :
358
358
  input.context instanceof AiAssistanceModel.AccessibilityAgent.AccessibilityContext ?
359
359
  html`<devtools-icon class="icon" name="performance" title="Lighthouse"></devtools-icon>` :
@@ -52,6 +52,7 @@ import {BackForwardCacheTreeElement} from './BackForwardCacheTreeElement.js';
52
52
  import {BackgroundServiceModel} from './BackgroundServiceModel.js';
53
53
  import {BackgroundServiceView} from './BackgroundServiceView.js';
54
54
  import {BounceTrackingMitigationsTreeElement} from './BounceTrackingMitigationsTreeElement.js';
55
+ import * as ApplicationComponents from './components/components.js';
55
56
  import {DeviceBoundSessionsModel} from './DeviceBoundSessionsModel.js';
56
57
  import {RootTreeElement as DeviceBoundSessionsRootTreeElement} from './DeviceBoundSessionsTreeElement.js';
57
58
  import {
@@ -110,6 +111,10 @@ const UIStrings = {
110
111
  * @description Text in Application Panel Sidebar of the Application panel
111
112
  */
112
113
  application: 'Application',
114
+ /**
115
+ * @description Text in Application Panel Sidebar of the Application panel
116
+ */
117
+ ads: 'Ads',
113
118
  /**
114
119
  * @description Text in Application Panel Sidebar of the Application panel
115
120
  */
@@ -354,6 +359,7 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
354
359
  pushMessagingTreeElement: BackgroundServiceTreeElement;
355
360
  reportingApiTreeElement: ReportingApiTreeElement;
356
361
  webMcpTreeElement?: WebMCPTreeElement;
362
+ adsTreeElement?: ApplicationPanelTreeElement;
357
363
  deviceBoundSessionsRootTreeElement: DeviceBoundSessionsRootTreeElement|undefined;
358
364
  deviceBoundSessionsModel: DeviceBoundSessionsModel|undefined;
359
365
  preloadingSummaryTreeElement: PreloadingSummaryTreeElement|undefined;
@@ -403,6 +409,25 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
403
409
  this.applicationTreeElement.appendChild(this.webMcpTreeElement);
404
410
  }
405
411
 
412
+ if (Root.Runtime.hostConfig.devToolsAdsPanel?.enabled) {
413
+ const adsTreeElement = new ApplicationPanelTreeElement(panel, i18nString(UIStrings.ads), false, 'ads');
414
+ const icon = createIcon('experiment');
415
+ adsTreeElement.setLeadingIcons([icon]);
416
+ adsTreeElement.itemURL = 'ads://' as Platform.DevToolsPath.UrlString;
417
+ let adsView: ApplicationComponents.AdsView.AdsView;
418
+ adsTreeElement.onselect = (selectedByUser?: boolean): boolean => {
419
+ ApplicationPanelTreeElement.prototype.onselect.call(adsTreeElement, selectedByUser);
420
+ if (!adsView) {
421
+ adsView = new ApplicationComponents.AdsView.AdsView();
422
+ }
423
+ adsTreeElement.showView(adsView);
424
+ UI.UIUserMetrics.UIUserMetrics.instance().panelShown('ads');
425
+ return false;
426
+ };
427
+ this.adsTreeElement = adsTreeElement;
428
+ this.applicationTreeElement.appendChild(this.adsTreeElement);
429
+ }
430
+
406
431
  const storageSectionTitle = i18nString(UIStrings.storage);
407
432
  const storageTreeElement = this.addSidebarSection(storageSectionTitle, 'storage');
408
433
  this.localStorageListTreeElement = new ExpandableApplicationPanelTreeElement(
@@ -16,6 +16,7 @@ import * as i18n from '../../core/i18n/i18n.js';
16
16
  import * as Platform from '../../core/platform/platform.js';
17
17
  import * as SDK from '../../core/sdk/sdk.js';
18
18
  import * as Protocol from '../../generated/protocol.js';
19
+ import type * as Bindings from '../../models/bindings/bindings.js';
19
20
  import type * as StackTrace from '../../models/stack_trace/stack_trace.js';
20
21
  import * as WebMCP from '../../models/web_mcp/web_mcp.js';
21
22
  import * as Adorners from '../../ui/components/adorners/adorners.js';
@@ -33,6 +34,8 @@ import {
33
34
  type TemplateResult,
34
35
  } from '../../ui/lit/lit.js';
35
36
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
37
+ import * as Console from '../console/console.js';
38
+ import symbolizedErrorWidgetStyles from '../console/symbolizedErrorWidget.css.js';
36
39
  import * as ProtocolMonitor from '../protocol_monitor/protocol_monitor.js';
37
40
 
38
41
  import webMCPViewStyles from './webMCPView.css.js';
@@ -191,10 +194,6 @@ const UIStrings = {
191
194
  * @description Notice to display when a tool has been unregistered
192
195
  */
193
196
  toolUnregisteredNotice: 'This tool has been unregistered',
194
- /**
195
- * @description Text preceding a nested error in a stack trace
196
- */
197
- causedBy: 'Caused by:',
198
197
  } as const;
199
198
  const str_ = i18n.i18n.registerUIStrings('panels/application/WebMCPView.ts', UIStrings);
200
199
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -592,7 +591,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
592
591
  ${widget(PayloadWidget, {
593
592
  valueObject: input.selectedCall?.result?.output,
594
593
  errorText: input.selectedCall?.result?.errorText,
595
- exceptionDetails: input.selectedCall?.result?.exceptionDetails,
594
+ symbolizedError: input.selectedCall?.result?.symbolizedError,
596
595
  })}>
597
596
  </devtools-widget>
598
597
  </devtools-tabbed-pane>
@@ -953,11 +952,11 @@ export interface PayloadViewInput {
953
952
  valueObject?: unknown;
954
953
  valueString?: string;
955
954
  errorText?: string;
956
- exceptionDetails?: WebMCP.WebMCPModel.ExceptionDetails;
955
+ symbolizedError?: Bindings.SymbolizedError.SymbolizedError|null;
957
956
  }
958
957
 
959
958
  export const PAYLOAD_DEFAULT_VIEW = (input: PayloadViewInput, output: object, target: HTMLElement): void => {
960
- if (!input.valueObject && !input.valueString && !input.errorText && !input.exceptionDetails) {
959
+ if (!input.valueObject && !input.valueString && !input.errorText && !input.symbolizedError) {
961
960
  render(nothing, target);
962
961
  return;
963
962
  }
@@ -988,73 +987,44 @@ export const PAYLOAD_DEFAULT_VIEW = (input: PayloadViewInput, output: object, ta
988
987
  html`<div class="payload-value source-code error-text">${text}</div>`;
989
988
 
990
989
  const createException = (
991
- details: WebMCP.WebMCPModel.ExceptionDetails,
992
- linkifier: Components.Linkifier.Linkifier = new Components.Linkifier.Linkifier(),
993
- ): TemplateResult => {
994
- const renderFrame = (
995
- frame: StackTrace.ErrorStackParser.ParsedErrorFrame,
996
- index: number,
997
- array: StackTrace.ErrorStackParser.ParsedErrorFrame[],
998
- ): TemplateResult => {
999
- const newline = index < array.length - 1 ? '\n' : '';
1000
- const {line, link, isCallFrame} = frame;
1001
-
1002
- if (!isCallFrame) {
1003
- return html`<span>${line}${newline}</span>`;
1004
- }
1005
-
1006
- if (!link) {
1007
- return html`<span class="formatted-builtin-stack-frame">${line}${newline}</span>`;
1008
- }
1009
-
1010
- const scriptLocationLink = linkifier.linkifyScriptLocation(
1011
- details.error.runtimeModel().target(),
1012
- link.scriptId || null,
1013
- link.url,
1014
- link.lineNumber,
1015
- {
1016
- columnNumber: link.columnNumber,
1017
- showColumnNumber: true,
1018
- },
1019
- );
1020
- scriptLocationLink.tabIndex = -1;
1021
-
1022
- return html`<span class="formatted-stack-frame">${link.prefix}${scriptLocationLink}${link.suffix}${
1023
- newline}</span>`;
1024
- };
1025
-
990
+ error: Bindings.SymbolizedError.SymbolizedError|null,
991
+ ): TemplateResult|typeof nothing => {
992
+ if (!error) {
993
+ return nothing;
994
+ }
1026
995
  return html`
1027
996
  <div class="payload-value source-code error-text">
1028
- ${details.frames.length === 0 && details.description ? html`<span>${details.description}\n</span>` : nothing}
1029
- <div>${details.frames.map(renderFrame)}</div>
1030
- ${
1031
- details.cause ? html`\n${i18nString(UIStrings.causedBy)}\n${createException(details.cause, linkifier)}` :
1032
- nothing}</div>`;
997
+ <devtools-widget
998
+ ${UI.Widget.widget(Console.SymbolizedErrorWidget.SymbolizedErrorWidget, {error})}
999
+ ></devtools-widget>
1000
+ </div>
1001
+ `;
1033
1002
  };
1034
1003
 
1035
- render(
1036
- html`
1004
+ render(html`
1037
1005
  <style>${webMCPViewStyles}</style>
1006
+ <style>${symbolizedErrorWidgetStyles}</style>
1038
1007
  <div class="call-payload-view">
1039
1008
  <div class="call-payload-content">
1040
1009
  ${
1041
- isParsable ? createPayload(input.valueObject) :
1042
- (input.valueString !== undefined ?
1043
- createSourceText(input.valueString) :
1044
- (input.exceptionDetails ? createException(input.exceptionDetails) :
1045
- (input.errorText ? createErrorText(input.errorText) : nothing)))}
1010
+ isParsable ?
1011
+ createPayload(input.valueObject) :
1012
+ (input.valueString !== undefined ?
1013
+ createSourceText(input.valueString) :
1014
+ (input.symbolizedError ? createException(input.symbolizedError) :
1015
+ (input.errorText ? createErrorText(input.errorText) : nothing)))}
1046
1016
  </div>
1047
1017
  </div>
1048
1018
  `,
1049
- target);
1019
+ target);
1050
1020
  };
1051
1021
 
1052
1022
  export class PayloadWidget extends UI.Widget.Widget {
1053
1023
  #valueObject?: unknown;
1054
1024
  #valueString?: string;
1055
1025
  #errorText?: string;
1056
- #exceptionDetailsPromise?: Promise<WebMCP.WebMCPModel.ExceptionDetails|undefined>;
1057
- #exceptionDetails?: WebMCP.WebMCPModel.ExceptionDetails;
1026
+ #symbolizedErrorPromise?: Promise<Bindings.SymbolizedError.SymbolizedError|null>;
1027
+ #symbolizedError?: Bindings.SymbolizedError.SymbolizedError|null;
1058
1028
  #view: typeof PAYLOAD_DEFAULT_VIEW;
1059
1029
 
1060
1030
  constructor(element?: HTMLElement, view = PAYLOAD_DEFAULT_VIEW) {
@@ -1089,27 +1059,27 @@ export class PayloadWidget extends UI.Widget.Widget {
1089
1059
  return this.#errorText;
1090
1060
  }
1091
1061
 
1092
- async #updateExceptionDetails(
1093
- exceptionDetailsPromise: Promise<WebMCP.WebMCPModel.ExceptionDetails|undefined>|undefined): Promise<void> {
1094
- if (this.#exceptionDetailsPromise === exceptionDetailsPromise) {
1062
+ async #updateSymbolizedError(symbolizedErrorPromise: Promise<Bindings.SymbolizedError.SymbolizedError|null>|
1063
+ undefined): Promise<void> {
1064
+ if (this.#symbolizedErrorPromise === symbolizedErrorPromise) {
1095
1065
  return;
1096
1066
  }
1097
- this.#exceptionDetailsPromise = exceptionDetailsPromise;
1098
- this.#exceptionDetails = undefined;
1067
+ this.#symbolizedErrorPromise = symbolizedErrorPromise;
1068
+ this.#symbolizedError = undefined;
1099
1069
  this.requestUpdate();
1100
- const exceptionDetails = await exceptionDetailsPromise;
1101
- if (this.#exceptionDetailsPromise === exceptionDetailsPromise) {
1102
- this.#exceptionDetails = exceptionDetails;
1070
+ const symbolizedError = await symbolizedErrorPromise;
1071
+ if (this.#symbolizedErrorPromise === symbolizedErrorPromise) {
1072
+ this.#symbolizedError = symbolizedError || null;
1103
1073
  this.requestUpdate();
1104
1074
  }
1105
1075
  }
1106
1076
 
1107
- set exceptionDetails(exceptionDetailsPromise: Promise<WebMCP.WebMCPModel.ExceptionDetails|undefined>|undefined) {
1108
- void this.#updateExceptionDetails(exceptionDetailsPromise);
1077
+ set symbolizedError(symbolizedErrorPromise: Promise<Bindings.SymbolizedError.SymbolizedError|null>|undefined) {
1078
+ void this.#updateSymbolizedError(symbolizedErrorPromise);
1109
1079
  }
1110
1080
 
1111
- get exceptionDetails(): Promise<WebMCP.WebMCPModel.ExceptionDetails|undefined>|undefined {
1112
- return this.#exceptionDetailsPromise;
1081
+ get symbolizedError(): Promise<Bindings.SymbolizedError.SymbolizedError|null>|undefined {
1082
+ return this.#symbolizedErrorPromise;
1113
1083
  }
1114
1084
  override wasShown(): void {
1115
1085
  super.wasShown();
@@ -1121,7 +1091,7 @@ export class PayloadWidget extends UI.Widget.Widget {
1121
1091
  valueObject: this.#valueObject,
1122
1092
  valueString: this.#valueString,
1123
1093
  errorText: this.#errorText,
1124
- exceptionDetails: this.#exceptionDetails,
1094
+ symbolizedError: this.#symbolizedError,
1125
1095
  };
1126
1096
  this.#view(input, {}, this.contentElement);
1127
1097
  }
@@ -7,6 +7,7 @@ import * as SDK from '../../../core/sdk/sdk.js';
7
7
  import type * as Protocol from '../../../generated/protocol.js';
8
8
  import * as UI from '../../../ui/legacy/legacy.js';
9
9
  import * as Lit from '../../../ui/lit/lit.js';
10
+ import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
10
11
 
11
12
  import adsViewStyles from './adsView.css.js';
12
13
 
@@ -89,34 +90,36 @@ const DEFAULT_VIEW: View = (input, output, target) => {
89
90
  // clang-format off
90
91
  Lit.render(html`
91
92
  <style>${adsViewStyles}</style>
92
- <dl class="metrics-container">
93
- <div class="metric-box">
94
- <dt class="metric-title">${i18nString(UIStrings.viewportAdDensity)}</dt>
95
- <dd class="metric-value">
96
- <span>${formatValue(metrics.viewportAdDensityByArea, true)}</span>
97
- <span class="metric-average">${i18nString(UIStrings.average, {PH1: formatAverage(metrics.averageViewportAdDensityByArea, true)})}</span>
98
- </dd>
99
- </div>
100
- <div class="metric-box">
101
- <dt class="metric-title">${i18nString(UIStrings.viewportAdCount)}</dt>
102
- <dd class="metric-value">
103
- <span>${formatValue(metrics.viewportAdCount, false)}</span>
104
- <span class="metric-average">${i18nString(UIStrings.average, {PH1: formatAverage(metrics.averageViewportAdCount, false)})}</span>
105
- </dd>
106
- </div>
107
- <div class="metric-box">
108
- <dt class="metric-title">${i18nString(UIStrings.totalCpuUsage)}</dt>
109
- <dd class="metric-value">
110
- <span>${formatCpu(metrics.totalAdCpuTime)}</span>
111
- </dd>
112
- </div>
113
- <div class="metric-box">
114
- <dt class="metric-title">${i18nString(UIStrings.totalNetworkUsage)}</dt>
115
- <dd class="metric-value">
116
- <span>${formatNetwork(metrics.totalAdNetworkBytes)}</span>
117
- </dd>
118
- </div>
119
- </dl>
93
+ <div class="ads-view-container" jslog=${VisualLogging.pane('ads')}>
94
+ <dl class="metrics-container">
95
+ <div class="metric-box">
96
+ <dt class="metric-title">${i18nString(UIStrings.viewportAdDensity)}</dt>
97
+ <dd class="metric-value">
98
+ <span>${formatValue(metrics.viewportAdDensityByArea, true)}</span>
99
+ <span class="metric-average">${i18nString(UIStrings.average, {PH1: formatAverage(metrics.averageViewportAdDensityByArea, true)})}</span>
100
+ </dd>
101
+ </div>
102
+ <div class="metric-box">
103
+ <dt class="metric-title">${i18nString(UIStrings.viewportAdCount)}</dt>
104
+ <dd class="metric-value">
105
+ <span>${formatValue(metrics.viewportAdCount, false)}</span>
106
+ <span class="metric-average">${i18nString(UIStrings.average, {PH1: formatAverage(metrics.averageViewportAdCount, false)})}</span>
107
+ </dd>
108
+ </div>
109
+ <div class="metric-box">
110
+ <dt class="metric-title">${i18nString(UIStrings.totalCpuUsage)}</dt>
111
+ <dd class="metric-value">
112
+ <span>${formatCpu(metrics.totalAdCpuTime)}</span>
113
+ </dd>
114
+ </div>
115
+ <div class="metric-box">
116
+ <dt class="metric-title">${i18nString(UIStrings.totalNetworkUsage)}</dt>
117
+ <dd class="metric-value">
118
+ <span>${formatNetwork(metrics.totalAdNetworkBytes)}</span>
119
+ </dd>
120
+ </div>
121
+ </dl>
122
+ </div>
120
123
  `, target);
121
124
  // clang-format on
122
125
  };
@@ -11,6 +11,12 @@
11
11
  overflow: auto;
12
12
  }
13
13
 
14
+ .ads-view-container {
15
+ display: flex;
16
+ flex-direction: column;
17
+ flex: auto;
18
+ }
19
+
14
20
  .metrics-container {
15
21
  flex: 0 0 auto;
16
22
  margin: 0 0 24px;
@@ -12,6 +12,7 @@ import * as Host from '../../core/host/host.js';
12
12
  import * as i18n from '../../core/i18n/i18n.js';
13
13
  import * as Platform from '../../core/platform/platform.js';
14
14
  import * as _ProtocolClient from '../../core/protocol_client/protocol_client.js'; // eslint-disable-line @typescript-eslint/no-unused-vars
15
+ import * as Root from '../../core/root/root.js';
15
16
  import * as SDK from '../../core/sdk/sdk.js';
16
17
  import type * as Protocol from '../../generated/protocol.js';
17
18
  import * as Bindings from '../../models/bindings/bindings.js';
@@ -1616,6 +1617,10 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1616
1617
  targetType = Host.UserMetrics.ExtensionEvalTarget.SAME_EXTENSION;
1617
1618
  } else {
1618
1619
  targetType = Host.UserMetrics.ExtensionEvalTarget.OTHER_EXTENSION;
1620
+ if (!Root.Runtime.hostConfig.extensionsOnChromeUrls?.enabled) {
1621
+ return this.status.E_FAILED(
1622
+ 'Access to extension URLs is restricted; use --extensions-on-chrome-urls to enable.');
1623
+ }
1619
1624
  }
1620
1625
  }
1621
1626
  Host.userMetrics.extensionEvalTarget(targetType);
@@ -66,8 +66,10 @@ export class IsolateSelector extends UI.Widget.VBox implements UI.ListControl.Li
66
66
  totalValueDiv: HTMLElement;
67
67
  readonly totalTrendDiv: HTMLElement;
68
68
 
69
- constructor() {
70
- super();
69
+ // `devtools-widget` passes its host element into widget constructors.
70
+ // Accept and forward it so this widget attaches to that host element.
71
+ constructor(element?: HTMLElement) {
72
+ super(element);
71
73
 
72
74
  this.items = new UI.ListModel.ListModel();
73
75
  this.list = new UI.ListControl.ListControl(this.items, this, UI.ListControl.ListMode.NonViewport);