[global] Remaps self.UI.viewManager

Moves self.UI.viewManager to an instance() method.

Bug: 1058320
Change-Id: I0c444101da59ba9eba4745d1dc551bb8906a0a4f
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2107624
Reviewed-by: Jack Franklin <[email protected]>
Commit-Queue: Paul Lewis <[email protected]>
diff --git a/.gitignore b/.gitignore
index b178401..ca4b2ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@
 test/e2e/**/*.tsbuildinfo
 test/shared/**/*.js
 test/shared/**/helper.d.ts
+test/shared/**/runner.d.ts
 test/shared/**/screenshot.d.ts
 test/shared/**/*.tsbuildinfo
 test/screenshots/**/*.js
diff --git a/front_end/accessibility/AccessibilitySidebarView.js b/front_end/accessibility/AccessibilitySidebarView.js
index 67e538b..4ba9f0f 100644
--- a/front_end/accessibility/AccessibilitySidebarView.js
+++ b/front_end/accessibility/AccessibilitySidebarView.js
@@ -20,7 +20,7 @@
     this._node = null;
     this._axNode = null;
     this._skipNextPullNode = false;
-    this._sidebarPaneStack = self.UI.viewManager.createStackLocation();
+    this._sidebarPaneStack = UI.ViewManager.ViewManager.instance().createStackLocation();
     this._breadcrumbsSubPane = new AXBreadcrumbsPane(this);
     this._sidebarPaneStack.showView(this._breadcrumbsSubPane);
     this._ariaSubPane = new ARIAAttributesPane();
diff --git a/front_end/browser_debugger/DOMBreakpointsSidebarPane.js b/front_end/browser_debugger/DOMBreakpointsSidebarPane.js
index a3ece6b..ccbdbd0 100644
--- a/front_end/browser_debugger/DOMBreakpointsSidebarPane.js
+++ b/front_end/browser_debugger/DOMBreakpointsSidebarPane.js
@@ -306,7 +306,7 @@
     if (this._highlightedBreakpoint) {
       this._list.refreshItem(this._highlightedBreakpoint);
     }
-    self.UI.viewManager.showView('sources.domBreakpoints');
+    UI.ViewManager.ViewManager.instance().showView('sources.domBreakpoints');
   }
 }
 
diff --git a/front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js b/front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
index 6950ad5..ff01361 100644
--- a/front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
+++ b/front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
@@ -116,7 +116,7 @@
       return;
     }
 
-    self.UI.viewManager.showView('sources.eventListenerBreakpoints');
+    UI.ViewManager.ViewManager.instance().showView('sources.eventListenerBreakpoints');
     this._categories.get(breakpoint.category()).element.expand();
     this._highlightedElement = this._breakpoints.get(breakpoint).element.listItemElement;
     UI.ARIAUtils.setDescription(this._highlightedElement, ls`breakpoint hit`);
diff --git a/front_end/browser_debugger/XHRBreakpointsSidebarPane.js b/front_end/browser_debugger/XHRBreakpointsSidebarPane.js
index 4e5a155..fdb5b1d 100644
--- a/front_end/browser_debugger/XHRBreakpointsSidebarPane.js
+++ b/front_end/browser_debugger/XHRBreakpointsSidebarPane.js
@@ -60,7 +60,7 @@
   }
 
   async _addButtonClicked() {
-    await self.UI.viewManager.showView('sources.xhrBreakpoints');
+    await UI.ViewManager.ViewManager.instance().showView('sources.xhrBreakpoints');
 
     const inputElementContainer = createElementWithClass('p', 'breakpoint-condition');
     inputElementContainer.textContent = Common.UIString.UIString('Break when URL contains:');
@@ -359,7 +359,7 @@
       return;
     }
     this._list.refreshItem(url);
-    self.UI.viewManager.showView('sources.xhrBreakpoints');
+    UI.ViewManager.ViewManager.instance().showView('sources.xhrBreakpoints');
   }
 
   _restoreBreakpoints() {
diff --git a/front_end/changes/ChangesView.js b/front_end/changes/ChangesView.js
index fae8179..cd0ed42 100644
--- a/front_end/changes/ChangesView.js
+++ b/front_end/changes/ChangesView.js
@@ -369,7 +369,7 @@
     }
     /** @type {!ChangesView} */
     const changesView = self.runtime.sharedInstance(ChangesView);
-    await self.UI.viewManager.showView('changes.changes');
+    await UI.ViewManager.ViewManager.instance().showView('changes.changes');
     changesView._changesSidebar.selectUISourceCode(diffUILocation.uiSourceCode, omitFocus);
   }
 }
diff --git a/front_end/console/ConsolePanel.js b/front_end/console/ConsolePanel.js
index 8902882..f0684d3 100644
--- a/front_end/console/ConsolePanel.js
+++ b/front_end/console/ConsolePanel.js
@@ -142,7 +142,7 @@
       consoleView.focus();
       return Promise.resolve();
     }
