chrome-devtools-frontend 1.0.1606789 → 1.0.1608868

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 (75) hide show
  1. package/docs/ui_engineering.md +2 -0
  2. package/eslint.config.mjs +2 -0
  3. package/front_end/core/common/VersionController.ts +18 -1
  4. package/front_end/core/host/UserMetrics.ts +0 -2
  5. package/front_end/core/platform/node/HostRuntime.ts +1 -1
  6. package/front_end/core/root/ExperimentNames.ts +0 -2
  7. package/front_end/core/sdk/AccessibilityModel.ts +13 -1
  8. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -13
  9. package/front_end/core/sdk/StorageBucketsModel.ts +0 -12
  10. package/front_end/entrypoints/main/MainImpl.ts +2 -11
  11. package/front_end/generated/InspectorBackendCommands.ts +3 -33
  12. package/front_end/generated/SupportedCSSProperties.js +8 -4
  13. package/front_end/generated/protocol-mapping.d.ts +7 -26
  14. package/front_end/generated/protocol-proxy-api.d.ts +5 -24
  15. package/front_end/generated/protocol.ts +2 -296
  16. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +2 -2
  17. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +1 -1
  18. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -6
  19. package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +2 -1
  20. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +46 -21
  21. package/front_end/{panels/profiler → models/heap_snapshot_model}/ChildrenProvider.ts +3 -4
  22. package/front_end/{panels/profiler → models/heap_snapshot_model}/HeapSnapshotProxy.ts +19 -36
  23. package/front_end/models/heap_snapshot_model/heap_snapshot_model.ts +4 -0
  24. package/front_end/models/javascript_metadata/NativeFunctions.js +0 -4
  25. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +53 -10
  26. package/front_end/panels/accessibility/accessibility.ts +0 -2
  27. package/front_end/panels/accessibility/accessibilitySidebarView.css +10 -0
  28. package/front_end/panels/ai_assistance/components/ChatMessage.ts +6 -5
  29. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +36 -17
  30. package/front_end/panels/ai_assistance/components/chatMessage.css +7 -0
  31. package/front_end/panels/ai_assistance/components/walkthroughView.css +39 -11
  32. package/front_end/panels/application/CrashReportContextView.ts +237 -0
  33. package/front_end/panels/application/IndexedDBModel.ts +0 -10
  34. package/front_end/panels/application/InterestGroupStorageModel.ts +0 -11
  35. package/front_end/panels/application/ReportingApiTreeElement.ts +40 -1
  36. package/front_end/panels/application/SharedStorageModel.ts +0 -11
  37. package/front_end/panels/application/WebMCPView.ts +389 -52
  38. package/front_end/panels/application/application.ts +4 -0
  39. package/front_end/panels/application/components/CrashReportContextGrid.ts +154 -0
  40. package/front_end/panels/application/components/components.ts +2 -0
  41. package/front_end/panels/application/webMCPView.css +107 -10
  42. package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +12 -2
  43. package/front_end/panels/elements/AccessibilityTreeView.ts +10 -6
  44. package/front_end/panels/elements/ElementsPanel.ts +9 -50
  45. package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
  46. package/front_end/panels/elements/elements-meta.ts +1 -0
  47. package/front_end/panels/elements/elementsPanel.css +4 -14
  48. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +23 -13
  49. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +30 -30
  50. package/front_end/panels/profiler/HeapSnapshotView.ts +16 -13
  51. package/front_end/panels/profiler/profiler.ts +0 -4
  52. package/front_end/panels/snippets/SnippetsQuickOpen.ts +5 -5
  53. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +2 -2
  54. package/front_end/panels/sources/sources-meta.ts +7 -7
  55. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +1 -3
  56. package/front_end/panels/timeline/ThirdPartyTreeView.ts +6 -1
  57. package/front_end/panels/timeline/ThreadAppender.ts +1 -3
  58. package/front_end/panels/timeline/TimelineController.ts +2 -2
  59. package/front_end/panels/timeline/TimelinePanel.ts +2 -4
  60. package/front_end/panels/timeline/TimelineTreeView.ts +32 -2
  61. package/front_end/panels/timeline/components/LiveMetricsView.ts +75 -54
  62. package/front_end/panels/timeline/components/timelineRangeSummaryView.css +8 -0
  63. package/front_end/panels/timeline/thirdPartyTreeView.css +0 -1
  64. package/front_end/panels/timeline/timeline-meta.ts +13 -0
  65. package/front_end/third_party/chromium/README.chromium +1 -1
  66. package/front_end/ui/legacy/TabbedPane.ts +3 -1
  67. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +3 -3
  68. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +2 -5
  69. package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +4 -4
  70. package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +5 -1
  71. package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -1
  72. package/front_end/ui/legacy/components/utils/imagePreview.css +1 -1
  73. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -3
  74. package/package.json +1 -1
  75. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +0 -653
