Skip to content

Commit 6c08c9f

Browse files
pfaffedevtools-frontend-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
[webmcp] Extend JSON editor for non-CDP commands
This adds some properties to control whether to show the target selector and command name, as well as a setter for the metadata. Also adds an UNKNOWN parameter type which takes raw json. Bug: 494516094 Change-Id: I8bef6342332512ed56f5fd2b0870fdd1fd862130 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7761663 Reviewed-by: Alex Rudenko <alexrudenko@chromium.org> Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
1 parent 146f5b5 commit 6c08c9f

File tree

2 files changed

+90
-3
lines changed

2 files changed

+90
-3
lines changed

front_end/panels/protocol_monitor/JSONEditor.test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,35 @@ describeWithEnvironment('JSONEditor', () => {
10411041

10421042
assert.deepEqual(response.parameters, expectedParameters);
10431043
});
1044+
1045+
it('should format unknown parameters as parsed JSON if they contain JSON, or verbatim otherwise', async () => {
1046+
const jsonEditor = renderJSONEditor();
1047+
jsonEditor.command = 'Test.test';
1048+
jsonEditor.parameters = [
1049+
{
1050+
name: 'anyOfProp1',
1051+
type: ProtocolMonitor.JSONEditor.ParameterType.UNKNOWN,
1052+
description: 'test',
1053+
optional: false,
1054+
value: '{"a": 1}',
1055+
},
1056+
{
1057+
name: 'anyOfProp2',
1058+
type: ProtocolMonitor.JSONEditor.ParameterType.UNKNOWN,
1059+
description: 'test',
1060+
optional: false,
1061+
value: 'raw string',
1062+
},
1063+
];
1064+
await jsonEditor.updateComplete;
1065+
1066+
const expectedParameters = {
1067+
anyOfProp1: {a: 1},
1068+
anyOfProp2: 'raw string',
1069+
};
1070+
1071+
assert.deepEqual(jsonEditor.getParameters(), expectedParameters);
1072+
});
10441073
});
10451074