-    self.UI.viewManager.showView('console-view');
+    UI.ViewManager.ViewManager.instance().showView('console-view');
     return Promise.resolve();
   }
 }
diff --git a/front_end/console_counters/WarningErrorCounter.js b/front_end/console_counters/WarningErrorCounter.js
index 44c838a..ff33ddb 100644
--- a/front_end/console_counters/WarningErrorCounter.js
+++ b/front_end/console_counters/WarningErrorCounter.js
@@ -25,7 +25,7 @@
 
     this._violationCounter = createElement('div');
     this._violationCounter.addEventListener('click', () => {
-      self.UI.viewManager.showView('lighthouse');
+      UI.ViewManager.ViewManager.instance().showView('lighthouse');
     });
     const violationShadowRoot =
         UI.Utils.createShadowRootWithCoreStyles(this._violationCounter, 'console_counters/errorWarningCounter.css');
diff --git a/front_end/coverage/CoverageView.js b/front_end/coverage/CoverageView.js
index d53f9b7..f418a5e 100644
--- a/front_end/coverage/CoverageView.js
+++ b/front_end/coverage/CoverageView.js
@@ -421,8 +421,9 @@
    */
   handleAction(context, actionId) {
     const coverageViewId = 'coverage';
-    self.UI.viewManager.showView(coverageViewId, /** userGesture= */ false, /** omitFocus= */ true)
-        .then(() => self.UI.viewManager.view(coverageViewId).widget())
+    UI.ViewManager.ViewManager.instance()
+        .showView(coverageViewId, /** userGesture= */ false, /** omitFocus= */ true)
+        .then(() => UI.ViewManager.ViewManager.instance().view(coverageViewId).widget())
         .then(widget => this._innerHandleAction(/** @type !CoverageView} */ (widget), actionId));
 
     return true;
@@ -506,8 +507,9 @@
         return;
       }
       const coverageViewId = 'coverage';
-      self.UI.viewManager.showView(coverageViewId)
-          .then(() => self.UI.viewManager.view(coverageViewId).widget())
+      UI.ViewManager.ViewManager.instance()
+          .showView(coverageViewId)
+          .then(() => UI.ViewManager.ViewManager.instance().view(coverageViewId).widget())
           .then(widget => {
             const matchFormattedSuffix = url.match(/(.*):formatted$/);
             const urlWithoutFormattedSuffix = (matchFormattedSuffix && matchFormattedSuffix[1]) || url;
diff --git a/front_end/elements/ElementsPanel.js b/front_end/elements/ElementsPanel.js
index 80d2d10..c2f5a7d 100644
--- a/front_end/elements/ElementsPanel.js
+++ b/front_end/elements/ElementsPanel.js
@@ -520,7 +520,7 @@
   switchToAndFocus(node) {
     // Reset search restore.
     this._searchableView.cancelSearch();
-    self.UI.viewManager.showView('elements').then(() => this.selectDOMNode(node, true));
+    UI.ViewManager.ViewManager.instance().showView('elements').then(() => this.selectDOMNode(node, true));
   }
 
   /**
@@ -739,7 +739,7 @@
       node.highlightForTwoSeconds();
     }
 
-    return self.UI.viewManager.showView('elements', false, !focus).then(() => {
+    return UI.ViewManager.ViewManager.instance().showView('elements', false, !focus).then(() => {
       this.selectDOMNode(node, focus);
       delete this._omitDefaultSelection;
 
@@ -877,7 +877,8 @@
       }
     }
 
-    this.sidebarPaneView = self.UI.viewManager.createTabbedLocation(() => self.UI.viewManager.showView('elements'));
+    this.sidebarPaneView = UI.ViewManager.ViewManager.instance().createTabbedLocation(
+        () => UI.ViewManager.ViewManager.instance().showView('elements'));
     const tabbedPane = this.sidebarPaneView.tabbedPane();
     if (this._popoverHelper) {
       this._popoverHelper.hidePopover();
diff --git a/front_end/emulation/SensorsView.js b/front_end/emulation/SensorsView.js
index c86143f..570b4b7 100644
--- a/front_end/emulation/SensorsView.js
+++ b/front_end/emulation/SensorsView.js
@@ -565,7 +565,7 @@
    * @return {boolean}
    */
   handleAction(context, actionId) {
-    self.UI.viewManager.showView('sensors');
+    UI.ViewManager.ViewManager.instance().showView('sensors');
     return true;
   }
 }
diff --git a/front_end/help/HelpImpl.js b/front_end/help/HelpImpl.js
index da822e6..b353596 100644
--- a/front_end/help/HelpImpl.js
+++ b/front_end/help/HelpImpl.js
@@ -49,7 +49,7 @@
     return;
   }
   Help._releaseNoteVersionSetting.set(latestVersion);