@@ -0,0 +1,237 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import '../../ui/legacy/legacy.js';
6
+
7
+ import * as i18n from '../../core/i18n/i18n.js';
8
+ import * as Platform from '../../core/platform/platform.js';
9
+ import * as SDK from '../../core/sdk/sdk.js';
10
+ import type * as Protocol from '../../generated/protocol.js';
11
+ import type * as TextUtils from '../../models/text_utils/text_utils.js';
12
+ import * as Buttons from '../../ui/components/buttons/buttons.js';
13
+ import * as UI from '../../ui/legacy/legacy.js';
14
+ import {html, render} from '../../ui/lit/lit.js';
15
+ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
16
+
17
+ import * as ApplicationComponents from './components/components.js';
18
+
19
+ const UIStrings = {
20
+ /**
21
+ * @description Placeholder text when no context is detected.
22
+ */
23
+ noContext: 'No context entries detected across frames.',
24
+ /**
25
+ * @description Fallback label when a frame has no URL.
26
+ */
27
+ unknownFrame: 'Unknown Frame',
28
+ /**
29
+ * @description Placeholder for a search field in a toolbar
30
+ */
31
+ filterByText: 'Filter by key or value',
32
+ /**
33
+ * @description Text to refresh the page
34
+ */
35
+ refresh: 'Refresh',
36
+ } as const;
37
+
38
+ const str_ = i18n.i18n.registerUIStrings('panels/application/CrashReportContextView.ts', UIStrings);
39
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
40
+
41
+ export interface FrameContextData {
42
+ url: string;
43
+ frameId: string;
44
+ displayName: string;
45
+ entries: Protocol.CrashReportContext.CrashReportContextEntry[];
46
+ }
47
+
48
+ interface ViewInput {
49
+ frames: FrameContextData[];
50
+ selectedKey: string|null;
51
+ onRowSelected: (key: string) => void;
52
+ onRefresh: () => void;
53
+ onFilterChanged: (e: CustomEvent<string>) => void;
54
+ filters: TextUtils.TextUtils.ParsedFilter[];
55
+ }
56
+
57
+ type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
58
+
59
+ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
60
+ const {widget} = UI.Widget;
61
+ // clang-format off
62
+ render(
63
+ html`
64
+ <style>${UI.inspectorCommonStyles}</style>
65
+ <style>
66
+ .crash-report-context-view {
67
+ padding-top: 5px;
68
+ overflow: auto;
69
+ }
70
+
71
+ .frame-section {
72
+ margin-top: var(--sys-size-8);
73
+ }
74
+
75
+ .frame-section:first-child {
76
+ margin-top: 0;
77
+ }
78
+
79
+ .frame-header {
80
+ display: flex;
81
+ align-items: center;
82
+ padding: var(--sys-size-4) var(--sys-size-6);
83
+ gap: var(--sys-size-6);
84
+ background-color: var(--sys-color-surface2);
85
+ border-bottom: 1px solid var(--sys-color-divider);
86
+ }
87
+
88
+ .frame-url {
89
+ font-weight: var(--ref-typeface-weight-bold);
90
+ flex: 1;
91
+ overflow: hidden;
92
+ text-overflow: ellipsis;
93
+ white-space: nowrap;
94
+ font-family: var(--default-font-family);
95
+ }
96
+
97
+
98
+ .toolbar-container {
99
+ border-bottom: 1px solid var(--sys-color-divider);
100
+ background-color: var(--sys-color-cdt-base-container);
101
+ }
102
+ </style>
103
+ <div class="vbox flex-auto" jslog=${VisualLogging.pane('crash-report-context')}>
104
+ <devtools-toolbar class="crash-report-context-toolbar" role="toolbar" jslog=${VisualLogging.toolbar()}>
105
+ <devtools-button title=${i18nString(UIStrings.refresh)}
106
+ @click=${input.onRefresh}
107
+ .iconName=${'refresh'}
108
+ .variant=${Buttons.Button.Variant.TOOLBAR}
109
+ jslog=${VisualLogging.action('refresh').track({
110
+ click: true
111
+ })}>
112
+ </devtools-button>
113
+ <devtools-toolbar-input type="filter" placeholder=${i18nString(UIStrings.filterByText)}
114
+ @change=${(e: CustomEvent<string>) => input.onFilterChanged(e)} class="flex-auto">
115
+ </devtools-toolbar-input>
116
+ </devtools-toolbar>
117
+ ${input.frames.length > 0 ? html`
118
+ <div class="crash-report-context-view flex-auto">
119
+ ${input.frames.map(frame => html`
120
+ <div class="frame-section">
121
+ <div class="frame-header">
122
+ <span class="frame-url" title="URL: ${frame.url}\nFrame ID: ${frame.frameId}">${frame.displayName}</span>
123
+ </div>
124
+ <div class="grid-container">
125
+ <devtools-widget
126
+ ${widget(ApplicationComponents.CrashReportContextGrid.CrashReportContextGrid, {
127
+ data: {
128
+ entries: frame.entries.map(e => ({key: e.key, value: e.value})),
129
+ selectedKey: input.selectedKey || undefined,
130
+ filters: input.filters
131
+ }
132
+ })}
133
+ @select=${(e: CustomEvent<string>) => input.onRowSelected(e.detail)}>
134
+ </devtools-widget>
135
+ </div>
136
+ </div>
137
+ `)}
138
+ </div>
139
+ ` : html`
140
+ ${widget(UI.EmptyWidget.EmptyWidget, {
141
+ header: i18nString(UIStrings.noContext),
142
+ })}
143
+ `}
144
+ </div>
145
+ `,
146
+ target);
147
+ // clang-format on
148
+ };
149
+
150
+ export class CrashReportContextView extends UI.Widget.VBox {
151
+ private selectedKey: string|null = null;
152
+ readonly #view: View;
153
+ #filters: TextUtils.TextUtils.ParsedFilter[] = [];
154
+
155
+ constructor(view: View = DEFAULT_VIEW) {
156
+ super();
157
+ this.#view = view;
158
+ this.requestUpdate();
159
+ }
160
+
161
+ override async performUpdate(): Promise<void> {
162
+ const models =
163
+ SDK.TargetManager.TargetManager.instance().models(SDK.CrashReportContextModel.CrashReportContextModel);
164
+ const allEntries =
165
+ (await Promise.all(models.map(model => model.getEntries())))
166
+ .flat()
167
+ .filter((entry): entry is Protocol.CrashReportContext.CrashReportContextEntry => entry !== null);
168
+
169
+ const frameData = this.#processFrameData(allEntries);
170
+
171
+ this.#view(
172
+ {
173
+ frames: frameData,
174
+ selectedKey: this.selectedKey,
175
+ filters: this.#filters,
176
+ onRowSelected: (key: string) => {
177
+ this.selectedKey = key;
178
+ this.requestUpdate();
179
+ },
180
+ onRefresh: () => {
181
+ this.requestUpdate();
182
+ },
183
+ onFilterChanged: (e: CustomEvent<string>) => {
184
+ const text = e.detail;
185
+ const textFilterRegExp = text ? Platform.StringUtilities.createPlainTextSearchRegex(text, 'i') : null;
186
+ if (textFilterRegExp) {
187
+ this.#filters = [
188
+ {key: 'key,value', regex: textFilterRegExp, negative: false},
189
+ ];
190
+ } else {
191
+ this.#filters = [];
192
+ }
193
+ this.requestUpdate();
194
+ },
195
+ },
196
+ undefined, this.contentElement);
197
+ }
198
+
199
+ #processFrameData(allEntries: Protocol.CrashReportContext.CrashReportContextEntry[]): FrameContextData[] {
200
+ if (allEntries.length === 0) {
201
+ return [];
202
+ }
203
+
204
+ const entriesByFrame = Map.groupBy(allEntries, entry => entry.frameId);
205
+
206
+ return [...entriesByFrame.entries()]
207
+ .map(([frameId, frameEntries]) => {
208
+ const frame = SDK.FrameManager.FrameManager.instance().getFrame(frameId as Protocol.Page.FrameId);
209
+ const url = frame?.url || i18nString(UIStrings.unknownFrame);
210
+ const displayName = frame?.displayName() || url;
211
+ return {
212
+ url,
213
+ frameId,
214
+ displayName,
215
+ isMain: frame?.isMainFrame() ?? false,
216
+ origin: frame?.securityOrigin || '',
217
+ entries: frameEntries,
218
+ };
219
+ })
220
+ // Ensure the main (outermost) frame is always listed first at the top of the View
221
+ .sort((a, b) => {
222
+ if (a.isMain && !b.isMain) {
223
+ return -1;
224
+ }
225
+ if (!a.isMain && b.isMain) {
226
+ return 1;
227
+ }
228
+ return 0;
229
+ })
230
+ .map(data => ({
231
+ url: data.url,
232
+ frameId: data.frameId,
233
+ displayName: data.displayName,
234
+ entries: data.entries,
235
+ }));
236
+ }
237
+ }
@@ -416,8 +416,6 @@ export class IndexedDBModel extends SDK.SDKModel.SDKModel<EventTypes> implements
416
416
  this.dispatchEventToListeners(Events.IndexedDBContentUpdated, {databaseId, objectStoreName, model: this});
