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.
- package/docs/ui_engineering.md +2 -0
- package/eslint.config.mjs +2 -0
- package/front_end/core/common/VersionController.ts +18 -1
- package/front_end/core/host/UserMetrics.ts +0 -2
- package/front_end/core/platform/node/HostRuntime.ts +1 -1
- package/front_end/core/root/ExperimentNames.ts +0 -2
- package/front_end/core/sdk/AccessibilityModel.ts +13 -1
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -13
- package/front_end/core/sdk/StorageBucketsModel.ts +0 -12
- package/front_end/entrypoints/main/MainImpl.ts +2 -11
- package/front_end/generated/InspectorBackendCommands.ts +3 -33
- package/front_end/generated/SupportedCSSProperties.js +8 -4
- package/front_end/generated/protocol-mapping.d.ts +7 -26
- package/front_end/generated/protocol-proxy-api.d.ts +5 -24
- package/front_end/generated/protocol.ts +2 -296
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +2 -2
- package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +1 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -6
- package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +2 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +46 -21
- package/front_end/{panels/profiler → models/heap_snapshot_model}/ChildrenProvider.ts +3 -4
- package/front_end/{panels/profiler → models/heap_snapshot_model}/HeapSnapshotProxy.ts +19 -36
- package/front_end/models/heap_snapshot_model/heap_snapshot_model.ts +4 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +0 -4
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +53 -10
- package/front_end/panels/accessibility/accessibility.ts +0 -2
- package/front_end/panels/accessibility/accessibilitySidebarView.css +10 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +6 -5
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +36 -17
- package/front_end/panels/ai_assistance/components/chatMessage.css +7 -0
- package/front_end/panels/ai_assistance/components/walkthroughView.css +39 -11
- package/front_end/panels/application/CrashReportContextView.ts +237 -0
- package/front_end/panels/application/IndexedDBModel.ts +0 -10
- package/front_end/panels/application/InterestGroupStorageModel.ts +0 -11
- package/front_end/panels/application/ReportingApiTreeElement.ts +40 -1
- package/front_end/panels/application/SharedStorageModel.ts +0 -11
- package/front_end/panels/application/WebMCPView.ts +389 -52
- package/front_end/panels/application/application.ts +4 -0
- package/front_end/panels/application/components/CrashReportContextGrid.ts +154 -0
- package/front_end/panels/application/components/components.ts +2 -0
- package/front_end/panels/application/webMCPView.css +107 -10
- package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +12 -2
- package/front_end/panels/elements/AccessibilityTreeView.ts +10 -6
- package/front_end/panels/elements/ElementsPanel.ts +9 -50
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
- package/front_end/panels/elements/elements-meta.ts +1 -0
- package/front_end/panels/elements/elementsPanel.css +4 -14
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +23 -13
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +30 -30
- package/front_end/panels/profiler/HeapSnapshotView.ts +16 -13
- package/front_end/panels/profiler/profiler.ts +0 -4
- package/front_end/panels/snippets/SnippetsQuickOpen.ts +5 -5
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +2 -2
- package/front_end/panels/sources/sources-meta.ts +7 -7
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +1 -3
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +6 -1
- package/front_end/panels/timeline/ThreadAppender.ts +1 -3
- package/front_end/panels/timeline/TimelineController.ts +2 -2
- package/front_end/panels/timeline/TimelinePanel.ts +2 -4
- package/front_end/panels/timeline/TimelineTreeView.ts +32 -2
- package/front_end/panels/timeline/components/LiveMetricsView.ts +75 -54
- package/front_end/panels/timeline/components/timelineRangeSummaryView.css +8 -0
- package/front_end/panels/timeline/thirdPartyTreeView.css +0 -1
- package/front_end/panels/timeline/timeline-meta.ts +13 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/TabbedPane.ts +3 -1
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +3 -3
- package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +2 -5
- package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +4 -4
- package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +5 -1
- package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -1
- package/front_end/ui/legacy/components/utils/imagePreview.css +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -3
- package/package.json +1 -1
- package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +0 -653
|
@@ -4,22 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
import '../../ui/components/icon_button/icon_button.js';
|
|
6
6
|
import '../../ui/components/lists/lists.js';
|
|
7
|
+
import '../../ui/components/node_text/node_text.js';
|
|
7
8
|
import '../../ui/legacy/components/data_grid/data_grid.js';
|
|
8
9
|
import '../../ui/legacy/legacy.js';
|
|
9
10
|
|
|
11
|
+
import * as Common from '../../core/common/common.js';
|
|
10
12
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
11
13
|
import * as Platform from '../../core/platform/platform.js';
|
|
12
14
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
13
15
|
import * as Protocol from '../../generated/protocol.js';
|
|
16
|
+
import type * as StackTrace from '../../models/stack_trace/stack_trace.js';
|
|
14
17
|
import * as WebMCP from '../../models/web_mcp/web_mcp.js';
|
|
15
18
|
import * as Adorners from '../../ui/components/adorners/adorners.js';
|
|
16
19
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
17
20
|
import type * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
|
21
|
+
import type * as NodeText from '../../ui/components/node_text/node_text.js';
|
|
22
|
+
import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
|
|
23
|
+
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
18
24
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
19
25
|
import {
|
|
20
26
|
Directives,
|
|
21
27
|
html,
|
|
28
|
+
nothing,
|
|
22
29
|
render,
|
|
30
|
+
type TemplateResult,
|
|
23
31
|
} from '../../ui/lit/lit.js';
|
|
24
32
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
25
33
|
|
|
@@ -47,6 +55,18 @@ const UIStrings = {
|
|
|
47
55
|
* @description Text to display when no calls have been made
|
|
48
56
|
*/
|
|
49
57
|
noCallsPlaceholder: 'Start interacting with your `WebMCP` agent to see real-time tool calls and executions here.',
|
|
58
|
+
/**
|
|
59
|
+
* @description Text for the header of the tool details section
|
|
60
|
+
*/
|
|
61
|
+
toolDetails: 'Details',
|
|
62
|
+
/**
|
|
63
|
+
* @description Text for the link to reveal the tool's DOM node in the Elements panel
|
|
64
|
+
*/
|
|
65
|
+
viewInElementsPanel: 'View in Elements panel',
|
|
66
|
+
/**
|
|
67
|
+
* @description Text for the frame of a tool
|
|
68
|
+
*/
|
|
69
|
+
frame: 'Frame',
|
|
50
70
|
/**
|
|
51
71
|
* @description Text for the name of a tool call
|
|
52
72
|
*/
|
|
@@ -71,6 +91,10 @@ const UIStrings = {
|
|
|
71
91
|
* @description Tooltip for the clear log button
|
|
72
92
|
*/
|
|
73
93
|
clearLog: 'Clear log',
|
|
94
|
+
/**
|
|
95
|
+
* @description Text to close something
|
|
96
|
+
*/
|
|
97
|
+
close: 'Close',
|
|
74
98
|
/**
|
|
75
99
|
* @description Placeholder for the filter input
|
|
76
100
|
*/
|
|
@@ -134,6 +158,7 @@ const UIStrings = {
|
|
|
134
158
|
} as const;
|
|
135
159
|
const str_ = i18n.i18n.registerUIStrings('panels/application/WebMCPView.ts', UIStrings);
|
|
136
160
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
161
|
+
const {widget} = UI.Widget;
|
|
137
162
|
|
|
138
163
|
export interface FilterState {
|
|
139
164
|
text: string;
|
|
@@ -159,6 +184,10 @@ export interface FilterMenuButtons {
|
|
|
159
184
|
}
|
|
160
185
|
export interface ViewInput {
|
|
161
186
|
tools: WebMCP.WebMCPModel.Tool[];
|
|
187
|
+
selectedTool: WebMCP.WebMCPModel.Tool|null;
|
|
188
|
+
onToolSelect: (tool: WebMCP.WebMCPModel.Tool|null) => void;
|
|
189
|
+
selectedCall: WebMCP.WebMCPModel.Call|null;
|
|
190
|
+
onCallSelect: (call: WebMCP.WebMCPModel.Call|null) => void;
|
|
162
191
|
filters: FilterState;
|
|
163
192
|
filterButtons: FilterMenuButtons;
|
|
164
193
|
onClearLogClick: () => void;
|
|
@@ -271,6 +300,24 @@ function getIconGroupsFromStats(toolStats: ReturnType<typeof calculateToolStats>
|
|
|
271
300
|
}
|
|
272
301
|
return groups;
|
|
273
302
|
}
|
|
303
|
+
|
|
304
|
+
export function parsePayload(payload?: unknown): {
|
|
305
|
+
valueObject: unknown,
|
|
306
|
+
valueString: string|undefined,
|
|
307
|
+
} {
|
|
308
|
+
if (payload === undefined) {
|
|
309
|
+
return {valueObject: undefined, valueString: undefined};
|
|
310
|
+
}
|
|
311
|
+
if (typeof payload === 'string') {
|
|
312
|
+
try {
|
|
313
|
+
return {valueObject: JSON.parse(payload), valueString: undefined};
|
|
314
|
+
} catch {
|
|
315
|
+
return {valueObject: undefined, valueString: payload};
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return {valueObject: payload, valueString: undefined};
|
|
319
|
+
}
|
|
320
|
+
|
|
274
321
|
export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
275
322
|
const tools = input.tools;
|
|
276
323
|
const stats = calculateToolStats(input.toolCalls);
|
|
@@ -332,36 +379,77 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
332
379
|
</devtools-toolbar>
|
|
333
380
|
</div>
|
|
334
381
|
${input.toolCalls.length > 0 ? html`
|
|
335
|
-
<devtools-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
<
|
|
342
|
-
<th id="input" weight="30">${i18nString(UIStrings.input)}</th>
|
|
343
|
-
<th id="output" weight="30">${i18nString(UIStrings.output)}</th>
|
|
344
|
-
</tr>
|
|
345
|
-
${Directives.repeat(input.toolCalls, call => call.invocationId + '-' + (call.result?.status ?? ''), call => html`
|
|
346
|
-
<tr class=${
|
|
347
|
-
call.result?.status === Protocol.WebMCP.InvocationStatus.Error ? 'status-error' :
|
|
348
|
-
call.result?.status === Protocol.WebMCP.InvocationStatus.Canceled ? 'status-cancelled' : ''
|
|
349
|
-
}>
|
|
382
|
+
<devtools-split-view name="webmcp-call-split-view"
|
|
383
|
+
direction="column"
|
|
384
|
+
sidebar-position="second"
|
|
385
|
+
sidebar-visibility=${input.selectedCall ? 'show' : 'hidden'}>
|
|
386
|
+
<div slot="main" style="display: flex; flex-direction: column; overflow: hidden; height: 100%;">
|
|
387
|
+
<devtools-data-grid striped .template=${html`
|
|
388
|
+
<table>
|
|
350
389
|
<style>${webMCPViewStyles}</style>
|
|
351
|
-
<
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
</
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
390
|
+
<tr>
|
|
391
|
+
<th id="name" weight="20">
|
|
392
|
+
${i18nString(UIStrings.name)}
|
|
393
|
+
</th>
|
|
394
|
+
<th id="status" weight="20">${i18nString(UIStrings.status)}</th>
|
|
395
|
+
${!input.selectedCall ? html`
|
|
396
|
+
<th id="input" weight="30">${i18nString(UIStrings.input)}</th>
|
|
397
|
+
<th id="output" weight="30">${i18nString(UIStrings.output)}</th>
|
|
398
|
+
` : nothing}
|
|
399
|
+
</tr>
|
|
400
|
+
${Directives.repeat(input.toolCalls, call => call.invocationId + '-' + (call.result?.status ?? ''),
|
|
401
|
+
call => html`
|
|
402
|
+
<tr class=${Directives.classMap({
|
|
403
|
+
'status-error': call.result?.status === Protocol.WebMCP.InvocationStatus.Error,
|
|
404
|
+
'status-cancelled': call.result?.status === Protocol.WebMCP.InvocationStatus.Canceled,
|
|
405
|
+
selected: call === input.selectedCall,
|
|
406
|
+
})} @click=${() => input.onCallSelect(call)}>
|
|
407
|
+
<td>${call.tool.name}</td>
|
|
408
|
+
<td>
|
|
409
|
+
<div class="status-cell">
|
|
410
|
+
${iconName(call) ? html`<devtools-icon class="small" name=${iconName(call)}></devtools-icon>`
|
|
411
|
+
: ''}
|
|
412
|
+
<span>${statusString(call)}</span>
|
|
413
|
+
</div>
|
|
414
|
+
</td>
|
|
415
|
+
${!input.selectedCall ? html`
|
|
416
|
+
<td>${call.input}</td>
|
|
417
|
+
<td>${call.result?.output ? JSON.stringify(call.result.output)
|
|
418
|
+
: call.result?.errorText ?? ''}</td>
|
|
419
|
+
` : nothing}
|
|
420
|
+
</tr>
|
|
421
|
+
`)}
|
|
422
|
+
</table>`}>
|
|
423
|
+
</devtools-data-grid>
|
|
424
|
+
</div>
|
|
425
|
+
<div slot="sidebar" style="height: 100%; display: flex; flex-direction: column; overflow: hidden;">
|
|
426
|
+
<devtools-tabbed-pane class="call-details-tabbed-pane">
|
|
427
|
+
<devtools-button
|
|
428
|
+
slot="left"
|
|
429
|
+
.iconName=${'cross'}
|
|
430
|
+
.size=${Buttons.Button.Size.SMALL}
|
|
431
|
+
.variant=${Buttons.Button.Variant.ICON}
|
|
432
|
+
title=${i18nString(UIStrings.close)}
|
|
433
|
+
@click=${() => input.onCallSelect(null)}
|
|
434
|
+
></devtools-button>
|
|
435
|
+
<devtools-widget
|
|
436
|
+
id="details"
|
|
437
|
+
title=${i18nString(UIStrings.toolDetails)}
|
|
438
|
+
${widget(ToolDetailsWidget, {tool: input.selectedCall?.tool})}>
|
|
439
|
+
</devtools-widget>
|
|
440
|
+
<devtools-widget
|
|
441
|
+
id="inputs"
|
|
442
|
+
title=${i18nString(UIStrings.input)}
|
|
443
|
+
${widget(PayloadWidget, parsePayload(input.selectedCall?.input))}>
|
|
444
|
+
</devtools-widget>
|
|
445
|
+
<devtools-widget
|
|
446
|
+
id="outputs"
|
|
447
|
+
title=${i18nString(UIStrings.output)}
|
|
448
|
+
${widget(PayloadWidget, parsePayload(input.selectedCall?.result?.output))}>
|
|
449
|
+
</devtools-widget>
|
|
450
|
+
</devtools-tabbed-pane>
|
|
451
|
+
</div>
|
|
452
|
+
</devtools-split-view>
|
|
365
453
|
<div class="webmcp-toolbar-container" role="toolbar">
|
|
366
454
|
<devtools-toolbar class="webmcp-toolbar" role="presentation" wrappable>
|
|
367
455
|
<span class="toolbar-text">${i18nString(UIStrings.totalCalls, {PH1: stats.total})}</span>
|
|
@@ -379,30 +467,50 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
379
467
|
text: i18nString(UIStrings.noCallsPlaceholder)})}
|
|
380
468
|
`}
|
|
381
469
|
</div>
|
|
382
|
-
<
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
<
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
470
|
+
<devtools-split-view slot="sidebar"
|
|
471
|
+
direction="column"
|
|
472
|
+
sidebar-position="second"
|
|
473
|
+
name="webmcp-details-split-view"
|
|
474
|
+
sidebar-visibility=${input.selectedTool ? 'show' : 'hidden'}>
|
|
475
|
+
<div slot="main" class="tool-list">
|
|
476
|
+
<div class="section-title">${i18nString(UIStrings.toolRegistry)}</div>
|
|
477
|
+
${tools.length === 0 ? html`
|
|
478
|
+
${UI.Widget.widget(UI.EmptyWidget.EmptyWidget, {header: i18nString(UIStrings.noToolsPlaceholderTitle),
|
|
479
|
+
text: i18nString(UIStrings.noToolsPlaceholder)})}
|
|
480
|
+
` : html`
|
|
481
|
+
<devtools-list>
|
|
482
|
+
${tools.map(tool => {
|
|
483
|
+
const toolStats = calculateToolStats(input.toolCalls.filter(c => c.tool === tool));
|
|
484
|
+
const groups = getIconGroupsFromStats(toolStats);
|
|
485
|
+
return html`
|
|
486
|
+
<div class=${Directives.classMap({'tool-item': true, selected: tool === input.selectedTool})}
|
|
487
|
+
@click=${() => input.onToolSelect(tool)}>
|
|
488
|
+
<div class="tool-name-container">
|
|
489
|
+
<div class="tool-name source-code">${tool.name}</div>
|
|
490
|
+
${groups.length > 0 ? html`<icon-button .data=${
|
|
491
|
+
{groups, compact: false} as IconButton.IconButton.IconButtonData}></icon-button>` : ''}
|
|
492
|
+
</div>
|
|
493
|
+
<div class="tool-description">${tool.description}</div>
|
|
398
494
|
</div>
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
495
|
+
`;
|
|
496
|
+
})}
|
|
497
|
+
</devtools-list>
|
|
498
|
+
`}
|
|
499
|
+
</div>
|
|
500
|
+
<div slot="sidebar" class="tool-details">
|
|
501
|
+
<div class="section-title">
|
|
502
|
+
<devtools-button
|
|
503
|
+
.iconName=${'cross'}
|
|
504
|
+
.size=${Buttons.Button.Size.SMALL}
|
|
505
|
+
.variant=${Buttons.Button.Variant.ICON}
|
|
506
|
+
title=${i18nString(UIStrings.close)}
|
|
507
|
+
@click=${() => input.onToolSelect(null)}
|
|
508
|
+
></devtools-button>
|
|
509
|
+
<span>${i18nString(UIStrings.toolDetails)}</span>
|
|
510
|
+
</div>
|
|
511
|
+
${widget(ToolDetailsWidget, {tool: input.selectedTool})}
|
|
512
|
+
</div>
|
|
513
|
+
</devtools-split-view>
|
|
406
514
|
</devtools-split-view>
|
|
407
515
|
`, target);
|
|
408
516
|
// clang-format on
|
|
@@ -410,6 +518,8 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
410
518
|
|
|
411
519
|
export class WebMCPView extends UI.Widget.VBox {
|
|
412
520
|
readonly #view: View;
|
|
521
|
+
#selectedTool: WebMCP.WebMCPModel.Tool|null = null;
|
|
522
|
+
#selectedCall: WebMCP.WebMCPModel.Call|null = null;
|
|
413
523
|
|
|
414
524
|
#filterState: FilterState = {
|
|
415
525
|
text: '',
|
|
@@ -553,6 +663,16 @@ export class WebMCPView extends UI.Widget.VBox {
|
|
|
553
663
|
const filteredCalls = filterToolCalls(toolCalls, this.#filterState);
|
|
554
664
|
const input: ViewInput = {
|
|
555
665
|
tools: this.#getTools(),
|
|
666
|
+
selectedTool: this.#selectedTool,
|
|
667
|
+
onToolSelect: tool => {
|
|
668
|
+
this.#selectedTool = tool;
|
|
669
|
+
this.requestUpdate();
|
|
670
|
+
},
|
|
671
|
+
selectedCall: this.#selectedCall,
|
|
672
|
+
onCallSelect: call => {
|
|
673
|
+
this.#selectedCall = call;
|
|
674
|
+
this.requestUpdate();
|
|
675
|
+
},
|
|
556
676
|
toolCalls: filteredCalls,
|
|
557
677
|
filters: this.#filterState,
|
|
558
678
|
filterButtons: this.#filterButtons,
|
|
@@ -562,3 +682,220 @@ export class WebMCPView extends UI.Widget.VBox {
|
|
|
562
682
|
this.#view(input, {}, this.contentElement);
|
|
563
683
|
}
|
|
564
684
|
}
|
|
685
|
+
export interface PayloadViewInput {
|
|
686
|
+
valueObject?: unknown;
|
|
687
|
+
valueString?: string;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
export const PAYLOAD_DEFAULT_VIEW = (input: PayloadViewInput, output: object, target: HTMLElement): void => {
|
|
691
|
+
if (input.valueObject === undefined && input.valueString === undefined) {
|
|
692
|
+
render(nothing, target);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
const isParsable = input.valueObject !== undefined;
|
|
696
|
+
|
|
697
|
+
const createPayload = (parsedInput: unknown): TemplateResult => {
|
|
698
|
+
const object = new SDK.RemoteObject.LocalJSONObject(parsedInput);
|
|
699
|
+
const section =
|
|
700
|
+
new ObjectUI.ObjectPropertiesSection.RootElement(new ObjectUI.ObjectPropertiesSection.ObjectTree(object, {
|
|
701
|
+
readOnly: true,
|
|
702
|
+
propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
|
|
703
|
+
}));
|
|
704
|
+
section.title = document.createTextNode(object.description);
|
|
705
|
+
section.listItemElement.classList.add('source-code', 'object-properties-section');
|
|
706
|
+
section.childrenListElement.classList.add('source-code', 'object-properties-section');
|
|
707
|
+
section.expand();
|
|
708
|
+
return html`<devtools-tree .template=${html`
|
|
709
|
+
<style>${ObjectUI.ObjectPropertiesSection.objectValueStyles}</style>
|
|
710
|
+
<style>${ObjectUI.ObjectPropertiesSection.objectPropertiesSectionStyles}</style>
|
|
711
|
+
<ul role="tree">
|
|
712
|
+
<devtools-tree-wrapper .treeElement=${section}></devtools-tree-wrapper>
|
|
713
|
+
</ul>
|
|
714
|
+
`}></devtools-tree>`;
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
const createSourceText = (text: string): TemplateResult => html`<div class="payload-value source-code">${text}</div>`;
|
|
718
|
+
|
|
719
|
+
render(
|
|
720
|
+
html`
|
|
721
|
+
<style>${webMCPViewStyles}</style>
|
|
722
|
+
<div class="call-payload-view">
|
|
723
|
+
<div class="call-payload-content">
|
|
724
|
+
${
|
|
725
|
+
isParsable ? createPayload(input.valueObject) :
|
|
726
|
+
(input.valueString !== undefined ? createSourceText(input.valueString) : nothing)}
|
|
727
|
+
</div>
|
|
728
|
+
</div>
|
|
729
|
+
`,
|
|
730
|
+
target);
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
export class PayloadWidget extends UI.Widget.Widget {
|
|
734
|
+
#valueObject?: unknown;
|
|
735
|
+
#valueString?: string;
|
|
736
|
+
#view: typeof PAYLOAD_DEFAULT_VIEW;
|
|
737
|
+
|
|
738
|
+
constructor(element?: HTMLElement, view = PAYLOAD_DEFAULT_VIEW) {
|
|
739
|
+
super(element);
|
|
740
|
+
this.#view = view;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
set valueObject(valueObject: unknown) {
|
|
744
|
+
this.#valueObject = valueObject;
|
|
745
|
+
this.requestUpdate();
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
get valueObject(): unknown {
|
|
749
|
+
return this.#valueObject;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
set valueString(valueString: string|undefined) {
|
|
753
|
+
this.#valueString = valueString;
|
|
754
|
+
this.requestUpdate();
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
get valueString(): string|undefined {
|
|
758
|
+
return this.#valueString;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
override wasShown(): void {
|
|
762
|
+
super.wasShown();
|
|
763
|
+
this.requestUpdate();
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
override performUpdate(): void {
|
|
767
|
+
const input: PayloadViewInput = {
|
|
768
|
+
valueObject: this.#valueObject,
|
|
769
|
+
valueString: this.#valueString,
|
|
770
|
+
};
|
|
771
|
+
this.#view(input, {}, this.contentElement);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
export interface ToolDetailsViewInput {
|
|
776
|
+
tool: WebMCP.WebMCPModel.Tool|null|undefined;
|
|
777
|
+
origin: SDK.DOMModel.DOMNode|StackTrace.StackTrace.StackTrace|undefined;
|
|
778
|
+
highlightNode: (node: SDK.DOMModel.DOMNode) => void;
|
|
779
|
+
clearHighlight: () => void;
|
|
780
|
+
revealNode: (node: SDK.DOMModel.DOMNode) => void;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// clang-format off
|
|
784
|
+
const TOOL_DETAILS_VIEW = (input: ToolDetailsViewInput, output: undefined, target: HTMLElement): void => {
|
|
785
|
+
if (!input.tool) {
|
|
786
|
+
render(nothing, target);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
const tool = input.tool;
|
|
790
|
+
const origin = input.origin;
|
|
791
|
+
render(html`
|
|
792
|
+
<style>${webMCPViewStyles}</style>
|
|
793
|
+
<div class="tool-details-grid">
|
|
794
|
+
<div class="label">Name</div>
|
|
795
|
+
<div class="value source-code">${tool.name}</div>
|
|
796
|
+
<div class="label">Description</div>
|
|
797
|
+
<div class="value">${tool.description}</div>
|
|
798
|
+
${tool.frame ? html`
|
|
799
|
+
<div class="label">${i18nString(UIStrings.frame)}</div>
|
|
800
|
+
<div class="value">${Components.Linkifier.Linkifier.linkifyRevealable(tool.frame, tool.frame.displayName())}</div>
|
|
801
|
+
` : nothing}
|
|
802
|
+
${origin instanceof SDK.DOMModel.DOMNode ? html`
|
|
803
|
+
<div class="label">Origin</div>
|
|
804
|
+
<div class="value tool-origin-container">
|
|
805
|
+
<span
|
|
806
|
+
class="node-text-container source-code tool-origin-node"
|
|
807
|
+
data-label="true"
|
|
808
|
+
@mouseenter=${() => input.highlightNode(origin)}
|
|
809
|
+
@mouseleave=${input.clearHighlight}>
|
|
810
|
+
<devtools-node-text .data=${{
|
|
811
|
+
nodeId: origin.getAttribute('id') || undefined,
|
|
812
|
+
nodeTitle: origin.nodeNameInCorrectCase(),
|
|
813
|
+
nodeClasses: origin.getAttribute('class')?.split(/\s+/).filter(s => Boolean(s))
|
|
814
|
+
} as NodeText.NodeText.NodeTextData}>
|
|
815
|
+
</devtools-node-text>
|
|
816
|
+
</span>
|
|
817
|
+
<devtools-button class="show-element"
|
|
818
|
+
.title=${i18nString(UIStrings.viewInElementsPanel)}
|
|
819
|
+
aria-label=${i18nString(UIStrings.viewInElementsPanel)}
|
|
820
|
+
.iconName=${'select-element'}
|
|
821
|
+
.jslogContext=${'elements.select-element'}
|
|
822
|
+
.size=${Buttons.Button.Size.SMALL}
|
|
823
|
+
.variant=${Buttons.Button.Variant.ICON}
|
|
824
|
+
@click=${() => input.revealNode(origin)}
|
|
825
|
+
></devtools-button>
|
|
826
|
+
</div>` : origin ? html`
|
|
827
|
+
<div class="label">Origin</div>
|
|
828
|
+
<div class="value">
|
|
829
|
+
${widget(Components.JSPresentationUtils.StackTracePreviewContent,
|
|
830
|
+
{stackTrace: origin, options: { expandable: true}})}
|
|
831
|
+
</div>` : nothing}
|
|
832
|
+
</div>
|
|
833
|
+
`, target);
|
|
834
|
+
};
|
|
835
|
+
// clang-format on
|
|
836
|
+
|
|
837
|
+
export class ToolDetailsWidget extends UI.Widget.Widget {
|
|
838
|
+
#tool: WebMCP.WebMCPModel.Tool|null|undefined = null;
|
|
839
|
+
#origin: SDK.DOMModel.DOMNode|StackTrace.StackTrace.StackTrace|undefined;
|
|
840
|
+
|
|
841
|
+
#view: typeof TOOL_DETAILS_VIEW;
|
|
842
|
+
|
|
843
|
+
constructor(element?: HTMLElement, view: typeof TOOL_DETAILS_VIEW = TOOL_DETAILS_VIEW) {
|
|
844
|
+
super(element);
|
|
845
|
+
this.#view = view;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
set tool(tool: WebMCP.WebMCPModel.Tool|null|undefined) {
|
|
849
|
+
if (this.#tool === tool) {
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
this.#tool = tool;
|
|
853
|
+
this.#origin = undefined;
|
|
854
|
+
|
|
855
|
+
if (this.#tool) {
|
|
856
|
+
void this.#setToolOrigin(this.#tool);
|
|
857
|
+
}
|
|
858
|
+
this.requestUpdate();
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
async #setToolOrigin(tool: WebMCP.WebMCPModel.Tool): Promise<void> {
|
|
862
|
+
const origin = await (tool.node ? tool.node.resolvePromise() : tool.stackTrace);
|
|
863
|
+
if (this.#tool === tool && origin) {
|
|
864
|
+
this.#origin = origin;
|
|
865
|
+
this.requestUpdate();
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
get tool(): WebMCP.WebMCPModel.Tool|null|undefined {
|
|
870
|
+
return this.#tool;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
#highlightNode = (node: SDK.DOMModel.DOMNode): void => {
|
|
874
|
+
node.highlight();
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
#clearHighlight = (): void => {
|
|
878
|
+
SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight();
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
#revealNode = (node: SDK.DOMModel.DOMNode): void => {
|
|
882
|
+
void Common.Revealer.reveal(node);
|
|
883
|
+
void node.scrollIntoView();
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
override performUpdate(): void {
|
|
887
|
+
const viewInput = {
|
|
888
|
+
tool: this.#tool,
|
|
889
|
+
origin: this.#origin,
|
|
890
|
+
highlightNode: this.#highlightNode,
|
|
891
|
+
clearHighlight: this.#clearHighlight,
|
|
892
|
+
revealNode: this.#revealNode,
|
|
893
|
+
};
|
|
894
|
+
this.#view(viewInput, undefined, this.contentElement);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
override wasShown(): void {
|
|
898
|
+
super.wasShown();
|
|
899
|
+
this.requestUpdate();
|
|
900
|
+
}
|
|
901
|
+
}
|
|
@@ -8,6 +8,7 @@ import * as BackgroundServiceModel from './BackgroundServiceModel.js';
|
|
|
8
8
|
import * as BackgroundServiceView from './BackgroundServiceView.js';
|
|
9
9
|
import * as BounceTrackingMitigationsTreeElement from './BounceTrackingMitigationsTreeElement.js';
|
|
10
10
|
import * as CookieItemsView from './CookieItemsView.js';
|
|
11
|
+
import * as CrashReportContextView from './CrashReportContextView.js';
|
|
11
12
|
import * as DeviceBoundSessionsModel from './DeviceBoundSessionsModel.js';
|
|
12
13
|
import * as DeviceBoundSessionsTreeElement from './DeviceBoundSessionsTreeElement.js';
|
|
13
14
|
import * as DeviceBoundSessionsView from './DeviceBoundSessionsView.js';
|
|
@@ -26,6 +27,7 @@ import * as OpenedWindowDetailsView from './OpenedWindowDetailsView.js';
|
|
|
26
27
|
import * as OriginTrialTreeView from './OriginTrialTreeView.js';
|
|
27
28
|
import * as PreloadingView from './preloading/PreloadingView.js';
|
|
28
29
|
import * as PreloadingTreeElement from './PreloadingTreeElement.js';
|
|
30
|
+
import * as ReportingApiTreeElement from './ReportingApiTreeElement.js';
|
|
29
31
|
import * as ReportingApiView from './ReportingApiView.js';
|
|
30
32
|
import * as ResourcesPanel from './ResourcesPanel.js';
|
|
31
33
|
import * as ServiceWorkerCacheViews from './ServiceWorkerCacheViews.js';
|
|
@@ -50,6 +52,7 @@ export {
|
|
|
50
52
|
BackgroundServiceView,
|
|
51
53
|
BounceTrackingMitigationsTreeElement,
|
|
52
54
|
CookieItemsView,
|
|
55
|
+
CrashReportContextView,
|
|
53
56
|
DeviceBoundSessionsModel,
|
|
54
57
|
DeviceBoundSessionsTreeElement,
|
|
55
58
|
DeviceBoundSessionsView,
|
|
@@ -68,6 +71,7 @@ export {
|
|
|
68
71
|
OriginTrialTreeView,
|
|
69
72
|
PreloadingTreeElement,
|
|
70
73
|
PreloadingView,
|
|
74
|
+
ReportingApiTreeElement,
|
|
71
75
|
ReportingApiView,
|
|
72
76
|
ResourcesPanel,
|
|
73
77
|
ServiceWorkerCacheViews,
|