-  self.UI.viewManager.showView(releaseNoteViewId, true);
+  UI.ViewManager.ViewManager.instance().showView(releaseNoteViewId, true);
 }
 
 /**
diff --git a/front_end/input/InputTimeline.js b/front_end/input/InputTimeline.js
index 2e7af45..b5cb907 100644
--- a/front_end/input/InputTimeline.js
+++ b/front_end/input/InputTimeline.js
@@ -291,8 +291,9 @@
    */
   handleAction(context, actionId) {
     const inputViewId = 'Inputs';
-    self.UI.viewManager.showView(inputViewId)
-        .then(() => self.UI.viewManager.view(inputViewId).widget())
+    UI.ViewManager.ViewManager.instance()
+        .showView(inputViewId)
+        .then(() => UI.ViewManager.ViewManager.instance().view(inputViewId).widget())
         .then(widget => this._innerHandleAction(/** @type !InputTimeline} */ (widget), actionId));
 
     return true;
diff --git a/front_end/issues/IssueRevealer.js b/front_end/issues/IssueRevealer.js
index 891ee5b..040c1b6 100644
--- a/front_end/issues/IssueRevealer.js
+++ b/front_end/issues/IssueRevealer.js
@@ -18,8 +18,8 @@
     if (!(issue instanceof SDK.Issue.Issue)) {
       throw new Error('Internal error: not a issue');
     }
-    await self.UI.viewManager.showView('issues-pane');
-    const issuesPane = await self.UI.viewManager.view('issues-pane').widget();
+    await UI.ViewManager.ViewManager.instance().showView('issues-pane');
+    const issuesPane = await UI.ViewManager.ViewManager.instance().view('issues-pane').widget();
     issuesPane.revealByCode(issue.code());
   }
 }
diff --git a/front_end/main/MainImpl.js b/front_end/main/MainImpl.js
index cfc8673..ed06b8a 100644
--- a/front_end/main/MainImpl.js
+++ b/front_end/main/MainImpl.js
@@ -194,7 +194,7 @@
   async _createAppUI() {
     MainImpl.time('Main._createAppUI');
 
-    self.UI.viewManager = new UI.ViewManager.ViewManager();
+    self.UI.viewManager = UI.ViewManager.ViewManager.instance();
 
     // Request filesystems early, we won't create connections until callback is fired. Things will happen in parallel.
     self.Persistence.isolatedFileSystemManager = new Persistence.IsolatedFileSystemManager.IsolatedFileSystemManager();
@@ -715,7 +715,8 @@
         continue;
       }
       moreTools.defaultSection().appendItem(
-          extension.title(), self.UI.viewManager.showView.bind(self.UI.viewManager, descriptor['id']));
+          extension.title(),
+          UI.ViewManager.ViewManager.instance().showView.bind(UI.ViewManager.ViewManager.instance(), descriptor['id']));
     }
 
     const helpSubMenu = contextMenu.footerSection().appendSubMenuItem(Common.UIString.UIString('Help'));
diff --git a/front_end/network/NetworkLogView.js b/front_end/network/NetworkLogView.js
index 21b3c23..2863f27 100644
--- a/front_end/network/NetworkLogView.js
+++ b/front_end/network/NetworkLogView.js
@@ -1422,7 +1422,7 @@
         patterns.push({enabled: true, url: url});
         manager.setBlockedPatterns(patterns);
         manager.setBlockingEnabled(true);
-        self.UI.viewManager.showView('network.blocked-urls');
+        UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
       }
 
       /**
@@ -1431,7 +1431,7 @@
       function removeBlockedURL(url) {
         patterns = patterns.filter(pattern => pattern.url !== url);
         manager.setBlockedPatterns(patterns);
-        self.UI.viewManager.showView('network.blocked-urls');
+        UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
       }
 
       const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
diff --git a/front_end/network/NetworkPanel.js b/front_end/network/NetworkPanel.js
index f613685..34ff3a3 100644
--- a/front_end/network/NetworkPanel.js
+++ b/front_end/network/NetworkPanel.js
@@ -116,8 +116,8 @@
     splitWidget.hideSidebar();
     splitWidget.enableShowModeSaving();
     splitWidget.show(this.element);
-    this._sidebarLocation = self.UI.viewManager.createTabbedLocation(async () => {
-      self.UI.viewManager.showView('network');
+    this._sidebarLocation = UI.ViewManager.ViewManager.instance().createTabbedLocation(async () => {
+      UI.ViewManager.ViewManager.instance().showView('network');
       splitWidget.showBoth();
     }, 'network-sidebar', true);
     const tabbedPane = this._sidebarLocation.tabbedPane();
@@ -195,7 +195,7 @@
       filterString += `${filter.filterType}:${filter.filterValue} `;
     }
     panel._networkLogView.setTextFilterValue(filterString);
-    self.UI.viewManager.showView('network');
+    UI.ViewManager.ViewManager.instance().showView('network');
   }
 
   /**
@@ -479,7 +479,7 @@
    * @return {!Promise<?NetworkItemView>}
    */
   async selectRequest(request) {
-    await self.UI.viewManager.showView('network');
+    await UI.ViewManager.ViewManager.instance().showView('network');
     this._networkLogView.selectRequest(request);
     return this._networkItemView;
   }