417
417
  }
418
418
  }
419
- attributionReportingTriggerRegistered(_event: Protocol.Storage.AttributionReportingTriggerRegisteredEvent): void {
420
- }
421
419
 
422
420
  cacheStorageListUpdated(_event: Protocol.Storage.CacheStorageListUpdatedEvent): void {
423
421
  }
@@ -447,14 +445,6 @@ export class IndexedDBModel extends SDK.SDKModel.SDKModel<EventTypes> implements
447
445
 
448
446
  storageBucketDeleted(_event: Protocol.Storage.StorageBucketDeletedEvent): void {
449
447
  }
450
-
451
- attributionReportingSourceRegistered(_event: Protocol.Storage.AttributionReportingSourceRegisteredEvent): void {
452
- }
453
- attributionReportingReportSent(_event: Protocol.Storage.AttributionReportingReportSentEvent): void {
454
- }
455
- attributionReportingVerboseDebugReportSent(_event: Protocol.Storage.AttributionReportingVerboseDebugReportSentEvent):
456
- void {
457
- }
458
448
  }
459
449
 
460
450
  SDK.SDKModel.SDKModel.register(IndexedDBModel, {capabilities: SDK.Target.Capability.STORAGE, autostart: false});
@@ -36,9 +36,6 @@ export class InterestGroupStorageModel extends SDK.SDKModel.SDKModel<EventTypes>
36
36
  this.dispatchEventToListeners(Events.INTEREST_GROUP_ACCESS, event);
