@@ -150,17 +150,16 @@ export class RESTDebugPanel {
150
150
api . config . pathPrefix
151
151
} `;
152
152
153
- // Get the path to the @vscode /webview-ui-toolkit minimized js
154
- const toolkitUri = this . _panel . webview . asWebviewUri ( vscode . Uri . joinPath ( webviewFolderUri , "toolkit-1.2.1.min.js" ) ) ;
155
-
156
153
// Set the webview's content
157
154
this . _panel . webview . html = `
158
155
<!DOCTYPE html>
159
156
<html lang="en-us">
160
157
<head>
161
158
<meta charset="UTF-8">
162
159
<meta name="viewport" content="width=device-width, initial-scale=1.0">
163
- <script type="module" src="${ toolkitUri } "></script>
160
+ <script type="module" src="${ this . _panel . webview . asWebviewUri (
161
+ vscode . Uri . joinPath ( webviewFolderUri , "elements-1.6.3.js" )
162
+ ) } "></script>
164
163
<title>${ RESTDebugPanel . _viewTitle } </title>
165
164
<style>
166
165
.path-grid {
@@ -171,10 +170,10 @@ export class RESTDebugPanel {
171
170
.component-container > * {
172
171
margin: 0.5rem 0;
173
172
}
174
- vscode-text-area , vscode-text-field {
173
+ vscode-textarea , vscode-textfield {
175
174
width: 100%;
176
175
}
177
- vscode-panels {
176
+ vscode-tabs {
178
177
display: contents;
179
178
}
180
179
.path-grid-container {
@@ -187,90 +186,88 @@ export class RESTDebugPanel {
187
186
max-width: 45vw;
188
187
}
189
188
#button {
190
- margin-top: 1rem;
189
+ margin-top: 0.5rem;
190
+ }
191
+ vscode-tab-panel {
192
+ overflow: visible;
191
193
}
192
194
</style>
193
195
</head>
194
196
<body>
195
197
<h1>${ RESTDebugPanel . _viewTitle } </h1>
196
- <form id="form">
197
- <p>
198
- Use the tabs below to specify the REST request method, path, headers, query parameters and body.
199
- Click the 'Start Debugging' button to send the REST request and start the debugging session.
200
- </p>
201
- <vscode-panels id="panels" activeid="methodPathTab" aria-label="Method & Path, Headers, Query Parameters and Body">
202
- <vscode-panel-tab id="methodPathTab">METHOD & PATH</vscode-panel-tab>
203
- <vscode-panel-tab id="headersTab">HEADERS</vscode-panel-tab>
204
- <vscode-panel-tab id="paramsTab">QUERY PARAMETERS</vscode-panel-tab>
205
- <vscode-panel-tab id="bodyTab">BODY</vscode-panel-tab>
206
- <vscode-panel-view id="methodPathView">
198
+ <form id="form">
199
+ <p>Use the tabs below to specify the REST request method, path, headers, query parameters and body.</p>
200
+ <p>Click the <vscode-badge>Start Debugging</vscode-badge> button to send the REST request and start the debugging session.</p>
201
+ <vscode-divider></vscode-divider>
202
+ <vscode-tabs id="panels" selected-index="0" aria-label="Method & Path, Headers, Query Parameters and Body">
203
+ <vscode-tab-header id="methodPathTab">METHOD & PATH</vscode-tab-header>
204
+ <vscode-tab-header id="headersTab">HEADERS</vscode-tab-header>
205
+ <vscode-tab-header id="paramsTab">QUERY PARAMETERS</vscode-tab-header>
206
+ <vscode-tab-header id="bodyTab">BODY</vscode-tab-header>
207
+ <vscode-tab-panel id="methodPathView">
207
208
<section class="component-container">
208
209
<p>
209
210
Select a method for this request, then select the web application
210
211
to use from the dropdown and enter the rest of the path in the input field
211
- next to the dropdown. The connection information of the server definition
212
+ next to the dropdown.
213
+ </p>
214
+ <p>
215
+ The connection information of the server definition
212
216
is shown for clarity but it cannot be edited.
213
217
</p>
214
- <vscode-radio-group id="method" orientation="horizontal ">
215
- <vscode-radio checked value="GET">GET</vscode-radio>
216
- <vscode-radio value="POST">POST</vscode-radio>
217
- <vscode-radio value="PUT">PUT</vscode-radio>
218
- <vscode-radio value="PATCH">PATCH</vscode-radio>
219
- <vscode-radio value="DELETE">DELETE</vscode-radio>
220
- <vscode-radio value="HEAD">HEAD</vscode-radio>
221
- <vscode-radio value="OPTIONS">OPTIONS</vscode-radio>
218
+ <vscode-radio-group id="method" name="method ">
219
+ <vscode-radio value="GET" name="method" checked >GET</vscode-radio>
220
+ <vscode-radio value="POST" name="method" >POST</vscode-radio>
221
+ <vscode-radio value="PUT" name="method" >PUT</vscode-radio>
222
+ <vscode-radio value="PATCH" name="method" >PATCH</vscode-radio>
223
+ <vscode-radio value="DELETE" name="method" >DELETE</vscode-radio>
224
+ <vscode-radio value="HEAD" name="method" >HEAD</vscode-radio>
225
+ <vscode-radio value="OPTIONS" name="method" >OPTIONS</vscode-radio>
222
226
</vscode-radio-group>
223
- <vscode-text-field readonly id="serverInfo"></vscode-text-field >
227
+ <vscode-textfield readonly id="serverInfo"></vscode-textfield >
224
228
<section class="path-grid">
225
229
<section class="path-grid-container">
226
- <vscode-dropdown id="webApp" position="below"></vscode-dropdown >
230
+ <vscode-single-select id="webApp" name="webApp" position="below"></vscode-single-select >
227
231
</section>
228
232
<section class="path-grid-container">
229
- <vscode-text-field id="path" placeholder="/path"></vscode-text-field >
233
+ <vscode-textfield id="path" name="path" placeholder="/path" pattern="^/.*$" required ></vscode-textfield >
230
234
</section>
231
235
</section>
232
236
</section>
233
- </vscode-panel-view >
234
- <vscode-panel-view id="headersView">
237
+ </vscode-tab-panel >
238
+ <vscode-tab-panel id="headersView">
235
239
<section class="component-container">
236
- <p>
237
- Enter your HTTP headers below, one per line, using the format 'HEADER: value'.
238
- If no 'Authorization' header is present, the username and password of the server connection will be used.
239
- If you provide a body, the 'Content-Type' header will be set automatically.
240
- To disable a header, add a hash (#) to the start of that line.
241
- </p>
242
- <vscode-text-area id="headersText" resize="vertical" placeholder="HEADER: value\n# INACTIVE_HEADER: value" rows="5"></vscode-text-area>
240
+ <p>Enter your HTTP headers below, one per line, using the format 'HEADER: value'.</p>
241
+ <p>If no 'Authorization' header is present, the username and password of the server connection will be used.</p>
242
+ <p>If you provide a body, the 'Content-Type' header will be set automatically.</p>
243
+ <p>To disable a header, add a hash (<vscode-badge>#</vscode-badge>) to the start of that line.</p>
244
+ <vscode-textarea id="headersText" name="headersText" resize="vertical" placeholder="HEADER: value\n# INACTIVE_HEADER: value" rows="5"></vscode-textarea>
243
245
</section>
244
- </vscode-panel-view >
245
- <vscode-panel-view id="paramsView">
246
+ </vscode-tab-panel >
247
+ <vscode-tab-panel id="paramsView">
246
248
<section class="component-container">
247
- <p>
248
- Enter your query parameters below, one per line, using the format 'param=1'.
249
- To disable a query parameter, add a hash (#) to the start of that line.
250
- </p>
251
- <vscode-text-area id="paramsText" resize="vertical" placeholder="param=1\n# inactive-param=1" rows="5"></vscode-text-area>
249
+ <p>Enter your query parameters below, one per line, using the format 'param=value'.</p>
250
+ <p>To disable a query parameter, add a hash (<vscode-badge>#</vscode-badge>) to the start of that line.</p>
251
+ <vscode-textarea id="paramsText" name="paramsText" resize="vertical" placeholder="param=1\n# inactive-param=1" rows="5"></vscode-textarea>
252
252
</section>
253
- </vscode-panel-view >
254
- <vscode-panel-view id="bodyView">
253
+ </vscode-tab-panel >
254
+ <vscode-tab-panel id="bodyView">
255
255
<section class="component-container">
256
- <p>
257
- To provide a request body, select the type of the body content
258
- and enter the content in the text box that appears.
259
- </p>
260
- <vscode-radio-group id="bodyType" orientation="horizontal">
261
- <vscode-radio checked value="No Body">No Body</vscode-radio>
262
- <vscode-radio value="JSON">JSON</vscode-radio>
263
- <vscode-radio value="Text">Text</vscode-radio>
264
- <vscode-radio value="XML">XML</vscode-radio>
265
- <vscode-radio value="HTML">HTML</vscode-radio>
256
+ <p>To provide a request body, select the type of the body content and enter the content in the text box that appears.</p>
257
+ <vscode-radio-group id="bodyType" name="bodyType">
258
+ <vscode-radio checked value="No Body" name="bodyType">No Body</vscode-radio>
259
+ <vscode-radio value="JSON" name="bodyType">JSON</vscode-radio>
260
+ <vscode-radio value="Text" name="bodyType">Text</vscode-radio>
261
+ <vscode-radio value="XML" name="bodyType">XML</vscode-radio>
262
+ <vscode-radio value="HTML" name="bodyType">HTML</vscode-radio>
266
263
</vscode-radio-group>
267
- <vscode-text-area id="bodyContent" resize="vertical" rows="10" hidden></vscode-text-area >
264
+ <vscode-textarea id="bodyContent" name="bodyContent" resize="vertical" rows="10" hidden></vscode-textarea >
268
265
</section>
269
- </vscode-panel-view >
270
- </vscode-panels >
266
+ </vscode-tab-panel >
267
+ </vscode-tabs >
271
268
</form>
272
269
<vscode-divider></vscode-divider>
273
- <vscode-button id="button" appearance="primary" type="button" >Start Debugging</vscode-button>
270
+ <vscode-button id="button">Start Debugging</vscode-button>
274
271
<script>
275
272
const vscode = acquireVsCodeApi();
276
273
const form = document.getElementById("form");
@@ -284,76 +281,75 @@ export class RESTDebugPanel {
284
281
const button = document.getElementById("button");
285
282
const webApp = document.getElementById("webApp");
286
283
const formFields = [method, serverInfo, path, headersText, paramsText, bodyType, bodyContent, webApp];
284
+ const sendData = (submitted) => {
285
+ const data = Object.fromEntries(new FormData(form));
286
+ if (
287
+ Object.keys(data).length == (formFields.length - 1) &&
288
+ data.webApp != "" && data.method != "" && data.bodyType != "" &&
289
+ (!submitted || (submitted && path.checkValidity()))
290
+ ) {
291
+ vscode.postMessage({
292
+ submitted,
293
+ ...data
294
+ });
295
+ }
296
+ };
287
297
288
- const setFormData = (data) => {
298
+ window.onmessage = (event) => {
299
+ const data = event.data, currentVals = new FormData(form);
289
300
formFields.forEach((field) => {
290
- if (data[field.id] && field.value != data[field.id]) {
291
- field.value = data[field.id];
292
- }
293
301
if (field.id == "webApp" && webApp.children.length == 0) {
294
302
// Create options and set the initial value
303
+ const initIdx = data.webApps.findIndex((e) => e == data.webApp) ?? 0;
295
304
data.webApps.forEach((webAppStr, idx) => {
296
305
const option = document.createElement("vscode-option");
297
306
option.innerText = webAppStr;
298
307
option.setAttribute("value",webAppStr);
299
- if (idx == 0 ) {
300
- option.setAttribute(" selected", true) ;
308
+ if (idx == initIdx ) {
309
+ option.selected = true;
301
310
}
302
311
webApp.appendChild(option);
303
- if (idx == 0) {
304
- webApp.value = webAppStr;
305
- }
306
312
});
307
- if (data.webApp != undefined && data.webApp != "" && data.webApps.includes(data.webApp)) {
308
- webApp.value = data.webApp;
309
- }
310
313
// Update width of dropdown
311
314
const longest = data.webApps.reduce((a,b) => a.length > b.length ? a : b);
312
315
const context = document.createElement("canvas").getContext("2d");
313
316
context.font = window.getComputedStyle(webApp,null).getPropertyValue("font");
314
- webApp.style.width = Math.ceil(context.measureText(longest).width) + "px";
315
- }
316
- });
317
- form.dispatchEvent(new Event("change"));
318
- }
319
- const getFormData = () => {
320
- const data = {};
321
- formFields.forEach((field) => {
322
- if (field.id != "serverInfo" && field.value != undefined) {
323
- data[field.id] = field.value;
317
+ webApp.style.width = Math.ceil(context.measureText(longest).width*(4/3)) + "px";
318
+ } else if (data[field.id] != undefined && currentVals.get(field.id) != data[field.id]) {
319
+ if (["method","bodyType"].includes(field.id)) {
320
+ // Check the correct radio
321
+ for (const c of field.children) {
322
+ c.checked = (c.value == data[field.id]);
323
+ }
324
+ if (field.id == "bodyType") {
325
+ // Make sure bodyContent is shown or hidden correctly
326
+ bodyContent.hidden = (data[field.id] == "No Body");
327
+ }
328
+ } else {
329
+ field.value = data[field.id];
330
+ if (field.id == "path") {
331
+ // Make sure valid path is marked as valid
332
+ }
333
+ }
324
334
}
325
335
});
326
- return data;
327
- }
328
-
329
- window.onmessage = (event) => setFormData(event.data);
330
- button.onclick = () => {
331
- vscode.postMessage({
332
- submitted: true,
333
- ...getFormData()
334
- });
335
- }
336
- form.onchange = (event) => {
337
- if (event.target.id != "panels") {
338
- const data = getFormData();
339
- if (
340
- Object.keys(data).length == formFields.length - 1 &&
341
- data.webApp != "" && data.method != "" && data.bodyType != ""
342
- ) {
343
- vscode.postMessage({
344
- submitted: false,
345
- ...data
346
- });
347
- }
348
- }
349
- }
336
+ };
337
+ form.onchange = () => sendData(false);
338
+ button.onclick = () => sendData(true);
350
339
bodyType.onchange = () => {
351
- if (bodyType.value == "No Body") {
352
- bodyContent.setAttribute("hidden","hidden");
353
- } else {
354
- bodyContent.removeAttribute("hidden");
340
+ let bt;
341
+ for (const c of bodyType.children) {
342
+ if (c.checked) {
343
+ bt = c.value;
344
+ break;
345
+ }
355
346
}
347
+ bodyContent.hidden = (bt == "No Body");
356
348
}
349
+ // Bubble change events up to the form
350
+ bodyContent.onchange = headersText.onchange =
351
+ paramsText.onchange = path.onchange =
352
+ webApp.onchange = () => form.dispatchEvent(new Event("change"));
357
353
</script>
358
354
</body>
359
355
</html>` ;
0 commit comments