@@ -583,7 +583,10 @@
      * @this {NetworkPanel}
      */
     function reveal(request) {
-      self.UI.viewManager.showView('network').then(this._networkLogView.resetFilter.bind(this._networkLogView)).then(this.revealAndHighlightRequest.bind(this, request));
+      UI.ViewManager.ViewManager.instance()
+          .showView('network')
+          .then(this._networkLogView.resetFilter.bind(this._networkLogView))
+          .then(this.revealAndHighlightRequest.bind(this, request));
     }
 
     /**
@@ -708,7 +711,8 @@
       return Promise.reject(new Error('Internal error: not a network request'));
     }
     const panel = NetworkPanel._instance();
-    return self.UI.viewManager.showView('network').then(panel.revealAndHighlightRequest.bind(panel, request));
+    return UI.ViewManager.ViewManager.instance().showView('network').then(
+        panel.revealAndHighlightRequest.bind(panel, request));
   }
 }
 
@@ -892,7 +896,7 @@
    * @return {!Promise<!Search.SearchView.SearchView>}
    */
   static async openSearch(query, searchImmediately) {
-    await self.UI.viewManager.showView('network.search-network-tab');
+    await UI.ViewManager.ViewManager.instance().showView('network.search-network-tab');
     const searchView =
         /** @type {!SearchNetworkView} */ (self.runtime.sharedInstance(SearchNetworkView));
     searchView.toggle(query, !!searchImmediately);
diff --git a/front_end/profiler/LiveHeapProfileView.js b/front_end/profiler/LiveHeapProfileView.js
index 2d3bdd5..125ec05 100644
--- a/front_end/profiler/LiveHeapProfileView.js
+++ b/front_end/profiler/LiveHeapProfileView.js
@@ -331,8 +331,8 @@
   handleAction(context, actionId) {
     (async () => {
       const profileViewId = 'live_heap_profile';
-      await self.UI.viewManager.showView(profileViewId);
-      const widget = await self.UI.viewManager.view(profileViewId).widget();
+      await UI.ViewManager.ViewManager.instance().showView(profileViewId);
+      const widget = await UI.ViewManager.ViewManager.instance().view(profileViewId).widget();
       this._innerHandleAction(/** @type {!LiveHeapProfileView} */ (widget), actionId);
     })();
     return true;
diff --git a/front_end/quick_open/CommandMenu.js b/front_end/quick_open/CommandMenu.js
index f45541f..c10b6ed 100644
--- a/front_end/quick_open/CommandMenu.js
+++ b/front_end/quick_open/CommandMenu.js
@@ -77,7 +77,8 @@
    */
   static createRevealViewCommand(extension, category) {
     const viewId = extension.descriptor()['id'];
-    const executeHandler = self.UI.viewManager.showView.bind(self.UI.viewManager, viewId);
+    const executeHandler =
+        UI.ViewManager.ViewManager.instance().showView.bind(UI.ViewManager.ViewManager.instance(), viewId);
     const tags = extension.descriptor()['tags'] || '';
     return CommandMenu.createCommand(
         category, tags, Common.UIString.UIString('Show %s', extension.title()), '', executeHandler);
diff --git a/front_end/resources/ResourcesPanel.js b/front_end/resources/ResourcesPanel.js
index 0a073cf..9c0f6b9 100644
--- a/front_end/resources/ResourcesPanel.js
+++ b/front_end/resources/ResourcesPanel.js
@@ -214,7 +214,7 @@
       return Promise.reject(new Error('Internal error: not a resource'));
     }
     const sidebar = ResourcesPanel._instance()._sidebar;
-    await self.UI.viewManager.showView('resources');
+    await UI.ViewManager.ViewManager.instance().showView('resources');
     await sidebar.showResource(resource);
   }
 }
@@ -234,7 +234,7 @@
     }
 
     const sidebar = ResourcesPanel._instance()._sidebar;
-    await self.UI.viewManager.showView('resources');
+    await UI.ViewManager.ViewManager.instance().showView('resources');
     await sidebar.cookieListTreeElement.select();
 
     const contextUrl = cookie.contextUrl();
diff --git a/front_end/settings/SettingsScreen.js b/front_end/settings/SettingsScreen.js
index 4d8b3e5..2a9635b 100644
--- a/front_end/settings/SettingsScreen.js
+++ b/front_end/settings/SettingsScreen.js
@@ -53,8 +53,8 @@
     UI.ARIAUtils.markAsHeading(settingsTitleElement, 1);
     settingsTitleElement.textContent = ls`Settings`;
 