37
37
  }
38
38
 
39
- attributionReportingTriggerRegistered(_event: Protocol.Storage.AttributionReportingTriggerRegisteredEvent): void {
40
- }
41
-
42
39
  indexedDBListUpdated(_event: Protocol.Storage.IndexedDBListUpdatedEvent): void {
43
40
  }
44
41
 
@@ -70,14 +67,6 @@ export class InterestGroupStorageModel extends SDK.SDKModel.SDKModel<EventTypes>
70
67
 
71
68
  storageBucketDeleted(_event: Protocol.Storage.StorageBucketDeletedEvent): void {
72
69
  }
73
-
74
- attributionReportingSourceRegistered(_event: Protocol.Storage.AttributionReportingSourceRegisteredEvent): void {
75
- }
76
- attributionReportingReportSent(_event: Protocol.Storage.AttributionReportingReportSentEvent): void {
77
- }
78
- attributionReportingVerboseDebugReportSent(_event: Protocol.Storage.AttributionReportingVerboseDebugReportSentEvent):
79
- void {
80
- }
81
70
  }
82
71
 
83
72
  SDK.SDKModel.SDKModel.register(
@@ -8,6 +8,7 @@ import type * as Platform from '../../core/platform/platform.js';
8
8
  import {createIcon} from '../../ui/kit/kit.js';
9
9
 
10
10
  import {ApplicationPanelTreeElement} from './ApplicationPanelTreeElement.js';
11
+ import {CrashReportContextView} from './CrashReportContextView.js';
11
12
  import {ReportingApiView} from './ReportingApiView.js';
12
13
  import type {ResourcesPanel} from './ResourcesPanel.js';
13
14
 
@@ -16,19 +17,32 @@ const UIStrings = {
16
17
  * @description Label for an item in the Application Panel Sidebar of the Application panel
17
18
  */
18
19
  reportingApi: 'Reporting API',
20
+ /**
21
+ * @description Label for the Crash Report Context child item in the Reporting API section.
22
+ */
23
+ crashReportContext: 'Crash Report Context',
19
24
  } as const;
20
25
  const str_ = i18n.i18n.registerUIStrings('panels/application/ReportingApiTreeElement.ts', UIStrings);
21
26
  export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
22
27
 
23
28
  export class ReportingApiTreeElement extends ApplicationPanelTreeElement {
24
29
  private view?: ReportingApiView;
30
+ #childrenInitialized = false;
25
31
 
26
32
  constructor(storagePanel: ResourcesPanel) {
27
- super(storagePanel, i18nString(UIStrings.reportingApi), false, 'reporting-api');
33
+ super(storagePanel, i18nString(UIStrings.reportingApi), true, 'reporting-api');
28
34
  const icon = createIcon('document');
29
35
  this.setLeadingIcons([icon]);
30
36
  }
31
37
 
38
+ override onattach(): void {
39
+ super.onattach();
40
+ if (!this.#childrenInitialized) {
41
+ this.#childrenInitialized = true;
42
+ this.appendChild(new CrashReportContextTreeElement(this.resourcesPanel));
43
+ }
44
+ }
45
+
32
46
  override get itemURL(): Platform.DevToolsPath.UrlString {
33
47
  return 'reportingApi://' as Platform.DevToolsPath.UrlString;
34
48
  }
@@ -43,3 +57,28 @@ export class ReportingApiTreeElement extends ApplicationPanelTreeElement {
43
57
  return false;
44
58
  }
45
59
  }
60
+
61
+ export class CrashReportContextTreeElement extends ApplicationPanelTreeElement {
62
+ private view?: CrashReportContextView;
63
+
64
+ constructor(storagePanel: ResourcesPanel) {
65
+ super(storagePanel, i18nString(UIStrings.crashReportContext), false, 'crash-report-context');
66
+ const icon = createIcon('table');
67
+ this.setLeadingIcons([icon]);
68
+ }
69
+
70
+ override get itemURL(): Platform.DevToolsPath.UrlString {
71
+ return 'reportingApi://crash-report-context' as Platform.DevToolsPath.UrlString;
72
+ }
73
+
74
+ override onselect(selectedByUser?: boolean): boolean {
75
+ super.onselect(selectedByUser);
76
+ if (!this.view) {
77
+ this.view = new CrashReportContextView();
78
+ }
79
+ this.view.requestUpdate();
80
+ this.showView(this.view);
81
+ Host.userMetrics.panelShown('crash-report-context');
82
+ return false;
83
+ }
84
+ }
@@ -215,9 +215,6 @@ export class SharedStorageModel extends SDK.SDKModel.SDKModel<EventTypes> implem
215
215
  _event: Protocol.Storage.SharedStorageWorkletOperationExecutionFinishedEvent): void {
216
216
  }
217
217
 
218
- attributionReportingTriggerRegistered(_event: Protocol.Storage.AttributionReportingTriggerRegisteredEvent): void {
219
- }
220
-
221
218
  indexedDBListUpdated(_event: Protocol.Storage.IndexedDBListUpdatedEvent): void {
222
219
  }
223
220
 
@@ -245,14 +242,6 @@ export class SharedStorageModel extends SDK.SDKModel.SDKModel<EventTypes> implem
245
242
 
246
243
  storageBucketDeleted(_event: Protocol.Storage.StorageBucketDeletedEvent): void {
247
244
  }
248
-
249
- attributionReportingSourceRegistered(_event: Protocol.Storage.AttributionReportingSourceRegisteredEvent): void {
250
- }
251
- attributionReportingReportSent(_event: Protocol.Storage.AttributionReportingReportSentEvent): void {
252
- }
253
- attributionReportingVerboseDebugReportSent(_event: Protocol.Storage.AttributionReportingVerboseDebugReportSentEvent):
254
- void {
255
- }
256
245
  }
257
246
 
258
247
  SDK.SDKModel.SDKModel.register(SharedStorageModel, {capabilities: SDK.Target.Capability.STORAGE, autostart: false});