Skip to content

Commit 380221d

Browse files
szuendDevtools-frontend LUCI CQ
authored andcommitted
[ui] Pass 'Universe' to 'loadView' functions of view registrations
[email protected] Bug: 451502260 Change-Id: I1f867ba59689d0a7830d9bdcfb76f36eb626da60 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7207149 Auto-Submit: Simon Zünd <[email protected]> Commit-Queue: Danil Somsikov <[email protected]> Reviewed-by: Danil Somsikov <[email protected]>
1 parent 2d2c0e5 commit 380221d

File tree

6 files changed

+36
-13
lines changed

6 files changed

+36
-13
lines changed

front_end/entrypoints/main/MainImpl.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ let loadedPanelCommonModule: typeof PanelCommon|undefined;
132132
export class MainImpl {
133133
#readyForTestPromise = Promise.withResolvers<void>();
134134
#veStartPromise!: Promise<void>;
135+
#universe!: Foundation.Universe.Universe;
135136

136137
constructor() {
137138
MainImpl.instanceForTest = this;
@@ -175,8 +176,8 @@ export class MainImpl {
175176
runSettingsMigration: !Host.InspectorFrontendHost.isUnderTest(),
176177
},
177178
};
178-
const universe = new Foundation.Universe.Universe(creationOptions);
179-
Root.DevToolsContext.setGlobalInstance(universe.context);
179+
this.#universe = new Foundation.Universe.Universe(creationOptions);
180+
Root.DevToolsContext.setGlobalInstance(this.#universe.context);
180181

181182
await this.requestAndRegisterLocaleData();
182183

@@ -425,6 +426,7 @@ export class MainImpl {
425426
{forceNew: true, win: window, frontendHost: Host.InspectorFrontendHost.InspectorFrontendHostInstance});
426427
UI.ContextMenu.ContextMenu.initialize();
427428
UI.ContextMenu.ContextMenu.installHandler(document);
429+
UI.ViewManager.ViewManager.instance({forceNew: true, universe: this.#universe});
428430

429431
// These instances need to be created early so they don't miss any events about requests/issues/etc.
430432
Logs.NetworkLog.NetworkLog.instance();

front_end/ui/legacy/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ devtools_ui_module("ui") {
108108
"../../core/platform:bundle",
109109
"../../core/root:bundle",
110110
"../../core/sdk:bundle",
111+
"../../foundation:bundle",
111112
"../../models/geometry:bundle",
112113
"../../models/text_utils:bundle",
113114
"../../ui/legacy/theme_support:bundle",

front_end/ui/legacy/ViewManager.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import * as Common from '../../core/common/common.js';
66
import type {EventTargetEvent} from '../../core/common/EventTarget.js';
77
import * as i18n from '../../core/i18n/i18n.js';
8+
import * as Root from '../../core/root/root.js';
89
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
910

1011
import * as UI from './legacy.js';
@@ -94,7 +95,8 @@ describeWithEnvironment('ViewManager', () => {
9495
});
9596
}
9697

97-
viewManager = UI.ViewManager.ViewManager.instance({forceNew: true});
98+
viewManager = UI.ViewManager.ViewManager.instance(
99+
{forceNew: true, universe: {context: new Root.DevToolsContext.DevToolsContext()}});
98100
locationResolver.createLocation(UI.ViewManager.ViewLocationValues.PANEL, true, 'view-1');
99101
locationResolver.createLocation(UI.ViewManager.ViewLocationValues.DRAWER_VIEW, false, undefined);
100102
});

front_end/ui/legacy/ViewManager.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as Host from '../../core/host/host.js';
1010
import * as i18n from '../../core/i18n/i18n.js';
1111
import * as Platform from '../../core/platform/platform.js';
1212
import * as Root from '../../core/root/root.js';
13+
import type * as Foundation from '../../foundation/foundation.js';
1314
import * as IconButton from '../components/icon_button/icon_button.js';
1415
import * as VisualLogging from '../visual_logging/visual_logging.js';
1516

@@ -52,10 +53,12 @@ export const defaultOptionsForTabs = {
5253

5354
export class PreRegisteredView implements View {
5455
private readonly viewRegistration: ViewRegistration;
56+
private readonly universe?: Foundation.Universe.Universe;
5557
private widgetPromise: Promise<Widget>|null;
5658

57-
constructor(viewRegistration: ViewRegistration) {
59+
constructor(viewRegistration: ViewRegistration, universe?: Foundation.Universe.Universe) {
5860
this.viewRegistration = viewRegistration;
61+
this.universe = universe;
5962
this.widgetPromise = null;
6063
}
6164

@@ -124,7 +127,10 @@ export class PreRegisteredView implements View {
124127

125128
widget(): Promise<Widget> {
126129
if (this.widgetPromise === null) {
127-
this.widgetPromise = this.viewRegistration.loadView();
130+
if (!this.universe) {
131+
throw new Error('Creating views via ViewManager requires a Foundation.Universe');
132+
}
133+
this.widgetPromise = this.viewRegistration.loadView(this.universe);
128134
}
129135
return this.widgetPromise;
130136
}
@@ -170,7 +176,9 @@ export class ViewManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
170176

171177
private readonly preRegisteredViews: PreRegisteredView[] = [];
172178

173-
private constructor() {
179+
// TODO(crbug.com/458180550): Pass the universe unconditionally once tests no longer rely
180+
// on `instance()` to create ViewManagers lazily in after/afterEach blocks.
181+
private constructor(universe?: Foundation.Universe.Universe) {
174182
super();
175183

176184
// Read override setting for location
@@ -184,7 +192,7 @@ export class ViewManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
184192
for (const view of getRegisteredViewExtensions()) {
185193
const location = view.location || 'none';
186194
const views = viewsByLocation.get(location) || [];
187-
views.push(new PreRegisteredView(view));
195+
views.push(new PreRegisteredView(view, universe));
188196
viewsByLocation.set(location, views);
189197
}
190198

@@ -220,10 +228,11 @@ export class ViewManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
220228

221229
static instance(opts: {
222230
forceNew: boolean|null,
231+
universe?: Foundation.Universe.Universe,
223232
} = {forceNew: null}): ViewManager {
224-
const {forceNew} = opts;
233+
const {forceNew, universe} = opts;
225234
if (!viewManagerInstance || forceNew) {
226-
viewManagerInstance = new ViewManager();
235+
viewManagerInstance = new ViewManager(universe);
227236
}
228237

229238
return viewManagerInstance;

front_end/ui/legacy/ViewRegistration.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import * as i18n from '../../core/i18n/i18n.js';
6+
import * as Root from '../../core/root/root.js';
67
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
78

89
import * as QuickOpen from './components/quick_open/quick_open.js';
@@ -41,6 +42,8 @@ describeWithEnvironment('ViewRegistration', () => {
4142
return new MockView();
4243
},
4344
});
45+
UI.ViewManager.ViewManager.instance(
46+
{forceNew: true, universe: {context: new Root.DevToolsContext.DevToolsContext()}});
4447
});
4548

4649
it('retrieves a registered view', async () => {

front_end/ui/legacy/ViewRegistration.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import * as i18n from '../../core/i18n/i18n.js';
66
import type * as Platform from '../../core/platform/platform.js';
77
import * as Root from '../../core/root/root.js';
8+
import type * as Foundation from '../../foundation/foundation.js';
89

910
import type {ViewLocationResolver} from './View.js';
1011
import type {Widget} from './Widget.js';
@@ -112,7 +113,11 @@ export interface ViewRegistration {
112113
/**
113114
* Returns an instance of the class that wraps the view.
114115
* The common pattern for implementing this function is loading the module with the wrapping 'Widget'
115-
* lazily loaded. As an example:
116+
* lazily loaded.
117+
* The DevTools universe is passed along, allowing `loadView` to retrieve necessary dependencies.
118+
* Prefer passing individual dependencies one by one instead of forwarding the full universe. This
119+
* makes testing easier.
120+
* As an example:
116121
*
117122
* ```js
118123
* let loadedElementsModule;
@@ -126,15 +131,16 @@ export interface ViewRegistration {
126131
* }
127132
* UI.ViewManager.registerViewExtension({
128133
* <...>
129-
* async loadView() {
134+
* async loadView(universe) {
130135
* const Elements = await loadElementsModule();
131-
* return Elements.ElementsPanel.ElementsPanel.instance();
136+
* const pageResourceLoader = universe.context.get(SDK.PageResourceLoader.PageResourceLoader);
137+
* return new Elements.ElementsPanel.ElementsPanel(pageResourceLoader);
132138
* },
133139
* <...>
134140
* });
135141
* ```
136142
*/
137-
loadView: () => Promise<Widget>;
143+
loadView: (universe: Foundation.Universe.Universe) => Promise<Widget>;
138144
/**
139145
* Used to sort the views that appear in a shared location.
140146
*/

0 commit comments

Comments
 (0)