Skip to content

Commit 951bae2

Browse files
wolfibDevtools-frontend LUCI CQ
authored andcommitted
Fix for JSONView not updating when selecting another report
After a previous CL (https://crrev.com/c/6859315), the content of the JSONView did not update when `input.focusedReport` changes. To fix this, the widget needs to have a setter method for updating the JSON. This CL creates a child class of `SearchableView` which has such a setter. Bug: 407750294 Change-Id: I6bc59379d883bbf2a4e6bc87c0a2b91845ce4e5d Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7000090 Auto-Submit: Wolfgang Beyer <[email protected]> Reviewed-by: Danil Somsikov <[email protected]> Commit-Queue: Danil Somsikov <[email protected]>
1 parent 143690d commit 951bae2

File tree

6 files changed

+91
-8
lines changed

6 files changed

+91
-8
lines changed

front_end/panels/application/ReportingApiView.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
import * as SDK from '../../core/sdk/sdk.js';
66
import * as Protocol from '../../generated/protocol.js';
7+
import {assertScreenshot, renderElementIntoDOM} from '../../testing/DOMHelpers.js';
78
import {createTarget} from '../../testing/EnvironmentHelpers.js';
89
import {describeWithMockConnection} from '../../testing/MockConnection.js';
910
import {createViewFunctionStub} from '../../testing/ViewFunctionHelpers.js';
11+
import * as UI from '../../ui/legacy/legacy.js';
1012

1113
import * as Application from './application.js';
1214

@@ -217,4 +219,56 @@ describeWithMockConnection('ReportingApiView', () => {
217219
await view.nextInput;
218220
assert.strictEqual(view.input.focusedReport, reports[0]);
219221
});
222+
223+
describe('view', () => {
224+
let target!: HTMLElement;
225+
let stub: sinon.SinonStub;
226+
227+
beforeEach(async () => {
228+
const original = Date.prototype.toLocaleString;
229+
stub = sinon.stub(Date.prototype, 'toLocaleString').callsFake(function(this: Date) {
230+
return original.call(this, 'en-US', {timeZone: 'UTC'});
231+
});
232+
233+
const container = document.createElement('div');
234+
renderElementIntoDOM(container);
235+
const widget = new UI.Widget.Widget();
236+
widget.markAsRoot();
237+
widget.show(container);
238+
target = widget.element;
239+
target.style.display = 'flex';
240+
target.style.width = '780px';
241+
target.style.height = '400px';
242+
});
243+
244+
afterEach(() => {
245+
stub.restore();
246+
});
247+
248+
it('updates report details', async () => {
249+
Application.ReportingApiView.DEFAULT_VIEW(
250+
{
251+
hasReports: true,
252+
hasEndpoints: false,
253+
endpoints: new Map(),
254+
reports,
255+
focusedReport: reports[0],
256+
onReportSelected: () => {},
257+
},
258+
undefined, target);
259+
await assertScreenshot('application/report_details.png');
260+
261+
Application.ReportingApiView.DEFAULT_VIEW(
262+
{
263+
hasReports: true,
264+
hasEndpoints: false,
265+
endpoints: new Map(),
266+
reports,
267+
focusedReport: reports[1],
268+
onReportSelected: () => {},
269+
},
270+
undefined, target);
271+
await assertScreenshot('application/report_details_updated.png');
272+
});
273+
});
220274
});

front_end/panels/application/ReportingApiView.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,11 @@ interface ViewInput {
5656
onReportSelected: (id: string) => void;
5757
}
5858

