chrome-devtools-frontend 1.0.1578486 → 1.0.1578729
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/front_end/core/common/Revealer.ts +0 -5
- package/front_end/core/sdk/ConsoleModel.ts +0 -3
- package/front_end/models/ai_assistance/AiConversation.ts +42 -22
- package/front_end/models/issues_manager/CookieIssue.ts +0 -1
- package/front_end/models/issues_manager/IssuesManager.ts +2 -15
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +17 -25
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +0 -1
- package/front_end/panels/application/preloading/components/RuleSetDetailsView.css +0 -5
- package/front_end/panels/console/ConsoleViewMessage.ts +0 -32
- package/front_end/panels/console/consoleView.css +0 -5
- package/front_end/panels/media/PlayerListView.ts +13 -1
- package/front_end/panels/media/playerListView.css +5 -0
- package/front_end/panels/network/NetworkItemView.ts +2 -1
- package/front_end/panels/network/NetworkLogViewColumns.ts +17 -6
- package/front_end/panels/network/RequestInitiatorView.ts +20 -4
- package/front_end/panels/network/RequestPayloadView.ts +253 -280
- package/front_end/panels/network/ShowMoreDetailsWidget.ts +3 -3
- package/front_end/panels/network/requestPayloadTree.css +6 -3
- package/front_end/panels/network/requestPayloadView.css +1 -0
- package/front_end/panels/security/SecurityPanel.ts +0 -16
- package/front_end/panels/security/security-meta.ts +1 -15
- package/front_end/panels/sources/CallStackSidebarPane.ts +1 -1
- package/front_end/ui/components/buttons/Button.ts +1 -1
- package/front_end/ui/legacy/InspectorView.ts +6 -5
- package/front_end/ui/legacy/Treeoutline.ts +81 -22
- package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +2 -1
- package/front_end/ui/legacy/softDropDown.css +7 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/mcp/mcp.ts +2 -0
- package/package.json +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright 2021 The Chromium Authors
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
|
-
/* eslint-disable @devtools/no-imperative-dom-api,@devtools/no-lit-render-outside-of-view */
|
|
5
4
|
|
|
6
5
|
/*
|
|
7
6
|
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
|
|
@@ -44,7 +43,7 @@ import objectPropertiesSectionStyles from '../../ui/legacy/components/object_ui/
|
|
|
44
43
|
// eslint-disable-next-line @devtools/es-modules-import
|
|
45
44
|
import objectValueStyles from '../../ui/legacy/components/object_ui/objectValue.css.js';
|
|
46
45
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
47
|
-
import {Directives, html, type LitTemplate, render} from '../../ui/lit/lit.js';
|
|
46
|
+
import {Directives, html, type LitTemplate, render, type TemplateResult} from '../../ui/lit/lit.js';
|
|
48
47
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
49
48
|
|
|
50
49
|
import requestPayloadTreeStyles from './requestPayloadTree.css.js';
|
|
@@ -104,49 +103,238 @@ const UIStrings = {
|
|
|
104
103
|
} as const;
|
|
105
104
|
const str_ = i18n.i18n.registerUIStrings('panels/network/RequestPayloadView.ts', UIStrings);
|
|
106
105
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
107
|
-
export class RequestPayloadView extends UI.Widget.VBox {
|
|
108
|
-
private request: SDK.NetworkRequest.NetworkRequest;
|
|
109
|
-
private decodeRequestParameters: boolean;
|
|
110
|
-
private queryStringCategory: Category;
|
|
111
|
-
private formDataCategory: Category;
|
|
112
|
-
private requestPayloadCategory: Category;
|
|
113
106
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
107
|
+
interface ViewInput {
|
|
108
|
+
decodeRequestParameters: boolean;
|
|
109
|
+
setURLDecoding(value: boolean): void;
|
|
110
|
+
viewQueryParamSource: boolean;
|
|
111
|
+
setViewQueryParamSource(value: boolean): void;
|
|
112
|
+
viewFormParamSource: boolean;
|
|
113
|
+
setViewFormParamSource(value: boolean): void;
|
|
114
|
+
viewJSONPayloadSource: boolean;
|
|
115
|
+
setViewJSONPayloadSource(value: boolean): void;
|
|
116
|
+
copyValue(value: string): void;
|
|
117
|
+
|
|
118
|
+
formData: string|undefined;
|
|
119
|
+
formParameters: SDK.NetworkRequest.NameValue[]|undefined;
|
|
120
|
+
queryString: string|null;
|
|
121
|
+
queryParameters: SDK.NetworkRequest.NameValue[]|null;
|
|
122
|
+
}
|
|
118
123
|
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
125
|
+
export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
126
|
+
const createViewSourceToggle = (viewSource: boolean, callback: (value: boolean) => void): LitTemplate =>
|
|
127
|
+
html`<devtools-button
|
|
128
|
+
class="payload-toggle"
|
|
129
|
+
jslog=${VisualLogging.action().track({click: true}).context('source-parse')}
|
|
130
|
+
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
131
|
+
@click=${(e: Event) => {
|
|
132
|
+
e.consume();
|
|
133
|
+
callback(!viewSource);
|
|
134
|
+
}}>
|
|
135
|
+
${viewSource ? i18nString(UIStrings.viewParsed) : i18nString(UIStrings.viewSource)}
|
|
136
|
+
</devtools-button>`;
|
|
137
|
+
|
|
138
|
+
const copyValueContextmenu = (title: string, value: () => string, jslogContext: string) => (e: Event) => {
|
|
139
|
+
e.consume(true);
|
|
140
|
+
const contextMenu = new UI.ContextMenu.ContextMenu(e);
|
|
141
|
+
const copyValueHandler = (): void => input.copyValue(value());
|
|
142
|
+
contextMenu.clipboardSection().appendItem(title, copyValueHandler, {jslogContext});
|
|
143
|
+
void contextMenu.show();
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const createSourceText = (text: string): TemplateResult => html`<li role=treeitem
|
|
147
|
+
@contextmenu=${copyValueContextmenu(i18nString(UIStrings.copyPayload), () => text, 'copy-payload')}>
|
|
148
|
+
<devtools-widget class='payload-value source-code' .widgetConfig=${widgetConfig(ShowMoreDetailsWidget, {text})}>
|
|
149
|
+
</devtools-widget>
|
|
150
|
+
</li>`;
|
|
151
|
+
|
|
152
|
+
const createParsedParams = (params: SDK.NetworkRequest.NameValue[]): TemplateResult[] => params.map(
|
|
153
|
+
param => html`<li role=treeitem @contextmenu=${
|
|
154
|
+
copyValueContextmenu(i18nString(UIStrings.copyValue), () => decodeURIComponent(param.value), 'copy-value')}>${
|
|
155
|
+
param.name !== '' ?
|
|
156
|
+
html`${RequestPayloadView.formatParameter(param.name, 'payload-name', input.decodeRequestParameters)}${
|
|
157
|
+
RequestPayloadView.formatParameter(
|
|
158
|
+
param.value, 'payload-value source-code', input.decodeRequestParameters)}` :
|
|
159
|
+
RequestPayloadView.formatParameter(
|
|
160
|
+
i18nString(UIStrings.empty), 'empty-request-payload', input.decodeRequestParameters)}</li>`);
|
|
161
|
+
|
|
162
|
+
const parsedFormData = (() => {
|
|
163
|
+
if (input.formData && !input.formParameters) {
|
|
164
|
+
try {
|
|
165
|
+
return JSON.parse(input.formData);
|
|
166
|
+
} catch {
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
})();
|
|
171
|
+
|
|
172
|
+
const createPayload = (parsedFormData: unknown): TemplateResult => {
|
|
173
|
+
const object = new SDK.RemoteObject.LocalJSONObject(parsedFormData);
|
|
174
|
+
const section =
|
|
175
|
+
new ObjectUI.ObjectPropertiesSection.RootElement(new ObjectUI.ObjectPropertiesSection.ObjectTree(object));
|
|
176
|
+
section.title = document.createTextNode(object.description);
|
|
177
|
+
section.listItemElement.classList.add('source-code', 'object-properties-section');
|
|
178
|
+
section.childrenListElement.classList.add('source-code', 'object-properties-section');
|
|
179
|
+
section.expand();
|
|
180
|
+
return html`<devtools-tree-wrapper
|
|
181
|
+
.treeElement=${section}></devtools-tree-wrapper>`;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const queryStringExpandedSetting =
|
|
185
|
+
Common.Settings.Settings.instance().createSetting('request-info-query-string-category-expanded', true);
|
|
186
|
+
const formDataExpandedSetting =
|
|
187
|
+
Common.Settings.Settings.instance().createSetting('request-info-form-data-category-expanded', true);
|
|
188
|
+
const requestPayloadExpandedSetting =
|
|
189
|
+
Common.Settings.Settings.instance().createSetting('request-info-request-payload-category-expanded', true);
|
|
190
|
+
|
|
191
|
+
const toggleURLDecoding = (e: Event): void => {
|
|
192
|
+
e.consume();
|
|
193
|
+
input.setURLDecoding(!input.decodeRequestParameters);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const onContextMenu = (viewSource: boolean, callback: (value: boolean) => void, includeURLDecodingOption = true) => (
|
|
197
|
+
event: Event): void => {
|
|
198
|
+
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
199
|
+
const section = contextMenu.newSection();
|
|
200
|
+
if (viewSource) {
|
|
201
|
+
section.appendItem(i18nString(UIStrings.viewParsed), () => callback(!viewSource), {jslogContext: 'view-parsed'});
|
|
202
|
+
} else {
|
|
203
|
+
section.appendItem(i18nString(UIStrings.viewSource), () => callback(!viewSource), {jslogContext: 'view-source'});
|
|
204
|
+
if (includeURLDecodingOption) {
|
|
205
|
+
const viewURLEncodedText =
|
|
206
|
+
input.decodeRequestParameters ? i18nString(UIStrings.viewUrlEncoded) : i18nString(UIStrings.viewDecoded);
|
|
207
|
+
section.appendItem(
|
|
208
|
+
viewURLEncodedText, toggleURLDecoding.bind(this, event), {jslogContext: 'toggle-url-decoding'});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
void contextMenu.show();
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// clang-format off
|
|
215
|
+
render(html`<style>${requestPayloadViewStyles}</style>
|
|
216
|
+
<devtools-tree dense class=request-payload-tree .template=${html`
|
|
217
|
+
<style>${objectValueStyles}</style>
|
|
218
|
+
<style>${objectPropertiesSectionStyles}</style>
|
|
219
|
+
<style>${requestPayloadTreeStyles}</style>
|
|
220
|
+
<ul role=tree>
|
|
221
|
+
<li
|
|
222
|
+
role=treeitem
|
|
223
|
+
?hidden=${!input.queryParameters}
|
|
224
|
+
jslog=${VisualLogging.section().context('query-string')}
|
|
225
|
+
@contextmenu=${onContextMenu(input.viewQueryParamSource, input.setViewQueryParamSource)}
|
|
226
|
+
@expanded=${(e: UI.TreeOutline.TreeViewElement.ExpandEvent) =>
|
|
227
|
+
queryStringExpandedSetting.set(e.detail.expanded)}
|
|
228
|
+
>
|
|
229
|
+
<div class="selection fill"></div>${i18nString(UIStrings.queryStringParameters)}<span
|
|
230
|
+
class=payload-count>${`\xA0(${input.queryParameters?.length ?? 0})`}</span>${
|
|
231
|
+
createViewSourceToggle(input.viewQueryParamSource, input.setViewQueryParamSource)}
|
|
232
|
+
<devtools-button
|
|
233
|
+
class=payload-toggle
|
|
234
|
+
?hidden=${input.viewQueryParamSource}
|
|
235
|
+
jslog=${VisualLogging.action().track({click: true}).context('decode-encode')}
|
|
236
|
+
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
237
|
+
@click=${toggleURLDecoding}>
|
|
238
|
+
${input.decodeRequestParameters ? i18nString(UIStrings.viewUrlEncoded) : i18nString(UIStrings.viewDecoded)}
|
|
239
|
+
</devtools-button>
|
|
240
|
+
<ul role=group ?hidden=${!queryStringExpandedSetting.get()}>
|
|
241
|
+
${input.viewQueryParamSource ? createSourceText(input.queryString ?? '')
|
|
242
|
+
: createParsedParams(input.queryParameters ?? [])}
|
|
243
|
+
</ul>
|
|
244
|
+
</li>
|
|
245
|
+
<li
|
|
246
|
+
role=treeitem
|
|
247
|
+
?hidden=${!input.formData || !input.formParameters}
|
|
248
|
+
jslog=${VisualLogging.section().context('form-data')}
|
|
249
|
+
@contextmenu=${onContextMenu(input.viewFormParamSource, input.setViewFormParamSource)}
|
|
250
|
+
@expanded=${(e: UI.TreeOutline.TreeViewElement.ExpandEvent) => formDataExpandedSetting.set(e.detail.expanded)}
|
|
251
|
+
>
|
|
252
|
+
<div class="selection fill"></div>${i18nString(UIStrings.formData)}<span
|
|
253
|
+
class=payload-count>${`\xA0(${input.formParameters?.length ?? 0})`}</span>${
|
|
254
|
+
createViewSourceToggle(input.viewFormParamSource, input.setViewFormParamSource)}
|
|
255
|
+
<devtools-button
|
|
256
|
+
class=payload-toggle
|
|
257
|
+
?hidden=${input.viewFormParamSource}
|
|
258
|
+
jslog=${VisualLogging.action().track({click: true}).context('decode-encode')}
|
|
259
|
+
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
260
|
+
@click=${toggleURLDecoding}>
|
|
261
|
+
${input.decodeRequestParameters ? i18nString(UIStrings.viewUrlEncoded) : i18nString(UIStrings.viewDecoded)}
|
|
262
|
+
</devtools-button>
|
|
263
|
+
<ul role=group ?hidden=${!formDataExpandedSetting.get()}>>
|
|
264
|
+
${input.viewFormParamSource ? createSourceText(input.formData ?? '')
|
|
265
|
+
: createParsedParams(input.formParameters ?? [])}
|
|
266
|
+
</ul>
|
|
267
|
+
</li>
|
|
268
|
+
<li
|
|
269
|
+
role=treeitem
|
|
270
|
+
?hidden=${!input.formData || Boolean(input.formParameters)}
|
|
271
|
+
jslog=${VisualLogging.section().context('request-payload')}
|
|
272
|
+
@contextmenu=${onContextMenu(input.viewJSONPayloadSource, input.setViewJSONPayloadSource,
|
|
273
|
+
/* includeURLDecodingOption*/ false)}
|
|
274
|
+
@expanded=${(e: UI.TreeOutline.TreeViewElement.ExpandEvent) =>
|
|
275
|
+
requestPayloadExpandedSetting.set(e.detail.expanded)}
|
|
276
|
+
>
|
|
277
|
+
<div class="selection fill"></div>${i18nString(UIStrings.requestPayload)}${
|
|
278
|
+
createViewSourceToggle(input.viewJSONPayloadSource, input.setViewJSONPayloadSource)}
|
|
279
|
+
<ul role=group ?hidden=${!requestPayloadExpandedSetting.get()}>
|
|
280
|
+
${!parsedFormData || input.viewJSONPayloadSource ? createSourceText(input.formData ?? '')
|
|
281
|
+
: createPayload(parsedFormData)}
|
|
282
|
+
</ul>
|
|
283
|
+
</li>
|
|
284
|
+
</ul>
|
|
285
|
+
`}></devtools-tree>
|
|
286
|
+
`, target);
|
|
287
|
+
// clang-format on
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
export class RequestPayloadView extends UI.Widget.VBox {
|
|
291
|
+
#request?: SDK.NetworkRequest.NetworkRequest;
|
|
292
|
+
#decodeRequestParameters = true;
|
|
293
|
+
#formData?: string;
|
|
294
|
+
#formParameters?: SDK.NetworkRequest.NameValue[];
|
|
295
|
+
#view: View;
|
|
296
|
+
#viewJSONPayloadSource = false;
|
|
297
|
+
#viewFormParamSource = false;
|
|
298
|
+
#viewQueryParamSource = false;
|
|
299
|
+
|
|
300
|
+
constructor(target?: HTMLElement, view = DEFAULT_VIEW) {
|
|
301
|
+
super({jslog: `${VisualLogging.pane('payload').track({resize: true})}`, classes: ['request-payload-view']});
|
|
302
|
+
this.#view = view;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
set request(request: SDK.NetworkRequest.NetworkRequest) {
|
|
306
|
+
if (this.#request) {
|
|
307
|
+
this.#request.removeEventListener(SDK.NetworkRequest.Events.REQUEST_HEADERS_CHANGED, this.#refreshFormData, this);
|
|
308
|
+
}
|
|
309
|
+
this.#request = request;
|
|
121
310
|
|
|
122
311
|
const contentType = request.requestContentType();
|
|
123
312
|
if (contentType) {
|
|
124
|
-
this
|
|
313
|
+
this.#decodeRequestParameters = Boolean(contentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (this.isShowing()) {
|
|
317
|
+
this.#request?.addEventListener(SDK.NetworkRequest.Events.REQUEST_HEADERS_CHANGED, this.#refreshFormData, this);
|
|
125
318
|
}
|
|
126
319
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
root.setDense(true);
|
|
131
|
-
this.element.appendChild(root.element);
|
|
320
|
+
this.requestUpdate();
|
|
321
|
+
void this.#refreshFormData();
|
|
322
|
+
}
|
|
132
323
|
|
|
133
|
-
|
|
134
|
-
this
|
|
135
|
-
this.requestPayloadCategory = new Category(root, 'request-payload');
|
|
324
|
+
get request(): SDK.NetworkRequest.NetworkRequest|undefined {
|
|
325
|
+
return this.#request;
|
|
136
326
|
}
|
|
137
327
|
|
|
138
328
|
override wasShown(): void {
|
|
139
329
|
super.wasShown();
|
|
140
|
-
this.request
|
|
330
|
+
this.request?.addEventListener(SDK.NetworkRequest.Events.REQUEST_HEADERS_CHANGED, this.#refreshFormData, this);
|
|
141
331
|
|
|
142
|
-
this
|
|
143
|
-
void this.refreshFormData();
|
|
144
|
-
// this._root.select(/* omitFocus */ true, /* selectedByUser */ false);
|
|
332
|
+
void this.#refreshFormData();
|
|
145
333
|
}
|
|
146
334
|
|
|
147
335
|
override willHide(): void {
|
|
148
336
|
super.willHide();
|
|
149
|
-
this.request
|
|
337
|
+
this.request?.removeEventListener(SDK.NetworkRequest.Events.REQUEST_HEADERS_CHANGED, this.#refreshFormData, this);
|
|
150
338
|
}
|
|
151
339
|
|
|
152
340
|
private addEntryContextMenuHandler(
|
|
@@ -163,124 +351,50 @@ export class RequestPayloadView extends UI.Widget.VBox {
|
|
|
163
351
|
});
|
|
164
352
|
}
|
|
165
353
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const queryParameters = this.request.queryParameters;
|
|
169
|
-
this.queryStringCategory.hidden = !queryParameters;
|
|
170
|
-
if (queryParameters) {
|
|
171
|
-
this.refreshParams(
|
|
172
|
-
i18nString(UIStrings.queryStringParameters), queryParameters, queryString, this.queryStringCategory);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
private async refreshFormData(): Promise<void> {
|
|
177
|
-
const formData = await this.request.requestFormData();
|
|
178
|
-
if (!formData) {
|
|
179
|
-
this.formDataCategory.hidden = true;
|
|
180
|
-
this.requestPayloadCategory.hidden = true;
|
|
354
|
+
override performUpdate(): void {
|
|
355
|
+
if (!this.request) {
|
|
181
356
|
return;
|
|
182
357
|
}
|
|
183
358
|
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
this.
|
|
187
|
-
this
|
|
188
|
-
this
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
this
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
private refreshParams(
|
|
214
|
-
title: string, params: SDK.NetworkRequest.NameValue[]|null, sourceText: string|null,
|
|
215
|
-
paramsTreeElement: UI.TreeOutline.TreeElement): void {
|
|
216
|
-
const viewParsed = function(this: RequestPayloadView, event: Event): void {
|
|
217
|
-
paramsTreeElement.listItemElement.removeEventListener('contextmenu', viewParsedContextMenu);
|
|
218
|
-
|
|
219
|
-
viewSourceForItems.delete(paramsTreeElement);
|
|
220
|
-
this.refreshParams(title, params, sourceText, paramsTreeElement);
|
|
221
|
-
event.consume();
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const viewParsedContextMenu = (event: Event): void => {
|
|
225
|
-
if (!paramsTreeElement.expanded) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
229
|
-
contextMenu.newSection().appendItem(
|
|
230
|
-
i18nString(UIStrings.viewParsed), viewParsed.bind(this, event), {jslogContext: 'view-parsed'});
|
|
231
|
-
void contextMenu.show();
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const viewSource = function(this: RequestPayloadView, event: Event): void {
|
|
235
|
-
paramsTreeElement.listItemElement.removeEventListener('contextmenu', viewSourceContextMenu);
|
|
236
|
-
|
|
237
|
-
viewSourceForItems.add(paramsTreeElement);
|
|
238
|
-
this.refreshParams(title, params, sourceText, paramsTreeElement);
|
|
239
|
-
event.consume();
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
const toggleURLDecoding = function(this: RequestPayloadView, event: Event): void {
|
|
243
|
-
paramsTreeElement.listItemElement.removeEventListener('contextmenu', viewSourceContextMenu);
|
|
244
|
-
this.toggleURLDecoding(event);
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
const viewSourceContextMenu = (event: Event): void => {
|
|
248
|
-
if (!paramsTreeElement.expanded) {
|
|
249
|
-
return;
|
|
359
|
+
const input: ViewInput = {
|
|
360
|
+
queryString: this.request.queryString(),
|
|
361
|
+
queryParameters: this.request.queryParameters,
|
|
362
|
+
formData: this.#formData,
|
|
363
|
+
formParameters: this.#formParameters,
|
|
364
|
+
decodeRequestParameters: this.#decodeRequestParameters,
|
|
365
|
+
setURLDecoding: (value: boolean): void => {
|
|
366
|
+
this.#decodeRequestParameters = value;
|
|
367
|
+
this.requestUpdate();
|
|
368
|
+
},
|
|
369
|
+
viewQueryParamSource: this.#viewQueryParamSource,
|
|
370
|
+
setViewQueryParamSource: (value: boolean): void => {
|
|
371
|
+
this.#viewQueryParamSource = value;
|
|
372
|
+
this.requestUpdate();
|
|
373
|
+
},
|
|
374
|
+
viewFormParamSource: this.#viewFormParamSource,
|
|
375
|
+
setViewFormParamSource: (value: boolean): void => {
|
|
376
|
+
this.#viewFormParamSource = value;
|
|
377
|
+
this.requestUpdate();
|
|
378
|
+
},
|
|
379
|
+
viewJSONPayloadSource: this.#viewJSONPayloadSource,
|
|
380
|
+
setViewJSONPayloadSource: (value: boolean): void => {
|
|
381
|
+
this.#viewJSONPayloadSource = value;
|
|
382
|
+
this.requestUpdate();
|
|
383
|
+
},
|
|
384
|
+
copyValue: (value: string): void => {
|
|
385
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue);
|
|
386
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(value);
|
|
250
387
|
}
|
|
251
|
-
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
252
|
-
const section = contextMenu.newSection();
|
|
253
|
-
section.appendItem(i18nString(UIStrings.viewSource), viewSource.bind(this, event), {jslogContext: 'view-source'});
|
|
254
|
-
const viewURLEncodedText =
|
|
255
|
-
this.decodeRequestParameters ? i18nString(UIStrings.viewUrlEncoded) : i18nString(UIStrings.viewDecoded);
|
|
256
|
-
section.appendItem(
|
|
257
|
-
viewURLEncodedText, toggleURLDecoding.bind(this, event), {jslogContext: 'toggle-url-decoding'});
|
|
258
|
-
void contextMenu.show();
|
|
259
388
|
};
|
|
389
|
+
this.#view(input, {}, this.element);
|
|
390
|
+
}
|
|
260
391
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
shouldViewSource ? this.createViewSourceToggle(/* viewSource */ true, viewParsed.bind(this)) :
|
|
266
|
-
html`${this.createViewSourceToggle(/* viewSource */ false, viewSource.bind(this))}
|
|
267
|
-
<devtools-button
|
|
268
|
-
class=payload-toggle
|
|
269
|
-
jslogi=${VisualLogging.action().track({click: true}).context('decode-encode')}
|
|
270
|
-
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
271
|
-
@click=${toggleURLDecoding.bind(this)}>
|
|
272
|
-
${this.decodeRequestParameters ? i18nString(UIStrings.viewUrlEncoded) : i18nString(UIStrings.viewDecoded)}
|
|
273
|
-
</devtools-button>`}`,
|
|
274
|
-
paramsTreeElement.listItemElement);
|
|
275
|
-
|
|
276
|
-
paramsTreeElement.removeChildren();
|
|
277
|
-
if (shouldViewSource) {
|
|
278
|
-
this.populateTreeElementWithSourceText(paramsTreeElement, (sourceText ?? '').trim());
|
|
279
|
-
paramsTreeElement.listItemElement.addEventListener('contextmenu', viewParsedContextMenu);
|
|
280
|
-
} else {
|
|
281
|
-
this.populateTreeElementWithParsedParameters(paramsTreeElement, params);
|
|
282
|
-
paramsTreeElement.listItemElement.addEventListener('contextmenu', viewSourceContextMenu);
|
|
392
|
+
async #refreshFormData(): Promise<void> {
|
|
393
|
+
this.#formData = await this.request?.requestFormData() ?? undefined;
|
|
394
|
+
if (this.#formData) {
|
|
395
|
+
this.#formParameters = await this.request?.formParameters() ?? undefined;
|
|
283
396
|
}
|
|
397
|
+
this.requestUpdate();
|
|
284
398
|
}
|
|
285
399
|
|
|
286
400
|
static formatParameter(value: string, className: string, decodeParameters: boolean): LitTemplate {
|
|
@@ -303,145 +417,4 @@ export class RequestPayloadView extends UI.Widget.VBox {
|
|
|
303
417
|
value}
|
|
304
418
|
</div>`;
|
|
305
419
|
}
|
|
306
|
-
|
|
307
|
-
private populateTreeElementWithParsedParameters(
|
|
308
|
-
paramsTreeElement: UI.TreeOutline.TreeElement, params: SDK.NetworkRequest.NameValue[]|null): void {
|
|
309
|
-
for (const param of params || []) {
|
|
310
|
-
const paramNameValue = document.createDocumentFragment();
|
|
311
|
-
if (param.name !== '') {
|
|
312
|
-
render(
|
|
313
|
-
html`${RequestPayloadView.formatParameter(param.name, 'payload-name', this.decodeRequestParameters)}${
|
|
314
|
-
RequestPayloadView.formatParameter(
|
|
315
|
-
param.value, 'payload-value source-code', this.decodeRequestParameters)}`,
|
|
316
|
-
paramNameValue);
|
|
317
|
-
} else {
|
|
318
|
-
render(
|
|
319
|
-
RequestPayloadView.formatParameter(
|
|
320
|
-
i18nString(UIStrings.empty), 'empty-request-payload', this.decodeRequestParameters),
|
|
321
|
-
paramNameValue);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const paramTreeElement = new UI.TreeOutline.TreeElement(paramNameValue);
|
|
325
|
-
this.addEntryContextMenuHandler(
|
|
326
|
-
paramTreeElement, i18nString(UIStrings.copyValue), 'copy-value', () => decodeURIComponent(param.value));
|
|
327
|
-
paramsTreeElement.appendChild(paramTreeElement);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
|
332
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
333
|
-
private refreshRequestJSONPayload(parsedObject: any, sourceText: string): void {
|
|
334
|
-
const rootListItem = this.requestPayloadCategory;
|
|
335
|
-
|
|
336
|
-
const viewParsed = function(this: RequestPayloadView, event: Event): void {
|
|
337
|
-
rootListItemElement.removeEventListener('contextmenu', viewParsedContextMenu);
|
|
338
|
-
viewSourceForItems.delete(rootListItem);
|
|
339
|
-
this.refreshRequestJSONPayload(parsedObject, sourceText);
|
|
340
|
-
event.consume();
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
const viewParsedContextMenu = (event: Event): void => {
|
|
344
|
-
if (!rootListItem.expanded) {
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
348
|
-
contextMenu.newSection().appendItem(
|
|
349
|
-
i18nString(UIStrings.viewParsed), viewParsed.bind(this, event), {jslogContext: 'view-parsed'});
|
|
350
|
-
void contextMenu.show();
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const viewSource = function(this: RequestPayloadView, event: Event): void {
|
|
354
|
-
rootListItemElement.removeEventListener('contextmenu', viewSourceContextMenu);
|
|
355
|
-
|
|
356
|
-
viewSourceForItems.add(rootListItem);
|
|
357
|
-
this.refreshRequestJSONPayload(parsedObject, sourceText);
|
|
358
|
-
event.consume();
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
const viewSourceContextMenu = (event: Event): void => {
|
|
362
|
-
if (!rootListItem.expanded) {
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
366
|
-
contextMenu.newSection().appendItem(
|
|
367
|
-
i18nString(UIStrings.viewSource), viewSource.bind(this, event), {jslogContext: 'view-source'});
|
|
368
|
-
void contextMenu.show();
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
const showSource = viewSourceForItems.has(rootListItem);
|
|
372
|
-
const rootListItemElement = rootListItem.listItemElement;
|
|
373
|
-
render(
|
|
374
|
-
html`<div class="selection fill"></div>${i18nString(UIStrings.requestPayload)}${
|
|
375
|
-
this.createViewSourceToggle(showSource, showSource ? viewParsed.bind(this) : viewSource.bind(this))}`,
|
|
376
|
-
rootListItemElement);
|
|
377
|
-
|
|
378
|
-
rootListItem.removeChildren();
|
|
379
|
-
if (showSource) {
|
|
380
|
-
this.populateTreeElementWithSourceText(rootListItem, sourceText);
|
|
381
|
-
rootListItemElement.addEventListener('contextmenu', viewParsedContextMenu);
|
|
382
|
-
} else {
|
|
383
|
-
rootListItem.childrenListElement.classList.add('source-code', 'object-properties-section');
|
|
384
|
-
this.populateTreeElementWithObject(rootListItem, parsedObject);
|
|
385
|
-
rootListItemElement.addEventListener('contextmenu', viewSourceContextMenu);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
private populateTreeElementWithObject(rootListItem: Category, parsedObject: object): void {
|
|
390
|
-
const object = new SDK.RemoteObject.LocalJSONObject(parsedObject);
|
|
391
|
-
const section =
|
|
392
|
-
new ObjectUI.ObjectPropertiesSection.RootElement(new ObjectUI.ObjectPropertiesSection.ObjectTree(object));
|
|
393
|
-
section.title = (object.description);
|
|
394
|
-
section.expand();
|
|
395
|
-
rootListItem.appendChild(section);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
private createViewSourceToggle(viewSource: boolean, handler: (arg0: Event) => void): LitTemplate {
|
|
399
|
-
return html`<devtools-button
|
|
400
|
-
class=payload-toggle
|
|
401
|
-
jslogi=${VisualLogging.action().track({click: true}).context('source-parse')}
|
|
402
|
-
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
403
|
-
@click=${handler}>
|
|
404
|
-
${viewSource ? i18nString(UIStrings.viewParsed) : i18nString(UIStrings.viewSource)}
|
|
405
|
-
</devtools-button>`;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
private toggleURLDecoding(event: Event): void {
|
|
409
|
-
this.decodeRequestParameters = !this.decodeRequestParameters;
|
|
410
|
-
this.refreshQueryString();
|
|
411
|
-
void this.refreshFormData();
|
|
412
|
-
event.consume();
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const viewSourceForItems = new WeakSet<Category|UI.TreeOutline.TreeElement>();
|
|
417
|
-
|
|
418
|
-
export class Category extends UI.TreeOutline.TreeElement {
|
|
419
|
-
override toggleOnClick: boolean;
|
|
420
|
-
private readonly expandedSetting: Common.Settings.Setting<boolean>;
|
|
421
|
-
override expanded: boolean;
|
|
422
|
-
|
|
423
|
-
constructor(root: UI.TreeOutline.TreeOutline, name: string, title?: string) {
|
|
424
|
-
super(title || '', true);
|
|
425
|
-
this.toggleOnClick = true;
|
|
426
|
-
this.hidden = true;
|
|
427
|
-
this.expandedSetting =
|
|
428
|
-
Common.Settings.Settings.instance().createSetting('request-info-' + name + '-category-expanded', true);
|
|
429
|
-
this.expanded = this.expandedSetting.get();
|
|
430
|
-
this.listItemElement.setAttribute('jslog', `${VisualLogging.section().context(name)}`);
|
|
431
|
-
root.appendChild(this);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
createLeaf(): UI.TreeOutline.TreeElement {
|
|
435
|
-
const leaf = new UI.TreeOutline.TreeElement();
|
|
436
|
-
this.appendChild(leaf);
|
|
437
|
-
return leaf;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
override onexpand(): void {
|
|
441
|
-
this.expandedSetting.set(true);
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
override oncollapse(): void {
|
|
445
|
-
this.expandedSetting.set(false);
|
|
446
|
-
}
|
|
447
420
|
}
|
|
@@ -41,14 +41,14 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
41
41
|
@contextmenu=${onContextMenuShowMore}
|
|
42
42
|
>${input.showMore ? input.text : input.text.substr(0, MAX_LENGTH)}</span>
|
|
43
43
|
${
|
|
44
|
-
|
|
44
|
+
!input.showMore && input.text.length > MAX_LENGTH ? html`<devtools-button
|
|
45
45
|
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
46
46
|
.jslogContext=${'show-more'}
|
|
47
47
|
@click=${input.onToggle}>
|
|
48
48
|
${i18nString(UIStrings.showMore)}
|
|
49
49
|
</devtools-button>` :
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
Lit.nothing}`,
|
|
51
|
+
target);
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
interface CopyMenuItem {
|
|
@@ -34,9 +34,12 @@
|
|
|
34
34
|
|
|
35
35
|
&:has(.payload-name) {
|
|
36
36
|
margin: var(--sys-size-3) 0;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
|
|
38
|
+
.tree-element-title {
|
|
39
|
+
display: grid;
|
|
40
|
+
grid-template-columns: min-content 1fr;
|
|
41
|
+
gap: var(--sys-size-6);
|
|
42
|
+
}
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -1617,19 +1617,3 @@ export interface OriginState {
|
|
|
1617
1617
|
}
|
|
1618
1618
|
|
|
1619
1619
|
export type Origin = Platform.DevToolsPath.UrlString;
|
|
1620
|
-
|
|
1621
|
-
export class SecurityRevealer implements Common.Revealer.Revealer<CookieReportView> {
|
|
1622
|
-
async reveal(): Promise<void> {
|
|
1623
|
-
await UI.ViewManager.ViewManager.instance().showView('security');
|
|
1624
|
-
const view = UI.ViewManager.ViewManager.instance().view('security');
|
|
1625
|
-
if (view) {
|
|
1626
|
-
const securityPanel = await view.widget();
|
|
1627
|
-
if (securityPanel instanceof SecurityPanel && securityPanel.sidebar.cookieReportTreeElement) {
|
|
1628
|
-
securityPanel.sidebar.cookieReportTreeElement.select(/* omitFocus=*/ false, /* selectedByUser=*/ true);
|
|
1629
|
-
} else {
|
|
1630
|
-
throw new Error(
|
|
1631
|
-
'Expected securityPanel to be an instance of SecurityPanel with a cookieReportTreeElement in the sidebar');
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
}
|