blob: 3513135da1428d3cd51bc00a727ed1c023166349 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Matt Lilek ([email protected]).
4 * Copyright (C) 2009 Joseph Pecoraro
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
Tim van der Lippe3cd66dc2020-01-10 15:26:2231import {ExecutionContextSelector} from './ExecutionContextSelector.js';
32
Blink Reformat4c46d092018-04-07 15:32:3733/**
34 * @unrestricted
35 */
Paul Lewisc1d99fa2019-12-10 16:26:2836export class MainImpl {
Blink Reformat4c46d092018-04-07 15:32:3737 /**
38 * @suppressGlobalPropertiesCheck
39 */
40 constructor() {
Paul Lewisc1d99fa2019-12-10 16:26:2841 MainImpl._instanceForTest = this;
Blink Reformat4c46d092018-04-07 15:32:3742 runOnWindowLoad(this._loaded.bind(this));
43 }
44
45 /**
46 * @param {string} label
47 */
48 static time(label) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3449 if (Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:3750 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3451 }
Blink Reformat4c46d092018-04-07 15:32:3752 console.time(label);
53 }
54
55 /**
56 * @param {string} label
57 */
58 static timeEnd(label) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3459 if (Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:3760 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3461 }
Blink Reformat4c46d092018-04-07 15:32:3762 console.timeEnd(label);
63 }
64
65 async _loaded() {
66 console.timeStamp('Main._loaded');
Tim van der Lippe99e59b82019-09-30 20:00:5967 await Root.Runtime.appStarted();
68 Root.Runtime.setPlatform(Host.platform());
69 Root.Runtime.setL10nCallback(ls);
Tim van der Lippe50cfa9b2019-10-01 10:40:5870 Host.InspectorFrontendHost.getPreferences(this._gotPreferences.bind(this));
Blink Reformat4c46d092018-04-07 15:32:3771 }
72
73 /**
74 * @param {!Object<string, string>} prefs
75 */
76 _gotPreferences(prefs) {
77 console.timeStamp('Main._gotPreferences');
Tim van der Lippe1d6e57a2019-09-30 11:55:3478 if (Host.isUnderTest(prefs)) {
Blink Reformat4c46d092018-04-07 15:32:3779 self.runtime.useTestBase();
Tim van der Lippe1d6e57a2019-09-30 11:55:3480 }
Blink Reformat4c46d092018-04-07 15:32:3781 this._createSettings(prefs);
82 this._createAppUI();
83 }
84
85 /**
86 * @param {!Object<string, string>} prefs
87 * Note: this function is called from testSettings in Tests.js.
88 */
89 _createSettings(prefs) {
90 this._initializeExperiments();
91 let storagePrefix = '';
Tim van der Lippe1d6e57a2019-09-30 11:55:3492 if (Host.isCustomDevtoolsFrontend()) {
Blink Reformat4c46d092018-04-07 15:32:3793 storagePrefix = '__custom__';
Tim van der Lippe99e59b82019-09-30 20:00:5994 } else if (
95 !Root.Runtime.queryParam('can_dock') && !!Root.Runtime.queryParam('debugFrontend') && !Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:3796 storagePrefix = '__bundled__';
Tim van der Lippe1d6e57a2019-09-30 11:55:3497 }
Blink Reformat4c46d092018-04-07 15:32:3798
99 let localStorage;
100 if (!Host.isUnderTest() && window.localStorage) {
101 localStorage = new Common.SettingsStorage(
102 window.localStorage, undefined, undefined, () => window.localStorage.clear(), storagePrefix);
103 } else {
104 localStorage = new Common.SettingsStorage({}, undefined, undefined, undefined, storagePrefix);
105 }
106 const globalStorage = new Common.SettingsStorage(
Tim van der Lippe50cfa9b2019-10-01 10:40:58107 prefs, Host.InspectorFrontendHost.setPreference, Host.InspectorFrontendHost.removePreference,
108 Host.InspectorFrontendHost.clearPreferences, storagePrefix);
Blink Reformat4c46d092018-04-07 15:32:37109 Common.settings = new Common.Settings(globalStorage, localStorage);
Tim van der Lippe1d6e57a2019-09-30 11:55:34110 if (!Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:37111 new Common.VersionController().updateVersion();
Tim van der Lippe1d6e57a2019-09-30 11:55:34112 }
Blink Reformat4c46d092018-04-07 15:32:37113 }
114
115 _initializeExperiments() {
116 // Keep this sorted alphabetically: both keys and values.
Tim van der Lippe99e59b82019-09-30 20:00:59117 Root.Runtime.experiments.register('applyCustomStylesheet', 'Allow custom UI themes');
118 Root.Runtime.experiments.register('captureNodeCreationStacks', 'Capture node creation stacks');
119 Root.Runtime.experiments.register('sourcesPrettyPrint', 'Automatically pretty print in the Sources Panel');
120 Root.Runtime.experiments.register('backgroundServices', 'Background web platform feature events', true);
121 Root.Runtime.experiments.register(
122 'backgroundServicesNotifications', 'Background services section for Notifications');
123 Root.Runtime.experiments.register(
124 'backgroundServicesPaymentHandler', 'Background services section for Payment Handler');
125 Root.Runtime.experiments.register(
126 'backgroundServicesPushMessaging', 'Background services section for Push Messaging');
Tim van der Lippe99e59b82019-09-30 20:00:59127 Root.Runtime.experiments.register('blackboxJSFramesOnTimeline', 'Blackbox JavaScript frames on Timeline', true);
128 Root.Runtime.experiments.register('cssOverview', 'CSS Overview');
129 Root.Runtime.experiments.register('emptySourceMapAutoStepping', 'Empty sourcemap auto-stepping');
130 Root.Runtime.experiments.register('inputEventsOnTimelineOverview', 'Input events on Timeline overview', true);
131 Root.Runtime.experiments.register('liveHeapProfile', 'Live heap profile', true);
Ted Meyer79b022f2019-10-08 18:24:30132 Root.Runtime.experiments.register('mediaInspector', 'Media Element Inspection');
Tim van der Lippe99e59b82019-09-30 20:00:59133 Root.Runtime.experiments.register('nativeHeapProfiler', 'Native memory sampling heap profiler', true);
134 Root.Runtime.experiments.register('protocolMonitor', 'Protocol Monitor');
135 Root.Runtime.experiments.register(
136 'recordCoverageWithPerformanceTracing', 'Record coverage while performance tracing');
137 Root.Runtime.experiments.register('samplingHeapProfilerTimeline', 'Sampling heap profiler timeline', true);
138 Root.Runtime.experiments.register('sourceDiff', 'Source diff');
Tim van der Lippe99e59b82019-09-30 20:00:59139 Root.Runtime.experiments.register('spotlight', 'Spotlight', true);
Blink Reformat4c46d092018-04-07 15:32:37140
141 // Timeline
Tim van der Lippe99e59b82019-09-30 20:00:59142 Root.Runtime.experiments.register('timelineEventInitiators', 'Timeline: event initiators');
143 Root.Runtime.experiments.register('timelineFlowEvents', 'Timeline: flow events', true);
144 Root.Runtime.experiments.register('timelineInvalidationTracking', 'Timeline: invalidation tracking', true);
145 Root.Runtime.experiments.register('timelineShowAllEvents', 'Timeline: show all events', true);
146 Root.Runtime.experiments.register(
147 'timelineV8RuntimeCallStats', 'Timeline: V8 Runtime Call Stats on Timeline', true);
148 Root.Runtime.experiments.register('timelineWebGL', 'Timeline: WebGL-based flamechart');
Ella Ge78047ef2019-12-13 14:19:51149 Root.Runtime.experiments.register('timelineReplayEvent', 'Timeline: Replay input events');
Blink Reformat4c46d092018-04-07 15:32:37150
Tim van der Lippe99e59b82019-09-30 20:00:59151 Root.Runtime.experiments.cleanUpStaleExperiments();
152 const enabledExperiments = Root.Runtime.queryParam('enabledExperiments');
Tim van der Lippe1d6e57a2019-09-30 11:55:34153 if (enabledExperiments) {
Tim van der Lippe99e59b82019-09-30 20:00:59154 Root.Runtime.experiments.setServerEnabledExperiments(enabledExperiments.split(';'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34155 }
Tim van der Lippe99e59b82019-09-30 20:00:59156 Root.Runtime.experiments.setDefaultExperiments([
Rayan Kanso93bacf72019-08-28 12:33:23157 'backgroundServices',
158 'backgroundServicesNotifications',
159 'backgroundServicesPushMessaging',
160 'backgroundServicesPaymentHandler',
161 ]);
Alexei Filippovfdfefe02019-03-09 00:33:24162
Tim van der Lippe99e59b82019-09-30 20:00:59163 if (Host.isUnderTest() && Root.Runtime.queryParam('test').includes('live-line-level-heap-profile.js')) {
164 Root.Runtime.experiments.enableForTest('liveHeapProfile');
Tim van der Lippe1d6e57a2019-09-30 11:55:34165 }
Blink Reformat4c46d092018-04-07 15:32:37166 }
167
168 /**
169 * @suppressGlobalPropertiesCheck
170 */
171 async _createAppUI() {
Paul Lewisc1d99fa2019-12-10 16:26:28172 MainImpl.time('Main._createAppUI');
Blink Reformat4c46d092018-04-07 15:32:37173
174 UI.viewManager = new UI.ViewManager();
175
176 // Request filesystems early, we won't create connections until callback is fired. Things will happen in parallel.
177 Persistence.isolatedFileSystemManager = new Persistence.IsolatedFileSystemManager();
178
Erik Luo9adba992019-06-26 01:17:52179 const themeSetting = Common.settings.createSetting('uiTheme', 'systemPreferred');
Blink Reformat4c46d092018-04-07 15:32:37180 UI.initializeUIUtils(document, themeSetting);
181 themeSetting.addChangeListener(Components.reload.bind(Components));
182
183 UI.installComponentRootStyles(/** @type {!Element} */ (document.body));
184
185 this._addMainEventListeners(document);
186
Tim van der Lippe99e59b82019-09-30 20:00:59187 const canDock = !!Root.Runtime.queryParam('can_dock');
Tim van der Lippe50cfa9b2019-10-01 10:40:58188 UI.zoomManager = new UI.ZoomManager(window, Host.InspectorFrontendHost);
Blink Reformat4c46d092018-04-07 15:32:37189 UI.inspectorView = UI.InspectorView.instance();
190 UI.ContextMenu.initialize();
191 UI.ContextMenu.installHandler(document);
192 UI.Tooltip.installHandler(document);
193 Components.dockController = new Components.DockController(canDock);
194 SDK.consoleModel = new SDK.ConsoleModel();
195 SDK.multitargetNetworkManager = new SDK.MultitargetNetworkManager();
196 SDK.domDebuggerManager = new SDK.DOMDebuggerManager();
197 SDK.targetManager.addEventListener(
198 SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged.bind(this));
199
200 UI.shortcutsScreen = new UI.ShortcutsScreen();
201 // set order of some sections explicitly
202 UI.shortcutsScreen.section(Common.UIString('Elements Panel'));
203 UI.shortcutsScreen.section(Common.UIString('Styles Pane'));
204 UI.shortcutsScreen.section(Common.UIString('Debugger'));
205 UI.shortcutsScreen.section(Common.UIString('Console'));
206
207 Workspace.fileManager = new Workspace.FileManager();
208 Workspace.workspace = new Workspace.Workspace();
209
210 Bindings.networkProjectManager = new Bindings.NetworkProjectManager();
211 Bindings.resourceMapping = new Bindings.ResourceMapping(SDK.targetManager, Workspace.workspace);
212 new Bindings.PresentationConsoleMessageManager();
213 Bindings.cssWorkspaceBinding = new Bindings.CSSWorkspaceBinding(SDK.targetManager, Workspace.workspace);
214 Bindings.debuggerWorkspaceBinding = new Bindings.DebuggerWorkspaceBinding(SDK.targetManager, Workspace.workspace);
215 Bindings.breakpointManager =
216 new Bindings.BreakpointManager(Workspace.workspace, SDK.targetManager, Bindings.debuggerWorkspaceBinding);
217 Extensions.extensionServer = new Extensions.ExtensionServer();
218
219 new Persistence.FileSystemWorkspaceBinding(Persistence.isolatedFileSystemManager, Workspace.workspace);
220 Persistence.persistence = new Persistence.Persistence(Workspace.workspace, Bindings.breakpointManager);
221 Persistence.networkPersistenceManager = new Persistence.NetworkPersistenceManager(Workspace.workspace);
222
Tim van der Lippe3cd66dc2020-01-10 15:26:22223 new ExecutionContextSelector(SDK.targetManager, UI.context);
Blink Reformat4c46d092018-04-07 15:32:37224 Bindings.blackboxManager = new Bindings.BlackboxManager(Bindings.debuggerWorkspaceBinding);
225
Paul Lewisc1d99fa2019-12-10 16:26:28226 new PauseListener();
Blink Reformat4c46d092018-04-07 15:32:37227
228 UI.actionRegistry = new UI.ActionRegistry();
229 UI.shortcutRegistry = new UI.ShortcutRegistry(UI.actionRegistry, document);
230 UI.ShortcutsScreen.registerShortcuts();
231 this._registerForwardedShortcuts();
232 this._registerMessageSinkListener();
233
Paul Lewisc1d99fa2019-12-10 16:26:28234 MainImpl.timeEnd('Main._createAppUI');
Blink Reformat4c46d092018-04-07 15:32:37235 this._showAppUI(await self.runtime.extension(Common.AppProvider).instance());
236 }
237
238 /**
239 * @param {!Object} appProvider
240 * @suppressGlobalPropertiesCheck
241 */
242 _showAppUI(appProvider) {
Paul Lewisc1d99fa2019-12-10 16:26:28243 MainImpl.time('Main._showAppUI');
Blink Reformat4c46d092018-04-07 15:32:37244 const app = /** @type {!Common.AppProvider} */ (appProvider).createApp();
245 // It is important to kick controller lifetime after apps are instantiated.
246 Components.dockController.initialize();
247 app.presentUI(document);
248
249 const toggleSearchNodeAction = UI.actionRegistry.action('elements.toggle-element-search');
250 // TODO: we should not access actions from other modules.
251 if (toggleSearchNodeAction) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58252 Host.InspectorFrontendHost.events.addEventListener(
Tim van der Lippe7b190162019-09-27 15:10:44253 Host.InspectorFrontendHostAPI.Events.EnterInspectElementMode,
Blink Reformat4c46d092018-04-07 15:32:37254 toggleSearchNodeAction.execute.bind(toggleSearchNodeAction), this);
255 }
Tim van der Lippe50cfa9b2019-10-01 10:40:58256 Host.InspectorFrontendHost.events.addEventListener(
Tim van der Lippe7b190162019-09-27 15:10:44257 Host.InspectorFrontendHostAPI.Events.RevealSourceLine, this._revealSourceLine, this);
Blink Reformat4c46d092018-04-07 15:32:37258
259 UI.inspectorView.createToolbars();
Tim van der Lippe50cfa9b2019-10-01 10:40:58260 Host.InspectorFrontendHost.loadCompleted();
Blink Reformat4c46d092018-04-07 15:32:37261
262 const extensions = self.runtime.extensions(Common.QueryParamHandler);
263 for (const extension of extensions) {
Tim van der Lippe99e59b82019-09-30 20:00:59264 const value = Root.Runtime.queryParam(extension.descriptor()['name']);
Tim van der Lippe1d6e57a2019-09-30 11:55:34265 if (value !== null) {
Blink Reformat4c46d092018-04-07 15:32:37266 extension.instance().then(handleQueryParam.bind(null, value));
Tim van der Lippe1d6e57a2019-09-30 11:55:34267 }
Blink Reformat4c46d092018-04-07 15:32:37268 }
269
270 /**
271 * @param {string} value
272 * @param {!Common.QueryParamHandler} handler
273 */
274 function handleQueryParam(value, handler) {
275 handler.handleQueryParam(value);
276 }
277
278 // Allow UI cycles to repaint prior to creating connection.
279 setTimeout(this._initializeTarget.bind(this), 0);
Paul Lewisc1d99fa2019-12-10 16:26:28280 MainImpl.timeEnd('Main._showAppUI');
Blink Reformat4c46d092018-04-07 15:32:37281 }
282
283 async _initializeTarget() {
Paul Lewisc1d99fa2019-12-10 16:26:28284 MainImpl.time('Main._initializeTarget');
Blink Reformat4c46d092018-04-07 15:32:37285 const instances =
286 await Promise.all(self.runtime.extensions('early-initialization').map(extension => extension.instance()));
Tim van der Lippe1d6e57a2019-09-30 11:55:34287 for (const instance of instances) {
Pavel Feldman07ef9722018-12-13 23:52:22288 await /** @type {!Common.Runnable} */ (instance).run();
Tim van der Lippe1d6e57a2019-09-30 11:55:34289 }
Blink Reformat4c46d092018-04-07 15:32:37290 // Used for browser tests.
Tim van der Lippe50cfa9b2019-10-01 10:40:58291 Host.InspectorFrontendHost.readyForTest();
Blink Reformat4c46d092018-04-07 15:32:37292 // Asynchronously run the extensions.
293 setTimeout(this._lateInitialization.bind(this), 100);
Paul Lewisc1d99fa2019-12-10 16:26:28294 MainImpl.timeEnd('Main._initializeTarget');
Blink Reformat4c46d092018-04-07 15:32:37295 }
296
297 _lateInitialization() {
Paul Lewisc1d99fa2019-12-10 16:26:28298 MainImpl.time('Main._lateInitialization');
Blink Reformat4c46d092018-04-07 15:32:37299 this._registerShortcuts();
300 Extensions.extensionServer.initializeExtensions();
Alexei Filippov19be5102019-04-16 20:40:24301 const extensions = self.runtime.extensions('late-initialization');
302 const promises = [];
303 for (const extension of extensions) {
304 const setting = extension.descriptor()['setting'];
305 if (!setting || Common.settings.moduleSetting(setting).get()) {
306 promises.push(extension.instance().then(instance => (/** @type {!Common.Runnable} */ (instance)).run()));
307 continue;
308 }
309 /**
310 * @param {!Common.Event} event
311 */
312 async function changeListener(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34313 if (!event.data) {
Alexei Filippov19be5102019-04-16 20:40:24314 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34315 }
Alexei Filippov19be5102019-04-16 20:40:24316 Common.settings.moduleSetting(setting).removeChangeListener(changeListener);
317 (/** @type {!Common.Runnable} */ (await extension.instance())).run();
318 }
319 Common.settings.moduleSetting(setting).addChangeListener(changeListener);
320 }
321 this._lateInitDonePromise = Promise.all(promises);
Paul Lewisc1d99fa2019-12-10 16:26:28322 MainImpl.timeEnd('Main._lateInitialization');
Blink Reformat4c46d092018-04-07 15:32:37323 }
324
Alexei Filippov19be5102019-04-16 20:40:24325 /**
326 * @return {!Promise}
327 */
328 lateInitDonePromiseForTest() {
329 return this._lateInitDonePromise;
330 }
331
Blink Reformat4c46d092018-04-07 15:32:37332 _registerForwardedShortcuts() {
333 /** @const */ const forwardedActions = [
334 'main.toggle-dock', 'debugger.toggle-breakpoints-active', 'debugger.toggle-pause', 'commandMenu.show',
335 'console.show'
336 ];
337 const actionKeys =
338 UI.shortcutRegistry.keysForActions(forwardedActions).map(UI.KeyboardShortcut.keyCodeAndModifiersFromKey);
Tim van der Lippe50cfa9b2019-10-01 10:40:58339 Host.InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));
Blink Reformat4c46d092018-04-07 15:32:37340 }
341
342 _registerMessageSinkListener() {
343 Common.console.addEventListener(Common.Console.Events.MessageAdded, messageAdded);
344
345 /**
346 * @param {!Common.Event} event
347 */
348 function messageAdded(event) {
349 const message = /** @type {!Common.Console.Message} */ (event.data);
Tim van der Lippe1d6e57a2019-09-30 11:55:34350 if (message.show) {
Blink Reformat4c46d092018-04-07 15:32:37351 Common.console.show();
Tim van der Lippe1d6e57a2019-09-30 11:55:34352 }
Blink Reformat4c46d092018-04-07 15:32:37353 }
354 }
355
356 /**
357 * @param {!Common.Event} event
358 */
359 _revealSourceLine(event) {
360 const url = /** @type {string} */ (event.data['url']);
361 const lineNumber = /** @type {number} */ (event.data['lineNumber']);
362 const columnNumber = /** @type {number} */ (event.data['columnNumber']);
363
364 const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
365 if (uiSourceCode) {
366 Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
367 return;
368 }
369
370 /**
371 * @param {!Common.Event} event
372 */
373 function listener(event) {
374 const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
375 if (uiSourceCode.url() === url) {
376 Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
377 Workspace.workspace.removeEventListener(Workspace.Workspace.Events.UISourceCodeAdded, listener);
378 }
379 }
380
381 Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, listener);
382 }
383
384 _registerShortcuts() {
385 const shortcut = UI.KeyboardShortcut;
386 const section = UI.shortcutsScreen.section(Common.UIString('All Panels'));
387 let keys = [
388 shortcut.makeDescriptor('[', shortcut.Modifiers.CtrlOrMeta),
389 shortcut.makeDescriptor(']', shortcut.Modifiers.CtrlOrMeta)
390 ];
391 section.addRelatedKeys(keys, Common.UIString('Go to the panel to the left/right'));
392
393 const toggleConsoleLabel = Common.UIString('Show console');
394 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
395 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), Common.UIString('Toggle drawer'));
396 if (Components.dockController.canDock()) {
397 section.addKey(
398 shortcut.makeDescriptor('M', shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift),
399 Common.UIString('Toggle device mode'));
400 section.addKey(
401 shortcut.makeDescriptor('D', shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift),
402 Common.UIString('Toggle dock side'));
403 }
404 section.addKey(shortcut.makeDescriptor('f', shortcut.Modifiers.CtrlOrMeta), Common.UIString('Search'));
405
406 const advancedSearchShortcutModifier = Host.isMac() ?
407 UI.KeyboardShortcut.Modifiers.Meta | UI.KeyboardShortcut.Modifiers.Alt :
408 UI.KeyboardShortcut.Modifiers.Ctrl | UI.KeyboardShortcut.Modifiers.Shift;
409 const advancedSearchShortcut = shortcut.makeDescriptor('f', advancedSearchShortcutModifier);
410 section.addKey(advancedSearchShortcut, Common.UIString('Search across all sources'));
411
412 const inspectElementModeShortcuts =
413 UI.shortcutRegistry.shortcutDescriptorsForAction('elements.toggle-element-search');
Tim van der Lippe1d6e57a2019-09-30 11:55:34414 if (inspectElementModeShortcuts.length) {
Blink Reformat4c46d092018-04-07 15:32:37415 section.addKey(inspectElementModeShortcuts[0], Common.UIString('Select node to inspect'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34416 }
Blink Reformat4c46d092018-04-07 15:32:37417
418 const openResourceShortcut = UI.KeyboardShortcut.makeDescriptor('p', UI.KeyboardShortcut.Modifiers.CtrlOrMeta);
419 section.addKey(openResourceShortcut, Common.UIString('Go to source'));
420
421 if (Host.isMac()) {
422 keys = [
423 shortcut.makeDescriptor('g', shortcut.Modifiers.Meta),
424 shortcut.makeDescriptor('g', shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
425 ];
426 section.addRelatedKeys(keys, Common.UIString('Find next/previous'));
427 }
428 }
429
430 _postDocumentKeyDown(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34431 if (!event.handled) {
Joel Einbindera66e5bf2018-05-31 01:26:37432 UI.shortcutRegistry.handleShortcut(event);
Tim van der Lippe1d6e57a2019-09-30 11:55:34433 }
Blink Reformat4c46d092018-04-07 15:32:37434 }
435
436 /**
437 * @param {!Event} event
438 */
439 _redispatchClipboardEvent(event) {
440 const eventCopy = new CustomEvent('clipboard-' + event.type, {bubbles: true});
441 eventCopy['original'] = event;
442 const document = event.target && event.target.ownerDocument;
443 const target = document ? document.deepActiveElement() : null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34444 if (target) {
Blink Reformat4c46d092018-04-07 15:32:37445 target.dispatchEvent(eventCopy);
Tim van der Lippe1d6e57a2019-09-30 11:55:34446 }
447 if (eventCopy.handled) {
Blink Reformat4c46d092018-04-07 15:32:37448 event.preventDefault();
Tim van der Lippe1d6e57a2019-09-30 11:55:34449 }
Blink Reformat4c46d092018-04-07 15:32:37450 }
451
452 _contextMenuEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34453 if (event.handled || event.target.classList.contains('popup-glasspane')) {
Blink Reformat4c46d092018-04-07 15:32:37454 event.preventDefault();
Tim van der Lippe1d6e57a2019-09-30 11:55:34455 }
Blink Reformat4c46d092018-04-07 15:32:37456 }
457
458 /**
459 * @param {!Document} document
460 */
461 _addMainEventListeners(document) {
462 document.addEventListener('keydown', this._postDocumentKeyDown.bind(this), false);
463 document.addEventListener('beforecopy', this._redispatchClipboardEvent.bind(this), true);
464 document.addEventListener('copy', this._redispatchClipboardEvent.bind(this), false);
465 document.addEventListener('cut', this._redispatchClipboardEvent.bind(this), false);
466 document.addEventListener('paste', this._redispatchClipboardEvent.bind(this), false);
467 document.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), true);
468 }
469
470 _onSuspendStateChanged() {
471 const suspended = SDK.targetManager.allTargetsSuspended();
472 UI.inspectorView.onSuspendStateChanged(suspended);
473 }
Paul Lewisc1d99fa2019-12-10 16:26:28474}
Blink Reformat4c46d092018-04-07 15:32:37475
476/**
477 * @implements {UI.ActionDelegate}
478 * @unrestricted
479 */
Paul Lewisc1d99fa2019-12-10 16:26:28480export class ZoomActionDelegate {
Blink Reformat4c46d092018-04-07 15:32:37481 /**
482 * @override
483 * @param {!UI.Context} context
484 * @param {string} actionId
485 * @return {boolean}
486 */
487 handleAction(context, actionId) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58488 if (Host.InspectorFrontendHost.isHostedMode()) {
Blink Reformat4c46d092018-04-07 15:32:37489 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34490 }
Blink Reformat4c46d092018-04-07 15:32:37491
492 switch (actionId) {
493 case 'main.zoom-in':
Tim van der Lippe50cfa9b2019-10-01 10:40:58494 Host.InspectorFrontendHost.zoomIn();
Blink Reformat4c46d092018-04-07 15:32:37495 return true;
496 case 'main.zoom-out':
Tim van der Lippe50cfa9b2019-10-01 10:40:58497 Host.InspectorFrontendHost.zoomOut();
Blink Reformat4c46d092018-04-07 15:32:37498 return true;
499 case 'main.zoom-reset':
Tim van der Lippe50cfa9b2019-10-01 10:40:58500 Host.InspectorFrontendHost.resetZoom();
Blink Reformat4c46d092018-04-07 15:32:37501 return true;
502 }
503 return false;
504 }
Paul Lewisc1d99fa2019-12-10 16:26:28505}
Blink Reformat4c46d092018-04-07 15:32:37506
507/**
508 * @implements {UI.ActionDelegate}
509 * @unrestricted
510 */
Paul Lewisc1d99fa2019-12-10 16:26:28511export class SearchActionDelegate {
Blink Reformat4c46d092018-04-07 15:32:37512 /**
513 * @override
514 * @param {!UI.Context} context
515 * @param {string} actionId
516 * @return {boolean}
517 * @suppressGlobalPropertiesCheck
518 */
519 handleAction(context, actionId) {
Mandy Chenc1c5bec2019-12-10 19:11:31520 let searchableView = UI.SearchableView.fromElement(document.deepActiveElement());
Tim van der Lippe1d6e57a2019-09-30 11:55:34521 if (!searchableView) {
Mandy Chenc1c5bec2019-12-10 19:11:31522 const currentPanel = UI.inspectorView.currentPanelDeprecated();
523 if (currentPanel) {
524 searchableView = currentPanel.searchableView();
525 }
526 if (!searchableView) {
527 return false;
528 }
Tim van der Lippe1d6e57a2019-09-30 11:55:34529 }
Blink Reformat4c46d092018-04-07 15:32:37530 switch (actionId) {
531 case 'main.search-in-panel.find':
532 return searchableView.handleFindShortcut();
533 case 'main.search-in-panel.cancel':
534 return searchableView.handleCancelSearchShortcut();
535 case 'main.search-in-panel.find-next':
536 return searchableView.handleFindNextShortcut();
537 case 'main.search-in-panel.find-previous':
538 return searchableView.handleFindPreviousShortcut();
539 }
540 return false;
541 }
Paul Lewisc1d99fa2019-12-10 16:26:28542}
Blink Reformat4c46d092018-04-07 15:32:37543
544/**
545 * @implements {UI.ToolbarItem.Provider}
546 */
Paul Lewisc1d99fa2019-12-10 16:26:28547export class MainMenuItem {
Blink Reformat4c46d092018-04-07 15:32:37548 constructor() {
549 this._item = new UI.ToolbarMenuButton(this._handleContextMenu.bind(this), true);
550 this._item.setTitle(Common.UIString('Customize and control DevTools'));
551 }
552
553 /**
554 * @override
555 * @return {?UI.ToolbarItem}
556 */
557 item() {
558 return this._item;
559 }
560
561 /**
562 * @param {!UI.ContextMenu} contextMenu
563 */
564 _handleContextMenu(contextMenu) {
565 if (Components.dockController.canDock()) {
566 const dockItemElement = createElementWithClass('div', 'flex-centered flex-auto');
Joel Einbinder57b9fad2019-02-08 23:31:35567 dockItemElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37568 const titleElement = dockItemElement.createChild('span', 'flex-auto');
569 titleElement.textContent = Common.UIString('Dock side');
570 const toggleDockSideShorcuts = UI.shortcutRegistry.shortcutDescriptorsForAction('main.toggle-dock');
571 titleElement.title = Common.UIString(
572 'Placement of DevTools relative to the page. (%s to restore last position)', toggleDockSideShorcuts[0].name);
573 dockItemElement.appendChild(titleElement);
574 const dockItemToolbar = new UI.Toolbar('', dockItemElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34575 if (Host.isMac() && !UI.themeSupport.hasTheme()) {
Joel Einbinder9a6bead2018-08-06 18:02:35576 dockItemToolbar.makeBlueOnHover();
Tim van der Lippe1d6e57a2019-09-30 11:55:34577 }
Blink Reformat4c46d092018-04-07 15:32:37578 const undock = new UI.ToolbarToggle(Common.UIString('Undock into separate window'), 'largeicon-undock');
579 const bottom = new UI.ToolbarToggle(Common.UIString('Dock to bottom'), 'largeicon-dock-to-bottom');
580 const right = new UI.ToolbarToggle(Common.UIString('Dock to right'), 'largeicon-dock-to-right');
581 const left = new UI.ToolbarToggle(Common.UIString('Dock to left'), 'largeicon-dock-to-left');
582 undock.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
583 bottom.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
584 right.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
585 left.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
586 undock.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35587 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.Undocked));
Blink Reformat4c46d092018-04-07 15:32:37588 bottom.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35589 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.DockedToBottom));
Blink Reformat4c46d092018-04-07 15:32:37590 right.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35591 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.DockedToRight));
Blink Reformat4c46d092018-04-07 15:32:37592 left.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35593 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.DockedToLeft));
Blink Reformat4c46d092018-04-07 15:32:37594 undock.setToggled(Components.dockController.dockSide() === Components.DockController.State.Undocked);
595 bottom.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToBottom);
596 right.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToRight);
597 left.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToLeft);
598 dockItemToolbar.appendToolbarItem(undock);
599 dockItemToolbar.appendToolbarItem(left);
600 dockItemToolbar.appendToolbarItem(bottom);
601 dockItemToolbar.appendToolbarItem(right);
Joel Einbinder57b9fad2019-02-08 23:31:35602 dockItemElement.addEventListener('keydown', event => {
603 let dir = 0;
Tim van der Lippe1d6e57a2019-09-30 11:55:34604 if (event.key === 'ArrowLeft') {
Joel Einbinder57b9fad2019-02-08 23:31:35605 dir = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:34606 } else if (event.key === 'ArrowRight') {
Joel Einbinder57b9fad2019-02-08 23:31:35607 dir = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:34608 } else {
Joel Einbinder57b9fad2019-02-08 23:31:35609 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34610 }
Joel Einbinder57b9fad2019-02-08 23:31:35611
612 const buttons = [undock, left, bottom, right];
613 let index = buttons.findIndex(button => button.element.hasFocus());
614 index = Number.constrain(index + dir, 0, buttons.length - 1);
615
616 buttons[index].element.focus();
617 event.consume(true);
618 });
Blink Reformat4c46d092018-04-07 15:32:37619 contextMenu.headerSection().appendCustomItem(dockItemElement);
620 }
621
Jan Scheffler53de0572019-10-16 12:31:18622
623 const button = this._item.element;
624
Blink Reformat4c46d092018-04-07 15:32:37625 /**
626 * @param {string} side
Jan Scheffler53de0572019-10-16 12:31:18627 * @suppressGlobalPropertiesCheck
Blink Reformat4c46d092018-04-07 15:32:37628 */
629 function setDockSide(side) {
Jan Scheffler53de0572019-10-16 12:31:18630 const hadKeyboardFocus = document.deepActiveElement().hasAttribute('data-keyboard-focus');
631 Components.dockController.once(Components.DockController.Events.AfterDockSideChanged).then(() => {
632 button.focus();
633 if (hadKeyboardFocus) {
634 UI.markAsFocusedByKeyboard(button);
635 }
636 });
Blink Reformat4c46d092018-04-07 15:32:37637 Components.dockController.setDockSide(side);
638 contextMenu.discard();
639 }
640
641 if (Components.dockController.dockSide() === Components.DockController.State.Undocked &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34642 SDK.targetManager.mainTarget() && SDK.targetManager.mainTarget().type() === SDK.Target.Type.Frame) {
Blink Reformat4c46d092018-04-07 15:32:37643 contextMenu.defaultSection().appendAction('inspector_main.focus-debuggee', Common.UIString('Focus debuggee'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34644 }
Blink Reformat4c46d092018-04-07 15:32:37645
646 contextMenu.defaultSection().appendAction(
647 'main.toggle-drawer',
648 UI.inspectorView.drawerVisible() ? Common.UIString('Hide console drawer') :
649 Common.UIString('Show console drawer'));
650 contextMenu.appendItemsAtLocation('mainMenu');
651 const moreTools = contextMenu.defaultSection().appendSubMenuItem(Common.UIString('More tools'));
652 const extensions = self.runtime.extensions('view', undefined, true);
653 for (const extension of extensions) {
654 const descriptor = extension.descriptor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34655 if (descriptor['persistence'] !== 'closeable') {
Blink Reformat4c46d092018-04-07 15:32:37656 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34657 }
658 if (descriptor['location'] !== 'drawer-view' && descriptor['location'] !== 'panel') {
Blink Reformat4c46d092018-04-07 15:32:37659 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34660 }
Blink Reformat4c46d092018-04-07 15:32:37661 moreTools.defaultSection().appendItem(
662 extension.title(), UI.viewManager.showView.bind(UI.viewManager, descriptor['id']));
663 }
664
665 const helpSubMenu = contextMenu.footerSection().appendSubMenuItem(Common.UIString('Help'));
666 helpSubMenu.appendItemsAtLocation('mainMenuHelp');
667 }
Paul Lewisc1d99fa2019-12-10 16:26:28668}
Blink Reformat4c46d092018-04-07 15:32:37669
670/**
671 * @unrestricted
672 */
Paul Lewisc1d99fa2019-12-10 16:26:28673export class PauseListener {
Blink Reformat4c46d092018-04-07 15:32:37674 constructor() {
675 SDK.targetManager.addModelListener(
676 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
677 }
678
679 /**
680 * @param {!Common.Event} event
681 */
682 _debuggerPaused(event) {
683 SDK.targetManager.removeModelListener(
684 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
685 const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
686 const debuggerPausedDetails = debuggerModel.debuggerPausedDetails();
687 UI.context.setFlavor(SDK.Target, debuggerModel.target());
688 Common.Revealer.reveal(debuggerPausedDetails);
689 }
Paul Lewisc1d99fa2019-12-10 16:26:28690}
Blink Reformat4c46d092018-04-07 15:32:37691
Tim van der Lippe4221a1a2019-11-05 12:54:17692/**
693 * @param {string} method
694 * @param {?Object} params
695 * @return {!Promise}
696 */
Paul Lewisc1d99fa2019-12-10 16:26:28697export function sendOverProtocol(method, params) {
Tim van der Lippe4221a1a2019-11-05 12:54:17698 return new Promise((resolve, reject) => {
699 Protocol.test.sendRawMessage(method, params, (err, ...results) => {
700 if (err) {
701 return reject(err);
702 }
703 return resolve(results);
704 });
705 });
Paul Lewisc1d99fa2019-12-10 16:26:28706}
Tim van der Lippe4221a1a2019-11-05 12:54:17707
708/**
709 * @implements {UI.ActionDelegate}
710 * @unrestricted
711 */
Paul Lewisc1d99fa2019-12-10 16:26:28712export class ReloadActionDelegate {
Tim van der Lippe4221a1a2019-11-05 12:54:17713 /**
714 * @override
715 * @param {!UI.Context} context
716 * @param {string} actionId
717 * @return {boolean}
718 */
719 handleAction(context, actionId) {
720 switch (actionId) {
721 case 'main.debug-reload':
722 Components.reload();
723 return true;
724 }
725 return false;
726 }
Paul Lewisc1d99fa2019-12-10 16:26:28727}
Tim van der Lippe4221a1a2019-11-05 12:54:17728
Paul Lewisc1d99fa2019-12-10 16:26:28729new MainImpl();