-    this._tabbedLocation =
-        self.UI.viewManager.createTabbedLocation(() => SettingsScreen._showSettingsScreen(), 'settings-view');
+    this._tabbedLocation = UI.ViewManager.ViewManager.instance().createTabbedLocation(
+        () => SettingsScreen._showSettingsScreen(), 'settings-view');
     const tabbedPane = this._tabbedLocation.tabbedPane();
     tabbedPane.leftToolbar().appendToolbarItem(new UI.Toolbar.ToolbarItem(settingsLabelElement));
     tabbedPane.setShrinkableTabs(false);
@@ -105,7 +105,7 @@
    * @param {string} name
    */
   _selectTab(name) {
-    self.UI.viewManager.showView(name);
+    UI.ViewManager.ViewManager.instance().showView(name);
   }
 }
 
diff --git a/front_end/sources/CoveragePlugin.js b/front_end/sources/CoveragePlugin.js
index 8b18d4d..f8fd1bd 100644
--- a/front_end/sources/CoveragePlugin.js
+++ b/front_end/sources/CoveragePlugin.js
@@ -28,7 +28,7 @@
     this._text = new UI.Toolbar.ToolbarButton(ls`Click to show Coverage Panel`);
     this._text.setSecondary();
     this._text.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => {
-      self.UI.viewManager.showView('coverage');
+      UI.ViewManager.ViewManager.instance().showView('coverage');
     });
 
     const mainTarget = SDK.SDKModel.TargetManager.instance().mainTarget();
diff --git a/front_end/sources/DebuggerPlugin.js b/front_end/sources/DebuggerPlugin.js
index 4833232..28fc707 100644
--- a/front_end/sources/DebuggerPlugin.js
+++ b/front_end/sources/DebuggerPlugin.js
@@ -214,7 +214,8 @@
           {text: ls`Unblackbox`, highlight: false, delegate: unblackbox, dismiss: true}, {
             text: ls`Configure`,
             highlight: false,
-            delegate: self.UI.viewManager.showView.bind(self.UI.viewManager, 'blackbox'),
+            delegate:
+                UI.ViewManager.ViewManager.instance().showView.bind(UI.ViewManager.ViewManager.instance(), 'blackbox'),
             dismiss: false
           }
         ]);
diff --git a/front_end/sources/JavaScriptBreakpointsSidebarPane.js b/front_end/sources/JavaScriptBreakpointsSidebarPane.js
index 5b4d614..2567ba7 100644
--- a/front_end/sources/JavaScriptBreakpointsSidebarPane.js
+++ b/front_end/sources/JavaScriptBreakpointsSidebarPane.js
@@ -105,7 +105,7 @@
       }
     }
     if (shouldShowView) {
-      self.UI.viewManager.showView('sources.jsBreakpoints');
+      UI.ViewManager.ViewManager.instance().showView('sources.jsBreakpoints');
     }
     this._list.element.classList.toggle(
         'breakpoints-list-deactivated', !Common.Settings.Settings.instance().moduleSetting('breakpointsActive').get());
diff --git a/front_end/sources/SearchSourcesView.js b/front_end/sources/SearchSourcesView.js
index e41fd53..22245d9 100644
--- a/front_end/sources/SearchSourcesView.js
+++ b/front_end/sources/SearchSourcesView.js
@@ -18,12 +18,12 @@
    * @return {!Promise}
    */
   static async openSearch(query, searchImmediately) {
-    const view = self.UI.viewManager.view('sources.search-sources-tab');
+    const view = UI.ViewManager.ViewManager.instance().view('sources.search-sources-tab');
     // Deliberately use target location name so that it could be changed
     // based on the setting later.
-    const location = await self.UI.viewManager.resolveLocation('drawer-view');
+    const location = await UI.ViewManager.ViewManager.instance().resolveLocation('drawer-view');
     location.appendView(view);
-    await self.UI.viewManager.revealView(/** @type {!UI.View.View} */ (view));
+    await UI.ViewManager.ViewManager.instance().revealView(/** @type {!UI.View.View} */ (view));
     const widget = /** @type {!Search.SearchView.SearchView} */ (await view.widget());
     widget.toggle(query, !!searchImmediately);
     return widget;
diff --git a/front_end/sources/SourcesPanel.js b/front_end/sources/SourcesPanel.js
index be32554..3d8878f 100644
--- a/front_end/sources/SourcesPanel.js
+++ b/front_end/sources/SourcesPanel.js
@@ -88,8 +88,8 @@
     this._splitWidget.setMainWidget(this.editorView);
 
     // Create navigator tabbed pane with toolbar.
-    this._navigatorTabbedLocation =
-        self.UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'navigator-view', true);
+    this._navigatorTabbedLocation = UI.ViewManager.ViewManager.instance().createTabbedLocation(
+        this._revealNavigatorSidebar.bind(this), 'navigator-view', true);
     const tabbedPane = this._navigatorTabbedLocation.tabbedPane();
     tabbedPane.setMinimumSize(100, 25);
     tabbedPane.element.classList.add('navigator-tabbed-pane');