10461075
describe('Verify the type of the entered value', () => {
@@ -1311,6 +1340,38 @@ describeWithEnvironment('JSONEditor', () => {
13111340
assert.deepEqual(numberOfInputs, 4);
13121341
});
13131342

1343+
describe('UI Visibility Properties', () => {
1344+
it('hides the target selector when displayTargetSelector is false', async () => {
1345+
const jsonEditor = renderJSONEditor();
1346+
jsonEditor.displayTargetSelector = false;
1347+
jsonEditor.performUpdate();
1348+
await jsonEditor.updateComplete;
1349+
1350+
const targetSelector = jsonEditor.contentElement.querySelector('.target-selector');
1351+
assert.isNull(targetSelector);
1352+
});
1353+
1354+
it('hides the command input when displayCommandInput is false', async () => {
1355+
const jsonEditor = renderJSONEditor();
1356+
jsonEditor.displayCommandInput = false;
1357+
jsonEditor.performUpdate();
1358+
await jsonEditor.updateComplete;
1359+
1360+
const commandInput = jsonEditor.contentElement.querySelector('.command');
1361+
assert.isNull(commandInput);
1362+
});
1363+
1364+
it('sets the command via commandToDisplay', async () => {
1365+
const jsonEditor = renderJSONEditor();
1366+
jsonEditor.commandToDisplay = 'Test.testCommand';
1367+
await jsonEditor.updateComplete;
1368+
1369+
assert.strictEqual(jsonEditor.command, 'Test.testCommand');
1370+
const input = jsonEditor.contentElement.querySelector('devtools-suggestion-input');
1371+
assert.strictEqual((input as SuggestionInput.SuggestionInput.SuggestionInput).value, 'Test.testCommand');
1372+
});
1373+
});
1374+
13141375
describe('Command suggestion filter', () => {
13151376
it('filters the commands by substring match', async () => {
13161377
assert(ProtocolMonitor.JSONEditor.suggestionFilter('Test', 'Tes'));

front_end/panels/protocol_monitor/JSONEditor.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export const enum ParameterType {
6464
BOOLEAN = 'boolean',
6565
ARRAY = 'array',
6666
OBJECT = 'object',
67+
UNKNOWN = 'unknown',
6768
}
6869

6970
interface BaseParameter {
@@ -100,7 +101,13 @@ interface ObjectParameter extends BaseParameter {
100101
value?: Parameter[];
101102
}
102103

103-
export type Parameter = ArrayParameter|NumberParameter|StringParameter|BooleanParameter|ObjectParameter;
104+
interface UnknownParameter extends BaseParameter {
105+
type: ParameterType.UNKNOWN;
106+
value?: string;
107+
}
108+
109+
export type Parameter =
110+
ArrayParameter|NumberParameter|StringParameter|BooleanParameter|ObjectParameter|UnknownParameter;
104111

105112
export interface Command {
106113
command: string;
@@ -128,6 +135,8 @@ interface ViewInput {
128135
onParameterKeydown: (event: KeyboardEvent) => void;
129136
onParameterKeyBlur: (event: Event) => void;
130137
onParameterValueBlur: (event: Event) => void;
138+
displayTargetSelector?: boolean;
139+
displayCommandInput?: boolean;
131140
}
132141

133142
export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
@@ -149,6 +158,7 @@ const defaultValueByType = new Map<string, string|number|boolean>([
149158
['string', ''],
150159
['number', 0],
151160
['boolean', false],
161+
['unknown', ''],
152162
]);
153163

154164
const DUMMY_DATA = 'dummy';
@@ -176,6 +186,8 @@ export class JSONEditor extends Common.ObjectWrapper.eventMixin<EventTypes, type
176186
#targetId?: string;
177187
#hintPopoverHelper?: UI.PopoverHelper.PopoverHelper;
178188
#view: View;
189+
displayTargetSelector = true;
190+
displayCommandInput = true;
179191

180192
constructor(element: HTMLElement, view = DEFAULT_VIEW) {
181193
super(element, {useShadowDom: true});
@@ -240,6 +252,10 @@ export class JSONEditor extends Common.ObjectWrapper.eventMixin<EventTypes, type
240252
}
241253
}
242254

255+
set commandToDisplay(command: string) {
256+
this.displayCommand(command, {});
257+
}
258+
243259
get targetId(): string|undefined {
244260
return this.#targetId;
245261
}
@@ -312,6 +328,13 @@ export class JSONEditor extends Common.ObjectWrapper.eventMixin<EventTypes, type
312328
}
313329
return nestedArrayParameters.length === 0 ? [] : nestedArrayParameters;
314330
}
331+
case ParameterType.UNKNOWN: {
332+
try {
333+
return JSON.parse(parameter.value as string);
334+
} catch {
335+
return parameter.value;
336+
}
337+
}
315338
default: {
316339
return parameter.value;
317340
}
@@ -967,6 +990,8 @@ export class JSONEditor extends Common.ObjectWrapper.eventMixin<EventTypes, type
967990
computeDropdownValues: (parameter: Parameter) => {
968991
return this.#computeDropdownValues(parameter);
969992
},
993+
displayTargetSelector: this.displayTargetSelector,
994+
displayCommandInput: this.displayCommandInput,
970995
};
971996
const viewOutput = {};
972997
this.#view(viewInput, viewOutput, this.contentElement);
@@ -1229,7 +1254,8 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
12291254
render(html`
12301255
<div class="wrapper" @keydown=${input.onKeydown} jslog=${VisualLogging.pane('command-editor').track({resize: true})}>
12311256
<div class="editor-wrapper">
1232-
${renderTargetSelectorRow(input)}
1257+
${input.displayTargetSelector !== false ? renderTargetSelectorRow(input) : nothing}
1258+
${input.displayCommandInput !== false ? html`
12331259
<div class="row attribute padded">
12341260
<div class="command">command<span class="separator">:</span></div>
12351261
<devtools-suggestion-input
@@ -1241,7 +1267,7 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
12411267
@blur=${input.onCommandInputBlur}
12421268
class=${classMap({'json-input': true})}
12431269
></devtools-suggestion-input>
1244-
</div>
1270+
</div>` : nothing}
12451271
${input.parameters.length ? html`
12461272
<div class="row attribute padded">
12471273
<div>parameters<span class="separator">:</span></div>

0 commit comments

Comments
 (0)