chrome-devtools-frontend 1.0.1613625 → 1.0.1615539
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/AUTHORS +1 -0
- package/docs/contributing/infrastructure.md +0 -1
- package/front_end/core/common/VersionController.ts +17 -1
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/OverlayModel.ts +2 -4
- package/front_end/core/sdk/sdk-meta.ts +13 -0
- package/front_end/entrypoints/device_mode_emulation_frame/device_mode_emulation_frame.ts +4 -0
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -1
- package/front_end/entrypoints/greendev_floaty/floaty.css +3 -0
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -1
- package/front_end/entrypoints/main/MainImpl.ts +0 -6
- package/front_end/entrypoints/shell/shell.ts +4 -0
- package/front_end/entrypoints/trace_app/trace_app.ts +4 -0
- package/front_end/generated/InspectorBackendCommands.ts +6 -4
- package/front_end/generated/protocol-mapping.d.ts +14 -0
- package/front_end/generated/protocol-proxy-api.d.ts +10 -0
- package/front_end/generated/protocol.ts +33 -3
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +10 -2
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +23 -7
- package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +4 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +200 -46
- package/front_end/models/issues_manager/IssuesManager.ts +4 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +673 -639
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +161 -0
- package/front_end/models/stack_trace/StackTrace.ts +18 -0
- package/front_end/models/stack_trace/StackTraceImpl.ts +96 -4
- package/front_end/models/stack_trace/StackTraceModel.ts +39 -0
- package/front_end/models/stack_trace/Trie.ts +21 -0
- package/front_end/models/stack_trace/stack_trace_impl.ts +2 -0
- package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +55 -14
- package/front_end/panels/ai_assistance/components/ChatView.ts +4 -3
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +4 -1
- package/front_end/panels/ai_assistance/components/optInChangeDialog.css +1 -2
- package/front_end/panels/application/WebMCPView.ts +270 -18
- package/front_end/panels/application/components/ProtocolHandlersView.ts +2 -2
- package/front_end/panels/application/webMCPView.css +4 -1
- package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +7 -0
- package/front_end/panels/console/ConsoleContextSelector.ts +1 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +8 -2
- package/front_end/panels/console/consoleView.css +4 -0
- package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -3
- package/front_end/panels/css_overview/CSSOverviewModel.ts +1 -2
- package/front_end/panels/network/RequestConditionsDrawer.ts +4 -2
- package/front_end/panels/network/RequestPayloadView.ts +8 -3
- package/front_end/panels/network/RequestTimingView.ts +6 -7
- package/front_end/panels/performance_monitor/PerformanceMonitor.ts +7 -5
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/codemirror/codemirror-tsconfig.json +4 -4
- package/front_end/third_party/lighthouse/lighthouse-tsconfig.json +1 -1
- package/front_end/tsconfig.json +2 -1
- package/front_end/ui/legacy/EmptyWidget.ts +2 -2
- package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +1 -2
- package/front_end/ui/legacy/components/color_picker/ContrastOverlay.ts +4 -5
- package/front_end/ui/legacy/components/source_frame/XMLView.ts +12 -7
- package/front_end/ui/lit/lit.ts +4 -1
- package/front_end/ui/lit/render.ts +81 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -1
- package/package.json +1 -1
- /package/front_end/third_party/codemirror/package/addon/runmode/{runmode-standalone.mjs.d.ts → runmode-standalone.d.mts} +0 -0
- /package/front_end/third_party/codemirror/package/mode/css/{css.mjs.d.ts → css.d.mts} +0 -0
- /package/front_end/third_party/codemirror/package/mode/javascript/{javascript.mjs.d.ts → javascript.d.mts} +0 -0
- /package/front_end/third_party/codemirror/package/mode/xml/{xml.mjs.d.ts → xml.d.mts} +0 -0
- /package/front_end/third_party/lighthouse/report-assets/{report-generator.mjs.d.ts → report-generator.d.mts} +0 -0
|
@@ -8,7 +8,10 @@ import '../../ui/components/node_text/node_text.js';
|
|
|
8
8
|
import '../../ui/legacy/components/data_grid/data_grid.js';
|
|
9
9
|
import '../../ui/legacy/legacy.js';
|
|
10
10
|
|
|
11
|
+
import type {JSONSchema7, JSONSchema7Definition} from 'json-schema';
|
|
12
|
+
|
|
11
13
|
import * as Common from '../../core/common/common.js';
|
|
14
|
+
import * as Host from '../../core/host/host.js';
|
|
12
15
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
13
16
|
import * as Platform from '../../core/platform/platform.js';
|
|
14
17
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
@@ -30,6 +33,7 @@ import {
|
|
|
30
33
|
type TemplateResult,
|
|
31
34
|
} from '../../ui/lit/lit.js';
|
|
32
35
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
36
|
+
import * as ProtocolMonitor from '../protocol_monitor/protocol_monitor.js';
|
|
33
37
|
|
|
34
38
|
import webMCPViewStyles from './webMCPView.css.js';
|
|
35
39
|
|
|
@@ -130,7 +134,7 @@ const UIStrings = {
|
|
|
130
134
|
/**
|
|
131
135
|
* @description Text for the status of a tool call that succeeded
|
|
132
136
|
*/
|
|
133
|
-
|
|
137
|
+
completed: 'Completed',
|
|
134
138
|
/**
|
|
135
139
|
* @description Text for the status of a tool call that has failed
|
|
136
140
|
*/
|
|
@@ -155,6 +159,14 @@ const UIStrings = {
|
|
|
155
159
|
* @example {1} PH1
|
|
156
160
|
*/
|
|
157
161
|
inProgressCount: '{PH1} In Progress',
|
|
162
|
+
/**
|
|
163
|
+
* @description Context menu action to copy the name of a tool
|
|
164
|
+
*/
|
|
165
|
+
copyName: 'Copy name',
|
|
166
|
+
/**
|
|
167
|
+
* @description Context menu action to copy the description of a tool
|
|
168
|
+
*/
|
|
169
|
+
copyDescription: 'Copy description',
|
|
158
170
|
} as const;
|
|
159
171
|
const str_ = i18n.i18n.registerUIStrings('panels/application/WebMCPView.ts', UIStrings);
|
|
160
172
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -167,7 +179,7 @@ export interface FilterState {
|
|
|
167
179
|
declarative?: boolean,
|
|
168
180
|
};
|
|
169
181
|
statusTypes?: {
|
|
170
|
-
|
|
182
|
+
completed?: boolean,
|
|
171
183
|
error?: boolean,
|
|
172
184
|
pending?: boolean,
|
|
173
185
|
};
|
|
@@ -202,8 +214,8 @@ export function filterToolCalls(
|
|
|
202
214
|
const statusTypes = filterState.statusTypes;
|
|
203
215
|
if (statusTypes) {
|
|
204
216
|
filtered = filtered.filter(call => {
|
|
205
|
-
const {
|
|
206
|
-
if (
|
|
217
|
+
const {completed, error, pending} = statusTypes;
|
|
218
|
+
if (completed && call.result?.status === Protocol.WebMCP.InvocationStatus.Completed) {
|
|
207
219
|
return true;
|
|
208
220
|
}
|
|
209
221
|
if (error && call.result?.status === Protocol.WebMCP.InvocationStatus.Error) {
|
|
@@ -243,33 +255,33 @@ export function filterToolCalls(
|
|
|
243
255
|
}
|
|
244
256
|
export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
245
257
|
function calculateToolStats(calls: WebMCP.WebMCPModel.Call[]):
|
|
246
|
-
{total: number,
|
|
247
|
-
let total = 0,
|
|
258
|
+
{total: number, completed: number, failed: number, canceled: number, inProgress: number} {
|
|
259
|
+
let total = 0, completed = 0, failed = 0, canceled = 0, inProgress = 0;
|
|
248
260
|
for (const call of calls) {
|
|
249
261
|
total++;
|
|
250
262
|
if (call.result?.status === Protocol.WebMCP.InvocationStatus.Error) {
|
|
251
263
|
failed++;
|
|
252
264
|
} else if (call.result?.status === Protocol.WebMCP.InvocationStatus.Canceled) {
|
|
253
265
|
canceled++;
|
|
254
|
-
} else if (call.result?.status === Protocol.WebMCP.InvocationStatus.
|
|
255
|
-
|
|
266
|
+
} else if (call.result?.status === Protocol.WebMCP.InvocationStatus.Completed) {
|
|
267
|
+
completed++;
|
|
256
268
|
} else if (call.result === undefined) {
|
|
257
269
|
inProgress++;
|
|
258
270
|
}
|
|
259
271
|
}
|
|
260
|
-
return {total,
|
|
272
|
+
return {total, completed, failed, canceled, inProgress};
|
|
261
273
|
}
|
|
262
274
|
|
|
263
275
|
function getIconGroupsFromStats(toolStats: ReturnType<typeof calculateToolStats>):
|
|
264
276
|
IconButton.IconButton.IconWithTextData[] {
|
|
265
277
|
const groups = [];
|
|
266
|
-
if (toolStats.
|
|
278
|
+
if (toolStats.completed > 0) {
|
|
267
279
|
groups.push({
|
|
268
280
|
iconName: 'check-circle',
|
|
269
281
|
iconColor: 'var(--sys-color-green)',
|
|
270
282
|
iconWidth: '16px',
|
|
271
283
|
iconHeight: '16px',
|
|
272
|
-
text: String(toolStats.
|
|
284
|
+
text: String(toolStats.completed),
|
|
273
285
|
});
|
|
274
286
|
}
|
|
275
287
|
if (toolStats.failed > 0) {
|
|
@@ -341,12 +353,22 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
341
353
|
return i18nString(UIStrings.error);
|
|
342
354
|
case Protocol.WebMCP.InvocationStatus.Canceled:
|
|
343
355
|
return i18nString(UIStrings.canceled);
|
|
344
|
-
case Protocol.WebMCP.InvocationStatus.
|
|
345
|
-
return i18nString(UIStrings.
|
|
356
|
+
case Protocol.WebMCP.InvocationStatus.Completed:
|
|
357
|
+
return i18nString(UIStrings.completed);
|
|
346
358
|
default:
|
|
347
359
|
return i18nString(UIStrings.inProgress);
|
|
348
360
|
}
|
|
349
361
|
};
|
|
362
|
+
const onToolContextMenu = (event: Event, tool: WebMCP.WebMCPModel.Tool): void => {
|
|
363
|
+
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
364
|
+
contextMenu.defaultSection().appendItem(i18nString(UIStrings.copyName), () => {
|
|
365
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(tool.name);
|
|
366
|
+
}, {jslogContext: 'webmcp.copy-tool-name'});
|
|
367
|
+
contextMenu.defaultSection().appendItem(i18nString(UIStrings.copyDescription), () => {
|
|
368
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(tool.description);
|
|
369
|
+
}, {jslogContext: 'webmcp.copy-tool-description'});
|
|
370
|
+
void contextMenu.show();
|
|
371
|
+
};
|
|
350
372
|
// clang-format off
|
|
351
373
|
render(html`
|
|
352
374
|
<style>${webMCPViewStyles}</style>
|
|
@@ -488,7 +510,8 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
488
510
|
const groups = getIconGroupsFromStats(toolStats);
|
|
489
511
|
return html`
|
|
490
512
|
<div class=${Directives.classMap({'tool-item': true, selected: tool === input.selectedTool})}
|
|
491
|
-
@click=${() => input.onToolSelect(tool)}
|
|
513
|
+
@click=${() => input.onToolSelect(tool)}
|
|
514
|
+
@contextmenu=${(e: Event) => onToolContextMenu(e, tool)}>
|
|
492
515
|
<div class="tool-name-container">
|
|
493
516
|
<div class="tool-name source-code">${tool.name}</div>
|
|
494
517
|
${groups.length > 0 ? html`<icon-button .data=${
|
|
@@ -600,19 +623,19 @@ export class WebMCPView extends UI.Widget.VBox {
|
|
|
600
623
|
}
|
|
601
624
|
|
|
602
625
|
#showStatusTypesContextMenu(contextMenu: UI.ContextMenu.ContextMenu): void {
|
|
603
|
-
const toggle = (key: '
|
|
626
|
+
const toggle = (key: 'completed'|'error'|'pending'): void => {
|
|
604
627
|
const current = this.#filterState.statusTypes ?? {};
|
|
605
628
|
const next = {...current, [key]: !current[key]};
|
|
606
629
|
let statusTypesToPass: FilterState['statusTypes'] = next;
|
|
607
|
-
if (!next.
|
|
630
|
+
if (!next.completed && !next.error && !next.pending) {
|
|
608
631
|
statusTypesToPass = undefined;
|
|
609
632
|
}
|
|
610
633
|
this.#handleFilterChange({...this.#filterState, statusTypes: statusTypesToPass});
|
|
611
634
|
};
|
|
612
635
|
|
|
613
636
|
contextMenu.defaultSection().appendCheckboxItem(
|
|
614
|
-
i18nString(UIStrings.
|
|
615
|
-
{checked: this.#filterState.statusTypes?.['
|
|
637
|
+
i18nString(UIStrings.completed), () => toggle('completed'),
|
|
638
|
+
{checked: this.#filterState.statusTypes?.['completed'] ?? false, jslogContext: 'webmcp.completed'});
|
|
616
639
|
contextMenu.defaultSection().appendCheckboxItem(
|
|
617
640
|
i18nString(UIStrings.error), () => toggle('error'),
|
|
618
641
|
{checked: this.#filterState.statusTypes?.['error'] ?? false, jslogContext: 'webmcp.error'});
|
|
@@ -990,3 +1013,232 @@ export class ToolDetailsWidget extends UI.Widget.Widget {
|
|
|
990
1013
|
this.requestUpdate();
|
|
991
1014
|
}
|
|
992
1015
|
}
|
|
1016
|
+
|
|
1017
|
+
export interface ParsedToolSchema {
|
|
1018
|
+
parameters: ProtocolMonitor.JSONEditor.Parameter[];
|
|
1019
|
+
typesByName: Map<string, ProtocolMonitor.JSONEditor.Parameter[]>;
|
|
1020
|
+
enumsByName: Map<string, Record<string, string>>;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
const parsedSchemaCache = new WeakMap<object, ParsedToolSchema>();
|
|
1024
|
+
|
|
1025
|
+
export function parseToolSchema(schema: JSONSchema7): ParsedToolSchema {
|
|
1026
|
+
if (typeof schema === 'object' && schema !== null) {
|
|
1027
|
+
const cached = parsedSchemaCache.get(schema);
|
|
1028
|
+
if (cached) {
|
|
1029
|
+
return cached;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
const typesByName = new Map<string, ProtocolMonitor.JSONEditor.Parameter[]>();
|
|
1034
|
+
const enumsByName = new Map<string, Record<string, string>>();
|
|
1035
|
+
const simpleTypesByName = new Map<string, ProtocolMonitor.JSONEditor.ParameterType>();
|
|
1036
|
+
let typeCount = 0;
|
|
1037
|
+
|
|
1038
|
+
function createEnumRecord(values: unknown[]): Record<string, string> {
|
|
1039
|
+
const enumRecord: Record<string, string> = {};
|
|
1040
|
+
for (const val of values) {
|
|
1041
|
+
enumRecord[String(val)] = String(val);
|
|
1042
|
+
}
|
|
1043
|
+
return enumRecord;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
function preScanDefinition(name: string, def: JSONSchema7Definition): void {
|
|
1047
|
+
if (typeof def === 'boolean') {
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1050
|
+
if (def.type === 'string' && def.enum) {
|
|
1051
|
+
enumsByName.set(name, createEnumRecord(def.enum));
|
|
1052
|
+
} else if (def.type && typeof def.type === 'string' && def.type !== 'object' && def.type !== 'array') {
|
|
1053
|
+
let paramType = ProtocolMonitor.JSONEditor.ParameterType.STRING;
|
|
1054
|
+
switch (def.type) {
|
|
1055
|
+
case 'number':
|
|
1056
|
+
case 'integer':
|
|
1057
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.NUMBER;
|
|
1058
|
+
break;
|
|
1059
|
+
case 'boolean':
|
|
1060
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.BOOLEAN;
|
|
1061
|
+
break;
|
|
1062
|
+
}
|
|
1063
|
+
simpleTypesByName.set(name, paramType);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
function parseDefinition(name: string, def: JSONSchema7Definition): void {
|
|
1068
|
+
if (typeof def === 'boolean') {
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
if (def.type === 'object' && def.properties) {
|
|
1072
|
+
const nestedParams: ProtocolMonitor.JSONEditor.Parameter[] = [];
|
|
1073
|
+
for (const [key, value] of Object.entries(def.properties)) {
|
|
1074
|
+
const isOpt = !(def.required || []).includes(key);
|
|
1075
|
+
nestedParams.push(parseProperty(key, value, isOpt));
|
|
1076
|
+
}
|
|
1077
|
+
typesByName.set(name, nestedParams);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// First pass: populate enums and simple types
|
|
1082
|
+
if (schema.definitions) {
|
|
1083
|
+
for (const [name, def] of Object.entries(schema.definitions)) {
|
|
1084
|
+
preScanDefinition(name, def);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
if (schema.$defs) {
|
|
1088
|
+
for (const [name, def] of Object.entries(schema.$defs)) {
|
|
1089
|
+
preScanDefinition(name, def);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
// Second pass: parse objects
|
|
1094
|
+
if (schema.definitions) {
|
|
1095
|
+
for (const [name, def] of Object.entries(schema.definitions)) {
|
|
1096
|
+
parseDefinition(name, def);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
if (schema.$defs) {
|
|
1100
|
+
for (const [name, def] of Object.entries(schema.$defs)) {
|
|
1101
|
+
parseDefinition(name, def);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
function parseProperty(
|
|
1106
|
+
name: string, propDef: JSONSchema7Definition, optional: boolean): ProtocolMonitor.JSONEditor.Parameter {
|
|
1107
|
+
if (typeof propDef === 'boolean') {
|
|
1108
|
+
return {
|
|
1109
|
+
name,
|
|
1110
|
+
optional,
|
|
1111
|
+
description: '',
|
|
1112
|
+
type: ProtocolMonitor.JSONEditor.ParameterType.STRING,
|
|
1113
|
+
isCorrectType: true,
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
const prop = propDef;
|
|
1117
|
+
if (prop.$ref) {
|
|
1118
|
+
const typeRef = prop.$ref.split('/').pop() || '';
|
|
1119
|
+
let paramType = ProtocolMonitor.JSONEditor.ParameterType.OBJECT;
|
|
1120
|
+
if (enumsByName.has(typeRef)) {
|
|
1121
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.STRING;
|
|
1122
|
+
} else {
|
|
1123
|
+
const simpleType = simpleTypesByName.get(typeRef);
|
|
1124
|
+
if (simpleType !== undefined) {
|
|
1125
|
+
paramType = simpleType;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
return {
|
|
1129
|
+
name,
|
|
1130
|
+
optional,
|
|
1131
|
+
description: prop.description || '',
|
|
1132
|
+
type: paramType,
|
|
1133
|
+
typeRef,
|
|
1134
|
+
isCorrectType: true,
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
const typeStr = Array.isArray(prop.type) ? prop.type[0] : prop.type;
|
|
1139
|
+
let type: string|undefined = typeStr === 'integer' ? 'number' : typeStr;
|
|
1140
|
+
if (!typeStr) {
|
|
1141
|
+
if (prop.properties) {
|
|
1142
|
+
type = 'object';
|
|
1143
|
+
} else if (prop.items) {
|
|
1144
|
+
type = 'array';
|
|
1145
|
+
} else {
|
|
1146
|
+
type = 'unknown';
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
const description = prop.description || '';
|
|
1150
|
+
|
|
1151
|
+
let paramType = ProtocolMonitor.JSONEditor.ParameterType.UNKNOWN;
|
|
1152
|
+
switch (type) {
|
|
1153
|
+
case 'string':
|
|
1154
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.STRING;
|
|
1155
|
+
break;
|
|
1156
|
+
case 'number':
|
|
1157
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.NUMBER;
|
|
1158
|
+
break;
|
|
1159
|
+
case 'boolean':
|
|
1160
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.BOOLEAN;
|
|
1161
|
+
break;
|
|
1162
|
+
case 'object':
|
|
1163
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.OBJECT;
|
|
1164
|
+
break;
|
|
1165
|
+
case 'array':
|
|
1166
|
+
paramType = ProtocolMonitor.JSONEditor.ParameterType.ARRAY;
|
|
1167
|
+
break;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
const base: ProtocolMonitor.JSONEditor.Parameter = {
|
|
1171
|
+
name,
|
|
1172
|
+
optional,
|
|
1173
|
+
description,
|
|
1174
|
+
type: paramType,
|
|
1175
|
+
isCorrectType: true,
|
|
1176
|
+
};
|
|
1177
|
+
|
|
1178
|
+
if (type === 'object') {
|
|
1179
|
+
if (prop.properties) {
|
|
1180
|
+
const typeRef = `Object_${++typeCount}`;
|
|
1181
|
+
const nestedParams: ProtocolMonitor.JSONEditor.Parameter[] = [];
|
|
1182
|
+
for (const [key, value] of Object.entries(prop.properties)) {
|
|
1183
|
+
const isOpt = !(prop.required || []).includes(key);
|
|
1184
|
+
nestedParams.push(parseProperty(key, value, isOpt));
|
|
1185
|
+
}
|
|
1186
|
+
typesByName.set(typeRef, nestedParams);
|
|
1187
|
+
base.typeRef = typeRef;
|
|
1188
|
+
} else {
|
|
1189
|
+
base.isKeyEditable = true;
|
|
1190
|
+
}
|
|
1191
|
+
} else if (type === 'array') {
|
|
1192
|
+
const items =
|
|
1193
|
+
prop.items && !Array.isArray(prop.items) && typeof prop.items !== 'boolean' ? prop.items : undefined;
|
|
1194
|
+
if (items) {
|
|
1195
|
+
const itemTypeStr = Array.isArray(items.type) ? items.type[0] : items.type;
|
|
1196
|
+
if (items.$ref) {
|
|
1197
|
+
base.typeRef = items.$ref.split('/').pop() || '';
|
|
1198
|
+
} else if (itemTypeStr === 'object' && items.properties) {
|
|
1199
|
+
const typeRef = `Object_${++typeCount}`;
|
|
1200
|
+
const nestedParams: ProtocolMonitor.JSONEditor.Parameter[] = [];
|
|
1201
|
+
for (const [key, value] of Object.entries(items.properties)) {
|
|
1202
|
+
const isOpt = !(items.required || []).includes(key);
|
|
1203
|
+
nestedParams.push(parseProperty(key, value, isOpt));
|
|
1204
|
+
}
|
|
1205
|
+
typesByName.set(typeRef, nestedParams);
|
|
1206
|
+
base.typeRef = typeRef;
|
|
1207
|
+
} else if (itemTypeStr) {
|
|
1208
|
+
const itemType = itemTypeStr === 'integer' ? 'number' : itemTypeStr;
|
|
1209
|
+
if (itemType === 'string' && items.enum) {
|
|
1210
|
+
const typeRef = `Enum_${++typeCount}`;
|
|
1211
|
+
enumsByName.set(typeRef, createEnumRecord(items.enum));
|
|
1212
|
+
base.typeRef = typeRef;
|
|
1213
|
+
} else {
|
|
1214
|
+
base.typeRef = itemType as string;
|
|
1215
|
+
}
|
|
1216
|
+
} else {
|
|
1217
|
+
base.typeRef = 'string';
|
|
1218
|
+
}
|
|
1219
|
+
} else {
|
|
1220
|
+
base.typeRef = 'string';
|
|
1221
|
+
}
|
|
1222
|
+
} else if (type === 'string' && prop.enum) {
|
|
1223
|
+
const typeRef = `Enum_${++typeCount}`;
|
|
1224
|
+
enumsByName.set(typeRef, createEnumRecord(prop.enum));
|
|
1225
|
+
base.typeRef = typeRef;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
return base;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
const parameters: ProtocolMonitor.JSONEditor.Parameter[] = [];
|
|
1232
|
+
if ((schema.type === 'object' || !schema.type) && schema.properties) {
|
|
1233
|
+
for (const [key, value] of Object.entries(schema.properties)) {
|
|
1234
|
+
const isOpt = !(schema.required || []).includes(key);
|
|
1235
|
+
parameters.push(parseProperty(key, value, isOpt));
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
const result = {parameters, typesByName, enumsByName};
|
|
1240
|
+
if (typeof schema === 'object' && schema !== null) {
|
|
1241
|
+
parsedSchemaCache.set(schema, result);
|
|
1242
|
+
}
|
|
1243
|
+
return result;
|
|
1244
|
+
}
|
|
@@ -150,7 +150,7 @@ const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
150
150
|
</div>
|
|
151
151
|
${renderProtocolTest(input.protocolHandler, input.queryInputState, input.protocolSelectHandler,
|
|
152
152
|
input.queryInputChangeHandler, input.testProtocolClickHandler)}
|
|
153
|
-
`, target);
|
|
153
|
+
`, target, {container: {classes: ['vbox']}});
|
|
154
154
|
// clang-format on
|
|
155
155
|
};
|
|
156
156
|
|
|
@@ -172,7 +172,7 @@ export class ProtocolHandlersView extends UI.Widget.Widget {
|
|
|
172
172
|
#view: View;
|
|
173
173
|
|
|
174
174
|
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
|
175
|
-
super(element, {useShadowDom: false
|
|
175
|
+
super(element, {useShadowDom: false});
|
|
176
176
|
this.#view = view;
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
height: 100%;
|
|
78
78
|
display: flex;
|
|
79
79
|
flex-direction: column;
|
|
80
|
-
overflow:
|
|
80
|
+
overflow: hidden;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
.tool-details-grid {
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
gap: 0 var(--sys-size-16);
|
|
87
87
|
padding: calc(0.5*var(--sys-size-6)) var(--sys-size-8);
|
|
88
88
|
align-items: flex-start;
|
|
89
|
+
overflow-y: auto;
|
|
89
90
|
|
|
90
91
|
.label {
|
|
91
92
|
color: var(--sys-color-on-surface-subtle);
|
|
@@ -94,6 +95,8 @@
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
.value {
|
|
98
|
+
user-select: text;
|
|
99
|
+
|
|
97
100
|
&.source-code {
|
|
98
101
|
color: var(--sys-color-token-attribute);
|
|
99
102
|
}
|
|
@@ -166,8 +166,15 @@ export const DEFAULT_SUMMARY_TOOLBAR_VIEW: View =
|
|
|
166
166
|
role="link"
|
|
167
167
|
jslog=${VisualLogging.link('open-ai-settings').track({
|
|
168
168
|
click: true,
|
|
169
|
+
keydown: 'Enter',
|
|
169
170
|
})}
|
|
170
171
|
@click=${input.onManageInSettingsTooltipClick}
|
|
172
|
+
@keydown=${(e: KeyboardEvent) => {
|
|
173
|
+
if (e.key === 'Enter') {
|
|
174
|
+
e.consume(true);
|
|
175
|
+
input.onManageInSettingsTooltipClick();
|
|
176
|
+
}
|
|
177
|
+
}}
|
|
171
178
|
>${lockedString(UIStringsNotTranslate.manageInSettings)}</span></div></devtools-tooltip>
|
|
172
179
|
</div>
|
|
173
180
|
`, target);
|
|
@@ -303,7 +303,7 @@ interface ViewInput {
|
|
|
303
303
|
type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
|
|
304
304
|
|
|
305
305
|
const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
306
|
-
if (!input.title
|
|
306
|
+
if (!input.title) {
|
|
307
307
|
render(nothing, target);
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
@@ -1592,7 +1592,10 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
1592
1592
|
const label = document.createElement('div');
|
|
1593
1593
|
label.classList.add('button-label');
|
|
1594
1594
|
const text = document.createElement('div');
|
|
1595
|
-
|
|
1595
|
+
// We use a data attribute and a CSS pseudo-element for the button label
|
|
1596
|
+
// to prevent the text from being picked up by the console's custom
|
|
1597
|
+
// copy-to-clipboard traversal, which only collects actual text nodes.
|
|
1598
|
+
text.setAttribute('data-text', this.getExplainLabel());
|
|
1596
1599
|
label.append(text);
|
|
1597
1600
|
button.append(label);
|
|
1598
1601
|
button.classList.add('hover-button');
|
|
@@ -1615,7 +1618,10 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
1615
1618
|
const label = document.createElement('div');
|
|
1616
1619
|
label.classList.add('button-label');
|
|
1617
1620
|
const text = document.createElement('div');
|
|
1618
|
-
|
|
1621
|
+
// We use a data attribute and a CSS pseudo-element for the button label
|
|
1622
|
+
// to prevent the text from being picked up by the console's custom
|
|
1623
|
+
// copy-to-clipboard traversal, which only collects actual text nodes.
|
|
1624
|
+
text.setAttribute('data-text', 'Debug with breakpoint AI');
|
|
1619
1625
|
label.append(text);
|
|
1620
1626
|
button.append(label);
|
|
1621
1627
|
button.classList.add('hover-button');
|
|
@@ -8,7 +8,6 @@ import '../../ui/kit/kit.js';
|
|
|
8
8
|
import * as Common from '../../core/common/common.js';
|
|
9
9
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
10
10
|
import * as Platform from '../../core/platform/platform.js';
|
|
11
|
-
import * as Root from '../../core/root/root.js';
|
|
12
11
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
13
12
|
import type * as Protocol from '../../generated/protocol.js';
|
|
14
13
|
import * as Geometry from '../../models/geometry/geometry.js';
|
|
@@ -483,7 +482,7 @@ function renderContrastIssue(key: string, issues: ContrastIssue[]): TemplateResu
|
|
|
483
482
|
const color = (minContrastIssue.textColor.asString(Common.Color.Format.HEXA));
|
|
484
483
|
const backgroundColor = (minContrastIssue.backgroundColor.asString(Common.Color.Format.HEXA));
|
|
485
484
|
|
|
486
|
-
const showAPCA =
|
|
485
|
+
const showAPCA = Common.Settings.Settings.instance().moduleSetting('apca').get();
|
|
487
486
|
|
|
488
487
|
const title = i18nString(UIStrings.textColorSOverSBackgroundResults, {
|
|
489
488
|
PH1: color,
|
|
@@ -1041,7 +1040,7 @@ function renderContrastRatio(data: PopulateNodesEventNodeTypes): TemplateResult
|
|
|
1041
1040
|
if (!('contrastRatio' in data)) {
|
|
1042
1041
|
throw new Error('Contrast ratio entry is missing a contrast ratio.');
|
|
1043
1042
|
}
|
|
1044
|
-
const showAPCA =
|
|
1043
|
+
const showAPCA = Common.Settings.Settings.instance().moduleSetting('apca').get();
|
|
1045
1044
|
const contrastRatio = Platform.NumberUtilities.floor(data.contrastRatio, 2);
|
|
1046
1045
|
const contrastRatioString = showAPCA ? contrastRatio + '%' : contrastRatio;
|
|
1047
1046
|
const border = getBorderString(data.backgroundColor);
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
|
-
import * as Root from '../../core/root/root.js';
|
|
7
6
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
7
|
import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
|
|
9
8
|
import type * as Protocol from '../../generated/protocol.js';
|
|
@@ -267,7 +266,7 @@ export class CSSOverviewModel extends SDK.SDKModel.SDKModel<void> {
|
|
|
267
266
|
const formattedTextColor = formatColor(blendedTextColor);
|
|
268
267
|
const formattedBackgroundColor = formatColor(blendedBackgroundColor.asLegacyColor());
|
|
269
268
|
const key = `${formattedTextColor}_${formattedBackgroundColor}`;
|
|
270
|
-
if (
|
|
269
|
+
if (Common.Settings.Settings.instance().moduleSetting('apca').get()) {
|
|
271
270
|
const contrastRatio = contrastInfo.contrastRatioAPCA();
|
|
272
271
|
const threshold = contrastInfo.contrastRatioAPCAThreshold();
|
|
273
272
|
const passes = contrastRatio && threshold ? Math.abs(contrastRatio) >= threshold : false;
|
|
@@ -291,7 +291,9 @@ interface AffectedCountViewInput {
|
|
|
291
291
|
}
|
|
292
292
|
type AffectedCountView = (input: AffectedCountViewInput, output: object, target: HTMLElement) => void;
|
|
293
293
|
export const AFFECTED_COUNT_DEFAULT_VIEW: AffectedCountView = (input, output, target) => {
|
|
294
|
-
render(
|
|
294
|
+
render(
|
|
295
|
+
html`${i18nString(UIStrings.dAffected, {PH1: input.count})}`, target,
|
|
296
|
+
{container: {classes: ['blocked-url-count']}});
|
|
295
297
|
};
|
|
296
298
|
|
|
297
299
|
function matchesUrl(conditions: SDK.NetworkManager.RequestCondition, url: string): boolean {
|
|
@@ -304,7 +306,7 @@ export class AffectedCountWidget extends UI.Widget.Widget {
|
|
|
304
306
|
#lookUpRequestCount?: (condition: SDK.NetworkManager.RequestCondition) => number;
|
|
305
307
|
|
|
306
308
|
constructor(target?: HTMLElement, view = AFFECTED_COUNT_DEFAULT_VIEW) {
|
|
307
|
-
super(target
|
|
309
|
+
super(target);
|
|
308
310
|
this.#view = view;
|
|
309
311
|
}
|
|
310
312
|
|
|
@@ -289,8 +289,13 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
289
289
|
</ul>
|
|
290
290
|
</li>
|
|
291
291
|
</ul>
|
|
292
|
-
`}></devtools-tree
|
|
293
|
-
|
|
292
|
+
`}></devtools-tree>`, target, {
|
|
293
|
+
container: {
|
|
294
|
+
classes: ['request-payload-view'],
|
|
295
|
+
attributes: {
|
|
296
|
+
jslog: `${VisualLogging.pane('payload').track({resize: true})}`,
|
|
297
|
+
},
|
|
298
|
+
}});
|
|
294
299
|
// clang-format on
|
|
295
300
|
};
|
|
296
301
|
|
|
@@ -305,7 +310,7 @@ export class RequestPayloadView extends UI.Widget.VBox {
|
|
|
305
310
|
#viewQueryParamSource = false;
|
|
306
311
|
|
|
307
312
|
constructor(target?: HTMLElement, view = DEFAULT_VIEW) {
|
|
308
|
-
super(
|
|
313
|
+
super();
|
|
309
314
|
this.#view = view;
|
|
310
315
|
}
|
|
311
316
|
|
|
@@ -407,9 +407,9 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
407
407
|
}
|
|
408
408
|
}
|
|
409
409
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
410
|
+
// clang-format off
|
|
411
|
+
render(html`
|
|
412
|
+
<style>${networkingTimingTableStyles}</style>
|
|
413
413
|
<table
|
|
414
414
|
class=${classes}
|
|
415
415
|
jslog=${VisualLogging.pane('timing').track({
|
|
@@ -532,9 +532,8 @@ ${uiI18n.getFormatLocalizedStringTemplate(str_, UIStrings.duringDevelopmentYouCa
|
|
|
532
532
|
html`<devtools-link href="https://web.dev/custom-metrics/#server-timing-api" .jslogContext=${'server-timing-api'}>${i18nString(UIStrings.theServerTimingApi)}</devtools-link>`})}
|
|
533
533
|
</td>
|
|
534
534
|
</tr>` : nothing}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
target);
|
|
535
|
+
</table>`, target, {container: {classes: ['resource-timing-view']}});
|
|
536
|
+
// clang-format on
|
|
538
537
|
};
|
|
539
538
|
|
|
540
539
|
export class RequestTimingView extends UI.Widget.VBox {
|
|
@@ -543,7 +542,7 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
543
542
|
#lastMinimumBoundary = -1;
|
|
544
543
|
readonly #view: View;
|
|
545
544
|
constructor(target?: HTMLElement, view = DEFAULT_VIEW) {
|
|
546
|
-
super(target
|
|
545
|
+
super(target);
|
|
547
546
|
this.#view = view;
|
|
548
547
|
}
|
|
549
548
|
|
|
@@ -626,8 +626,9 @@ interface ControlPaneInput {
|
|
|
626
626
|
type ControlPaneView = (input: ControlPaneInput, output: object, target: HTMLElement) => void;
|
|
627
627
|
|
|
628
628
|
const CONTROL_PANE_DEFAULT_VIEW: ControlPaneView = (input, _output, target) => {
|
|
629
|
-
|
|
630
|
-
|
|
629
|
+
// clang-format off
|
|
630
|
+
render(html`
|
|
631
|
+
${input.chartsInfo.map(chartInfo => {
|
|
631
632
|
const chartName = chartInfo.metrics[0].name;
|
|
632
633
|
const active = input.enabledCharts.has(chartName);
|
|
633
634
|
const value = input.metricValues.get(chartName) || 0;
|
|
@@ -637,8 +638,9 @@ const CONTROL_PANE_DEFAULT_VIEW: ControlPaneView = (input, _output, target) => {
|
|
|
637
638
|
value,
|
|
638
639
|
(e: Event) => input.onCheckboxChange(chartName, e),
|
|
639
640
|
);
|
|
640
|
-
})
|
|
641
|
-
|
|
641
|
+
})}
|
|
642
|
+
`, target, {container: {classes: ['perfmon-control-pane']}});
|
|
643
|
+
// clang-format on
|
|
642
644
|
};
|
|
643
645
|
|
|
644
646
|
export class ControlPane extends UI.Widget.VBox {
|
|
@@ -651,7 +653,7 @@ export class ControlPane extends UI.Widget.VBox {
|
|
|
651
653
|
readonly #view: ControlPaneView;
|
|
652
654
|
|
|
653
655
|
constructor(element: HTMLElement, view = CONTROL_PANE_DEFAULT_VIEW) {
|
|
654
|
-
super(element, {useShadowDom: false
|
|
656
|
+
super(element, {useShadowDom: false});
|
|
655
657
|
this.#view = view;
|
|
656
658
|
|
|
657
659
|
this.#enabledChartsSetting = Common.Settings.Settings.instance().createSetting(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: Internal
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: 7e9e4ee5d284534f90cf424bf02eb9d65ed151ec
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|