@@ -97,13 +97,13 @@
     navigatorMenuButton.setTitle(Common.UIString.UIString('More options'));
     tabbedPane.rightToolbar().appendToolbarItem(navigatorMenuButton);
 
-    if (self.UI.viewManager.hasViewsForLocation('run-view-sidebar')) {
+    if (UI.ViewManager.ViewManager.instance().hasViewsForLocation('run-view-sidebar')) {
       const navigatorSplitWidget =
           new UI.SplitWidget.SplitWidget(false, true, 'sourcePanelNavigatorSidebarSplitViewState');
       navigatorSplitWidget.setMainWidget(tabbedPane);
-      const runViewTabbedPane =
-          self.UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'run-view-sidebar')
-              .tabbedPane();
+      const runViewTabbedPane = UI.ViewManager.ViewManager.instance()
+                                    .createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'run-view-sidebar')
+                                    .tabbedPane();
       navigatorSplitWidget.setSidebarWidget(runViewTabbedPane);
       navigatorSplitWidget.installResizer(runViewTabbedPane.headerElement());
       this.editorView.setSidebarWidget(navigatorSplitWidget);
@@ -119,7 +119,7 @@
     this.editorView.setMainWidget(this._sourcesView);
 
     this._threadsSidebarPane = null;
-    this._watchSidebarPane = /** @type {!UI.View.View} */ (self.UI.viewManager.view('sources.watch'));
+    this._watchSidebarPane = /** @type {!UI.View.View} */ (UI.ViewManager.ViewManager.instance().view('sources.watch'));
     this._callstackPane = self.runtime.sharedInstance(CallStackSidebarPane);
 
     Common.Settings.Settings.instance()
@@ -206,7 +206,8 @@
 
   _showThreadsIfNeeded() {
     if (ThreadsSidebarPane.shouldBeShown() && !this._threadsSidebarPane) {
-      this._threadsSidebarPane = /** @type {!UI.View.View} */ (self.UI.viewManager.view('sources.threads'));
+      this._threadsSidebarPane =
+          /** @type {!UI.View.View} */ (UI.ViewManager.ViewManager.instance().view('sources.threads'));
       if (this._sidebarPaneStack && this._threadsSidebarPane) {
         this._sidebarPaneStack.showView(
             this._threadsSidebarPane, this._splitWidget.isVertical() ? this._watchSidebarPane : this._callstackPane);
@@ -300,7 +301,7 @@
     if (!self.UI.inspectorView.canSelectPanel('sources')) {
       return false;
     }
-    self.UI.viewManager.showView('sources');
+    UI.ViewManager.ViewManager.instance().showView('sources');
     return true;
   }
 
@@ -438,7 +439,7 @@
           if (skipReveal) {
             this._navigatorTabbedLocation.tabbedPane().selectTab(viewId);
           } else {
-            self.UI.viewManager.showView(viewId);
+            UI.ViewManager.ViewManager.instance().showView(viewId);
           }
         }
       }
@@ -956,7 +957,8 @@
     vbox.element.appendChild(this._debugToolbarDrawer);
 
     vbox.setMinimumAndPreferredSizes(minToolbarWidth, 25, minToolbarWidth, 100);
-    this._sidebarPaneStack = self.UI.viewManager.createStackLocation(this._revealDebuggerSidebar.bind(this));
+    this._sidebarPaneStack =
+        UI.ViewManager.ViewManager.instance().createStackLocation(this._revealDebuggerSidebar.bind(this));
     this._sidebarPaneStack.widget().element.classList.add('overflow-auto');
     this._sidebarPaneStack.widget().show(vbox.element);
     this._sidebarPaneStack.widget().element.appendChild(this._debuggerPausedMessage.element());
@@ -971,12 +973,14 @@
     }
 
     this._sidebarPaneStack.showView(this._callstackPane);
-    const jsBreakpoints = /** @type {!UI.View.View} */ (self.UI.viewManager.view('sources.jsBreakpoints'));
+    const jsBreakpoints =
+        /** @type {!UI.View.View} */ (UI.ViewManager.ViewManager.instance().view('sources.jsBreakpoints'));
     const sourceScopeChainView = /** @type {?UI.View.View} */
         (Root.Runtime.experiments.isEnabled('wasmDWARFDebugging') ?
-             self.UI.viewManager.view('sources.sourceScopeChain') :
+             UI.ViewManager.ViewManager.instance().view('sources.sourceScopeChain') :
              null);