59-
type View = (input: ViewInput, output: object, target: HTMLElement) => void;
60-
61-
export const DEFAULT_VIEW: View = (input, _output, target) => {
59+
export const DEFAULT_VIEW = (input: ViewInput, output: undefined, target: HTMLElement): void => {
6260
if (input.hasReports || input.hasEndpoints) {
6361
// clang-format off
6462
render(html`
63+
<style>${UI.inspectorCommonStyles}</style>
6564
<devtools-split-view sidebar-position="second" sidebar-initial-size="150" jslog=${
6665
VisualLogging.pane('reporting-api')}>
6766
${input.hasReports ? html`
@@ -73,9 +72,9 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
7372
</div>
7473
<div slot="sidebar" class="vbox" jslog=${VisualLogging.pane('preview').track({resize: true})}>
7574
${input.focusedReport ? html`
76-
<devtools-widget .widgetConfig=${widgetConfig(
77-
element => SourceFrame.JSONView.JSONView.createViewSync(input.focusedReport?.body || '', element)
78-
)}></devtools-widget>
75+
<devtools-widget .widgetConfig=${widgetConfig(SourceFrame.JSONView.SearchableJsonView, {
76+
jsonObject: input.focusedReport.body,
77+
})}></devtools-widget>
7978
` : html`
8079
<devtools-widget .widgetConfig=${widgetConfig(UI.EmptyWidget.EmptyWidget, {
8180
header: i18nString(UIStrings.noReportSelected),
@@ -112,6 +111,8 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
112111
}
113112
};
114113

114+
type View = typeof DEFAULT_VIEW;
115+
115116
export class ReportingApiView extends UI.Widget.VBox implements
116117
SDK.TargetManager.SDKModelObserver<SDK.NetworkManager.NetworkManager> {
117118
#endpoints: Map<string, Protocol.Network.ReportingApiEndpoint[]>;
@@ -164,7 +165,7 @@ export class ReportingApiView extends UI.Widget.VBox implements
164165
focusedReport: this.#focusedReport,
165166
onReportSelected: this.#onReportSelected.bind(this),
166167
};
167-
this.#view(viewInput, {}, this.element);
168+
this.#view(viewInput, undefined, this.element);
168169
}
169170

170171
#onEndpointsChangedForOrigin({data}: {data: Protocol.Network.ReportingApiEndpointsChangedForOriginEvent}): void {

front_end/ui/legacy/SearchableView.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ function createClearButton(jslogContext: string): Buttons.Button.Button {
139139
return button;
140140
}
141141
export class SearchableView extends VBox {
142-
private searchProvider: Searchable;
142+
protected searchProvider: Searchable;
143143
private replaceProvider: Replaceable|null;
144144
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
145145
// eslint-disable-next-line @typescript-eslint/no-explicit-any

front_end/ui/legacy/components/source_frame/JSONView.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const UIStrings = {
2020
} as const;
2121
const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/source_frame/JSONView.ts', UIStrings);
2222
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
23+
2324
export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Searchable {
2425
private initialized: boolean;
2526
private readonly parsedJSON: ParsedJSON;
@@ -67,6 +68,10 @@ export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Search
6768
return searchableView;
6869
}
6970

71+
setSearchableView(searchableView: UI.SearchableView.SearchableView): void {
72+
this.searchableView = searchableView;
73+
}
74+
7075
private static parseJSON(text: string|null): Promise<ParsedJSON|null> {
7176
let returnObj: ParsedJSON<string>|null = null;
7277
if (text) {
@@ -280,3 +285,26 @@ export class ParsedJSON<T extends unknown = unknown> {
280285
this.suffix = suffix;
281286
}
282287
}
288+
289+
export class SearchableJsonView extends UI.SearchableView.SearchableView {
290+
#jsonView: JSONView;
291+
292+
constructor(element: HTMLElement) {
293+
const jsonView = new JSONView(new ParsedJSON('', '', ''));
294+
super(jsonView, null, undefined, element);
295+
this.#jsonView = jsonView;
296+
this.setPlaceholder(i18nString(UIStrings.find));
297+
jsonView.setSearchableView(this);
298+
jsonView.show(this.element);
299+
jsonView.element.tabIndex = 0;
300+
}
301+
302+
set jsonObject(obj: Object) {
303+
const jsonView = new JSONView(new ParsedJSON(obj, '', ''));
304+
this.#jsonView.detach();
305+
this.#jsonView = jsonView;
306+
this.searchProvider = jsonView;
307+
jsonView.show(this.element);
308+
this.requestUpdate();
309+
}
310+
}
42.1 KB
Loading
44.7 KB
Loading

0 commit comments

Comments
 (0)