-    const scopeChainView = /** @type {!UI.View.View} */ (self.UI.viewManager.view('sources.scopeChain'));
+    const scopeChainView =
+        /** @type {!UI.View.View} */ (UI.ViewManager.ViewManager.instance().view('sources.scopeChain'));
 
     if (this._tabbedLocationHeader) {
       this._splitWidget.uninstallResizer(this._tabbedLocationHeader);
@@ -1000,7 +1004,8 @@
       // Populate the left stack.
       this._sidebarPaneStack.showView(jsBreakpoints);
 
-      const tabbedLocation = self.UI.viewManager.createTabbedLocation(this._revealDebuggerSidebar.bind(this));
+      const tabbedLocation =
+          UI.ViewManager.ViewManager.instance().createTabbedLocation(this._revealDebuggerSidebar.bind(this));
       splitWidget.setSidebarWidget(tabbedLocation.tabbedPane());
       this._tabbedLocationHeader = tabbedLocation.tabbedPane().headerElement();
       this._splitWidget.installResizer(this._tabbedLocationHeader);
@@ -1028,7 +1033,7 @@
    * @return {!Promise}
    */
   _setAsCurrentPanel() {
-    return self.UI.viewManager.showView('sources');
+    return UI.ViewManager.ViewManager.instance().showView('sources');
   }
 
   /**
diff --git a/front_end/sources/SourcesView.js b/front_end/sources/SourcesView.js
index 80bb1f5..e1995ca 100644
--- a/front_end/sources/SourcesView.js
+++ b/front_end/sources/SourcesView.js
@@ -98,7 +98,7 @@
       }
 
       event.returnValue = Common.UIString.UIString('DevTools have unsaved changes that will be permanently lost.');
-      self.UI.viewManager.showView('sources');
+      UI.ViewManager.ViewManager.instance().showView('sources');
       for (let i = 0; i < unsavedSourceCodes.length; ++i) {
         Common.Revealer.reveal(unsavedSourceCodes[i]);
       }
diff --git a/front_end/sources/WatchExpressionsSidebarPane.js b/front_end/sources/WatchExpressionsSidebarPane.js
index ba93658..bb77c7a 100644
--- a/front_end/sources/WatchExpressionsSidebarPane.js
+++ b/front_end/sources/WatchExpressionsSidebarPane.js
@@ -117,7 +117,7 @@
   }
 
   async _addButtonClicked() {
-    await self.UI.viewManager.showView('sources.watch');
+    await UI.ViewManager.ViewManager.instance().showView('sources.watch');
     this._createWatchExpression(null).startEditing();
   }
 
@@ -225,7 +225,7 @@
    * @param {string} expression
    */
   _focusAndAddExpressionToWatch(expression) {
-    self.UI.viewManager.showView('sources.watch');
+    UI.ViewManager.ViewManager.instance().showView('sources.watch');
     this.doUpdate();
     this._addExpressionToWatch(expression);
   }
diff --git a/front_end/timeline/TimelinePanel.js b/front_end/timeline/TimelinePanel.js
index a341a40..dadecce2 100644
--- a/front_end/timeline/TimelinePanel.js
+++ b/front_end/timeline/TimelinePanel.js
@@ -550,8 +550,9 @@
     };
 
     if (recordingOptions.startCoverage) {
-      await self.UI.viewManager.showView('coverage')
-          .then(() => self.UI.viewManager.view('coverage').widget())
+      await UI.ViewManager.ViewManager.instance()
+          .showView('coverage')
+          .then(() => UI.ViewManager.ViewManager.instance().view('coverage').widget())
           .then(widget => widget.ensureRecordingStarted());
     }
 
@@ -584,8 +585,9 @@
     }
     this._setState(State.StopPending);
     if (this._startCoverage.get()) {
-      await self.UI.viewManager.showView('coverage')
-          .then(() => self.UI.viewManager.view('coverage').widget())
+      await UI.ViewManager.ViewManager.instance()
+          .showView('coverage')
+          .then(() => UI.ViewManager.ViewManager.instance().view('coverage').widget())
           .then(widget => widget.stopRecording());
     }
     const model = await this._controller.stopRecording();
@@ -853,8 +855,9 @@
     this._historyManager.addRecording(this._performanceModel);
 
     if (this._startCoverage.get()) {
-      self.UI.viewManager.showView('coverage')
-          .then(() => self.UI.viewManager.view('coverage').widget())
+      UI.ViewManager.ViewManager.instance()
+          .showView('coverage')
+          .then(() => UI.ViewManager.ViewManager.instance().view('coverage').widget())
           .then(widget => widget.processBacklog())
           .then(() => this._updateOverviewControls());
     }
@@ -1298,7 +1301,7 @@
    * @param {string} value
    */
   handleQueryParam(value) {
-    self.UI.viewManager.showView('timeline').then(() => {
+    UI.ViewManager.ViewManager.instance().showView('timeline').then(() => {
       TimelinePanel.instance()._loadFromURL(window.decodeURIComponent(value));
     });
   }
diff --git a/front_end/ui/InspectorView.js b/front_end/ui/InspectorView.js
index e90b949..f07debb 100644
--- a/front_end/ui/InspectorView.js
+++ b/front_end/ui/InspectorView.js
@@ -42,6 +42,7 @@
 import {Events as TabbedPaneEvents} from './TabbedPane.js';
 import {ToolbarButton} from './Toolbar.js';
 import {View, ViewLocation, ViewLocationResolver} from './View.js';  // eslint-disable-line no-unused-vars
+import {ViewManager} from './ViewManager.js';
 import {VBox, WidgetFocusRestorer} from './Widget.js';
 
 /**
@@ -63,7 +64,7 @@
 
     // Create drawer tabbed pane.
     this._drawerTabbedLocation =
-        self.UI.viewManager.createTabbedLocation(this._showDrawer.bind(this, false), 'drawer-view', true, true);
+        ViewManager.instance().createTabbedLocation(this._showDrawer.bind(this, false), 'drawer-view', true, true);
     const moreTabsButton = this._drawerTabbedLocation.enableMoreTabsButton();
     moreTabsButton.setTitle(ls`More Tools`);
     this._drawerTabbedPane = this._drawerTabbedLocation.tabbedPane();
@@ -77,7 +78,7 @@
     this._drawerTabbedPane.rightToolbar().appendToolbarItem(closeDrawerButton);
 
     // Create main area tabbed pane.
-    this._tabbedLocation = self.UI.viewManager.createTabbedLocation(
+    this._tabbedLocation = ViewManager.instance().createTabbedLocation(
         Host.InspectorFrontendHost.InspectorFrontendHostInstance.bringToFront.bind(
             Host.InspectorFrontendHost.InspectorFrontendHostInstance),
         'panel', true, true, Root.Runtime.queryParam('panel'));
@@ -171,7 +172,7 @@
    */
   panel(panelName) {
     return (
-        /** @type {!Promise.<!Panel>} */ (self.UI.viewManager.view(panelName).widget()));
+        /** @type {!Promise.<!Panel>} */ (ViewManager.instance().view(panelName).widget()));
   }
 
   /**
@@ -197,7 +198,7 @@
    * @return {!Promise.<?Panel>}
    */
   showPanel(panelName) {
-    return self.UI.viewManager.showView(panelName);
+    return ViewManager.instance().showView(panelName);
   }
 
   /**
@@ -213,7 +214,7 @@
    */
   currentPanelDeprecated() {
     return (
-        /** @type {?Panel} */ (self.UI.viewManager.materializedWidget(this._tabbedPane.selectedTabId || '')));
+        /** @type {?Panel} */ (ViewManager.instance().materializedWidget(this._tabbedPane.selectedTabId || '')));
   }
 
   /**
diff --git a/front_end/ui/View.js b/front_end/ui/View.js
index 5f459df..cd4afdb 100644
--- a/front_end/ui/View.js
+++ b/front_end/ui/View.js
@@ -4,6 +4,7 @@
 
 import {TabbedPane} from './TabbedPane.js';  // eslint-disable-line no-unused-vars
 import {ItemsProvider, Toolbar, ToolbarItem, ToolbarMenuButton} from './Toolbar.js';  // eslint-disable-line no-unused-vars
+import {ViewManager} from './ViewManager.js';
 import {VBox, Widget} from './Widget.js';
 
 /**
@@ -127,7 +128,7 @@
    * @return {!Promise}
    */
   revealView() {
-    return self.UI.viewManager.revealView(this);
+    return ViewManager.instance().revealView(this);
   }
 
   /**
diff --git a/front_end/ui/ViewManager.js b/front_end/ui/ViewManager.js
index 5a15759..2a6e351 100644
--- a/front_end/ui/ViewManager.js
+++ b/front_end/ui/ViewManager.js
@@ -13,9 +13,17 @@
 import {VBox, Widget} from './Widget.js';  // eslint-disable-line no-unused-vars
 
 /**
+ * @type {!ViewManager}
+ */
+let viewManagerInstance;
+
+/**
  * @unrestricted
  */
 export class ViewManager {
+  /**
+   * @private
+   */
   constructor() {
     /** @type {!Map<string, !View>} */
     this._views = new Map();
@@ -30,6 +38,18 @@
   }
 
   /**
+   * @param {{forceNew: ?boolean}} opts
+   */
+  static instance(opts = {forceNew: null}) {
+    const {forceNew} = opts;
+    if (!viewManagerInstance || forceNew) {
+      viewManagerInstance = new ViewManager();
+    }
+
+    return viewManagerInstance;
+  }
+
+  /**
    * @param {!Array<!ToolbarItem>} toolbarItems
    * @return {?Element}
    */