blob: e7a5ec1b870a0b4a96dfa69022505bb41a04aa1d [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
31/**
32 * @unrestricted
33 */
34Main.Main = class {
35 /**
36 * @suppressGlobalPropertiesCheck
37 */
38 constructor() {
39 Main.Main._instanceForTest = this;
40 runOnWindowLoad(this._loaded.bind(this));
41 }
42
43 /**
44 * @param {string} label
45 */
46 static time(label) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3447 if (Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:3748 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3449 }
Blink Reformat4c46d092018-04-07 15:32:3750 console.time(label);
51 }
52
53 /**
54 * @param {string} label
55 */
56 static timeEnd(label) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3457 if (Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:3758 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3459 }
Blink Reformat4c46d092018-04-07 15:32:3760 console.timeEnd(label);
61 }
62
63 async _loaded() {
64 console.timeStamp('Main._loaded');
Tim van der Lippe99e59b82019-09-30 20:00:5965 await Root.Runtime.appStarted();
66 Root.Runtime.setPlatform(Host.platform());
67 Root.Runtime.setL10nCallback(ls);
Tim van der Lippe50cfa9b2019-10-01 10:40:5868 Host.InspectorFrontendHost.getPreferences(this._gotPreferences.bind(this));
Blink Reformat4c46d092018-04-07 15:32:3769 }
70
71 /**
72 * @param {!Object<string, string>} prefs
73 */
74 _gotPreferences(prefs) {
75 console.timeStamp('Main._gotPreferences');
Tim van der Lippe1d6e57a2019-09-30 11:55:3476 if (Host.isUnderTest(prefs)) {
Blink Reformat4c46d092018-04-07 15:32:3777 self.runtime.useTestBase();
Tim van der Lippe1d6e57a2019-09-30 11:55:3478 }
Blink Reformat4c46d092018-04-07 15:32:3779 this._createSettings(prefs);
80 this._createAppUI();
81 }
82
83 /**
84 * @param {!Object<string, string>} prefs
85 * Note: this function is called from testSettings in Tests.js.
86 */
87 _createSettings(prefs) {
88 this._initializeExperiments();
89 let storagePrefix = '';
Tim van der Lippe1d6e57a2019-09-30 11:55:3490 if (Host.isCustomDevtoolsFrontend()) {
Blink Reformat4c46d092018-04-07 15:32:3791 storagePrefix = '__custom__';
Tim van der Lippe99e59b82019-09-30 20:00:5992 } else if (
93 !Root.Runtime.queryParam('can_dock') && !!Root.Runtime.queryParam('debugFrontend') && !Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:3794 storagePrefix = '__bundled__';
Tim van der Lippe1d6e57a2019-09-30 11:55:3495 }
Blink Reformat4c46d092018-04-07 15:32:3796
97 let localStorage;
98 if (!Host.isUnderTest() && window.localStorage) {
99 localStorage = new Common.SettingsStorage(
100 window.localStorage, undefined, undefined, () => window.localStorage.clear(), storagePrefix);
101 } else {
102 localStorage = new Common.SettingsStorage({}, undefined, undefined, undefined, storagePrefix);
103 }
104 const globalStorage = new Common.SettingsStorage(
Tim van der Lippe50cfa9b2019-10-01 10:40:58105 prefs, Host.InspectorFrontendHost.setPreference, Host.InspectorFrontendHost.removePreference,
106 Host.InspectorFrontendHost.clearPreferences, storagePrefix);
Blink Reformat4c46d092018-04-07 15:32:37107 Common.settings = new Common.Settings(globalStorage, localStorage);
Tim van der Lippe1d6e57a2019-09-30 11:55:34108 if (!Host.isUnderTest()) {
Blink Reformat4c46d092018-04-07 15:32:37109 new Common.VersionController().updateVersion();
Tim van der Lippe1d6e57a2019-09-30 11:55:34110 }
Blink Reformat4c46d092018-04-07 15:32:37111 }
112
113 _initializeExperiments() {
114 // Keep this sorted alphabetically: both keys and values.
Tim van der Lippe99e59b82019-09-30 20:00:59115 Root.Runtime.experiments.register('applyCustomStylesheet', 'Allow custom UI themes');
116 Root.Runtime.experiments.register('captureNodeCreationStacks', 'Capture node creation stacks');
117 Root.Runtime.experiments.register('sourcesPrettyPrint', 'Automatically pretty print in the Sources Panel');
118 Root.Runtime.experiments.register('backgroundServices', 'Background web platform feature events', true);
119 Root.Runtime.experiments.register(
120 'backgroundServicesNotifications', 'Background services section for Notifications');
121 Root.Runtime.experiments.register(
122 'backgroundServicesPaymentHandler', 'Background services section for Payment Handler');
123 Root.Runtime.experiments.register(
124 'backgroundServicesPushMessaging', 'Background services section for Push Messaging');
125 Root.Runtime.experiments.register(
Rayan Kanso54809672019-07-24 18:40:28126 'backgroundServicesPeriodicBackgroundSync', 'Background services section for Periodic Background Sync');
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');
139 Root.Runtime.experiments.register('splitInDrawer', 'Split in drawer', true);
140 Root.Runtime.experiments.register('spotlight', 'Spotlight', true);
141 Root.Runtime.experiments.register('terminalInDrawer', 'Terminal in drawer', true);
Blink Reformat4c46d092018-04-07 15:32:37142
143 // Timeline
Tim van der Lippe99e59b82019-09-30 20:00:59144 Root.Runtime.experiments.register('timelineEventInitiators', 'Timeline: event initiators');
145 Root.Runtime.experiments.register('timelineFlowEvents', 'Timeline: flow events', true);
146 Root.Runtime.experiments.register('timelineInvalidationTracking', 'Timeline: invalidation tracking', true);
147 Root.Runtime.experiments.register('timelineShowAllEvents', 'Timeline: show all events', true);
148 Root.Runtime.experiments.register(
149 'timelineV8RuntimeCallStats', 'Timeline: V8 Runtime Call Stats on Timeline', true);
150 Root.Runtime.experiments.register('timelineWebGL', 'Timeline: WebGL-based flamechart');
Blink Reformat4c46d092018-04-07 15:32:37151
Tim van der Lippe99e59b82019-09-30 20:00:59152 Root.Runtime.experiments.cleanUpStaleExperiments();
153 const enabledExperiments = Root.Runtime.queryParam('enabledExperiments');
Tim van der Lippe1d6e57a2019-09-30 11:55:34154 if (enabledExperiments) {
Tim van der Lippe99e59b82019-09-30 20:00:59155 Root.Runtime.experiments.setServerEnabledExperiments(enabledExperiments.split(';'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34156 }
Tim van der Lippe99e59b82019-09-30 20:00:59157 Root.Runtime.experiments.setDefaultExperiments([
Rayan Kanso93bacf72019-08-28 12:33:23158 'backgroundServices',
159 'backgroundServicesNotifications',
160 'backgroundServicesPushMessaging',
161 'backgroundServicesPaymentHandler',
162 ]);
Alexei Filippovfdfefe02019-03-09 00:33:24163
Tim van der Lippe99e59b82019-09-30 20:00:59164 if (Host.isUnderTest() && Root.Runtime.queryParam('test').includes('live-line-level-heap-profile.js')) {
165 Root.Runtime.experiments.enableForTest('liveHeapProfile');
Tim van der Lippe1d6e57a2019-09-30 11:55:34166 }
Blink Reformat4c46d092018-04-07 15:32:37167 }
168
169 /**
170 * @suppressGlobalPropertiesCheck
171 */
172 async _createAppUI() {
173 Main.Main.time('Main._createAppUI');
174
175 UI.viewManager = new UI.ViewManager();
176
177 // Request filesystems early, we won't create connections until callback is fired. Things will happen in parallel.
178 Persistence.isolatedFileSystemManager = new Persistence.IsolatedFileSystemManager();
179
Erik Luo9adba992019-06-26 01:17:52180 const themeSetting = Common.settings.createSetting('uiTheme', 'systemPreferred');
Blink Reformat4c46d092018-04-07 15:32:37181 UI.initializeUIUtils(document, themeSetting);
182 themeSetting.addChangeListener(Components.reload.bind(Components));
183
184 UI.installComponentRootStyles(/** @type {!Element} */ (document.body));
185
186 this._addMainEventListeners(document);
187
Tim van der Lippe99e59b82019-09-30 20:00:59188 const canDock = !!Root.Runtime.queryParam('can_dock');
Tim van der Lippe50cfa9b2019-10-01 10:40:58189 UI.zoomManager = new UI.ZoomManager(window, Host.InspectorFrontendHost);
Blink Reformat4c46d092018-04-07 15:32:37190 UI.inspectorView = UI.InspectorView.instance();
191 UI.ContextMenu.initialize();
192 UI.ContextMenu.installHandler(document);
193 UI.Tooltip.installHandler(document);
194 Components.dockController = new Components.DockController(canDock);
195 SDK.consoleModel = new SDK.ConsoleModel();
196 SDK.multitargetNetworkManager = new SDK.MultitargetNetworkManager();
197 SDK.domDebuggerManager = new SDK.DOMDebuggerManager();
198 SDK.targetManager.addEventListener(
199 SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged.bind(this));
200
201 UI.shortcutsScreen = new UI.ShortcutsScreen();
202 // set order of some sections explicitly
203 UI.shortcutsScreen.section(Common.UIString('Elements Panel'));
204 UI.shortcutsScreen.section(Common.UIString('Styles Pane'));
205 UI.shortcutsScreen.section(Common.UIString('Debugger'));
206 UI.shortcutsScreen.section(Common.UIString('Console'));
207
208 Workspace.fileManager = new Workspace.FileManager();
209 Workspace.workspace = new Workspace.Workspace();
210
211 Bindings.networkProjectManager = new Bindings.NetworkProjectManager();
212 Bindings.resourceMapping = new Bindings.ResourceMapping(SDK.targetManager, Workspace.workspace);
213 new Bindings.PresentationConsoleMessageManager();
214 Bindings.cssWorkspaceBinding = new Bindings.CSSWorkspaceBinding(SDK.targetManager, Workspace.workspace);
215 Bindings.debuggerWorkspaceBinding = new Bindings.DebuggerWorkspaceBinding(SDK.targetManager, Workspace.workspace);
216 Bindings.breakpointManager =
217 new Bindings.BreakpointManager(Workspace.workspace, SDK.targetManager, Bindings.debuggerWorkspaceBinding);
218 Extensions.extensionServer = new Extensions.ExtensionServer();
219
220 new Persistence.FileSystemWorkspaceBinding(Persistence.isolatedFileSystemManager, Workspace.workspace);
221 Persistence.persistence = new Persistence.Persistence(Workspace.workspace, Bindings.breakpointManager);
222 Persistence.networkPersistenceManager = new Persistence.NetworkPersistenceManager(Workspace.workspace);
223
224 new Main.ExecutionContextSelector(SDK.targetManager, UI.context);
225 Bindings.blackboxManager = new Bindings.BlackboxManager(Bindings.debuggerWorkspaceBinding);
226
227 new Main.Main.PauseListener();
228
229 UI.actionRegistry = new UI.ActionRegistry();
230 UI.shortcutRegistry = new UI.ShortcutRegistry(UI.actionRegistry, document);
231 UI.ShortcutsScreen.registerShortcuts();
232 this._registerForwardedShortcuts();
233 this._registerMessageSinkListener();
234
235 Main.Main.timeEnd('Main._createAppUI');
236 this._showAppUI(await self.runtime.extension(Common.AppProvider).instance());
237 }
238
239 /**
240 * @param {!Object} appProvider
241 * @suppressGlobalPropertiesCheck
242 */
243 _showAppUI(appProvider) {
244 Main.Main.time('Main._showAppUI');
245 const app = /** @type {!Common.AppProvider} */ (appProvider).createApp();
246 // It is important to kick controller lifetime after apps are instantiated.
247 Components.dockController.initialize();
248 app.presentUI(document);
249
250 const toggleSearchNodeAction = UI.actionRegistry.action('elements.toggle-element-search');
251 // TODO: we should not access actions from other modules.
252 if (toggleSearchNodeAction) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58253 Host.InspectorFrontendHost.events.addEventListener(
Tim van der Lippe7b190162019-09-27 15:10:44254 Host.InspectorFrontendHostAPI.Events.EnterInspectElementMode,
Blink Reformat4c46d092018-04-07 15:32:37255 toggleSearchNodeAction.execute.bind(toggleSearchNodeAction), this);
256 }
Tim van der Lippe50cfa9b2019-10-01 10:40:58257 Host.InspectorFrontendHost.events.addEventListener(
Tim van der Lippe7b190162019-09-27 15:10:44258 Host.InspectorFrontendHostAPI.Events.RevealSourceLine, this._revealSourceLine, this);
Blink Reformat4c46d092018-04-07 15:32:37259
260 UI.inspectorView.createToolbars();
Tim van der Lippe50cfa9b2019-10-01 10:40:58261 Host.InspectorFrontendHost.loadCompleted();
Blink Reformat4c46d092018-04-07 15:32:37262
263 const extensions = self.runtime.extensions(Common.QueryParamHandler);
264 for (const extension of extensions) {
Tim van der Lippe99e59b82019-09-30 20:00:59265 const value = Root.Runtime.queryParam(extension.descriptor()['name']);
Tim van der Lippe1d6e57a2019-09-30 11:55:34266 if (value !== null) {
Blink Reformat4c46d092018-04-07 15:32:37267 extension.instance().then(handleQueryParam.bind(null, value));
Tim van der Lippe1d6e57a2019-09-30 11:55:34268 }
Blink Reformat4c46d092018-04-07 15:32:37269 }
270
271 /**
272 * @param {string} value
273 * @param {!Common.QueryParamHandler} handler
274 */
275 function handleQueryParam(value, handler) {
276 handler.handleQueryParam(value);
277 }
278
279 // Allow UI cycles to repaint prior to creating connection.
280 setTimeout(this._initializeTarget.bind(this), 0);
281 Main.Main.timeEnd('Main._showAppUI');
282 }
283
284 async _initializeTarget() {
285 Main.Main.time('Main._initializeTarget');
286 const instances =
287 await Promise.all(self.runtime.extensions('early-initialization').map(extension => extension.instance()));
Tim van der Lippe1d6e57a2019-09-30 11:55:34288 for (const instance of instances) {
Pavel Feldman07ef9722018-12-13 23:52:22289 await /** @type {!Common.Runnable} */ (instance).run();
Tim van der Lippe1d6e57a2019-09-30 11:55:34290 }
Blink Reformat4c46d092018-04-07 15:32:37291 // Used for browser tests.
Tim van der Lippe50cfa9b2019-10-01 10:40:58292 Host.InspectorFrontendHost.readyForTest();
Blink Reformat4c46d092018-04-07 15:32:37293 // Asynchronously run the extensions.
294 setTimeout(this._lateInitialization.bind(this), 100);
295 Main.Main.timeEnd('Main._initializeTarget');
296 }
297
298 _lateInitialization() {
299 Main.Main.time('Main._lateInitialization');
300 this._registerShortcuts();
301 Extensions.extensionServer.initializeExtensions();
Alexei Filippov19be5102019-04-16 20:40:24302 const extensions = self.runtime.extensions('late-initialization');
303 const promises = [];
304 for (const extension of extensions) {
305 const setting = extension.descriptor()['setting'];
306 if (!setting || Common.settings.moduleSetting(setting).get()) {
307 promises.push(extension.instance().then(instance => (/** @type {!Common.Runnable} */ (instance)).run()));
308 continue;
309 }
310 /**
311 * @param {!Common.Event} event
312 */
313 async function changeListener(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34314 if (!event.data) {
Alexei Filippov19be5102019-04-16 20:40:24315 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34316 }
Alexei Filippov19be5102019-04-16 20:40:24317 Common.settings.moduleSetting(setting).removeChangeListener(changeListener);
318 (/** @type {!Common.Runnable} */ (await extension.instance())).run();
319 }
320 Common.settings.moduleSetting(setting).addChangeListener(changeListener);
321 }
322 this._lateInitDonePromise = Promise.all(promises);
Blink Reformat4c46d092018-04-07 15:32:37323 Main.Main.timeEnd('Main._lateInitialization');
324 }
325
Alexei Filippov19be5102019-04-16 20:40:24326 /**
327 * @return {!Promise}
328 */
329 lateInitDonePromiseForTest() {
330 return this._lateInitDonePromise;
331 }
332
Blink Reformat4c46d092018-04-07 15:32:37333 _registerForwardedShortcuts() {
334 /** @const */ const forwardedActions = [
335 'main.toggle-dock', 'debugger.toggle-breakpoints-active', 'debugger.toggle-pause', 'commandMenu.show',
336 'console.show'
337 ];
338 const actionKeys =
339 UI.shortcutRegistry.keysForActions(forwardedActions).map(UI.KeyboardShortcut.keyCodeAndModifiersFromKey);
Tim van der Lippe50cfa9b2019-10-01 10:40:58340 Host.InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));
Blink Reformat4c46d092018-04-07 15:32:37341 }
342
343 _registerMessageSinkListener() {
344 Common.console.addEventListener(Common.Console.Events.MessageAdded, messageAdded);
345
346 /**
347 * @param {!Common.Event} event
348 */
349 function messageAdded(event) {
350 const message = /** @type {!Common.Console.Message} */ (event.data);
Tim van der Lippe1d6e57a2019-09-30 11:55:34351 if (message.show) {
Blink Reformat4c46d092018-04-07 15:32:37352 Common.console.show();
Tim van der Lippe1d6e57a2019-09-30 11:55:34353 }
Blink Reformat4c46d092018-04-07 15:32:37354 }
355 }
356
357 /**
358 * @param {!Common.Event} event
359 */
360 _revealSourceLine(event) {
361 const url = /** @type {string} */ (event.data['url']);
362 const lineNumber = /** @type {number} */ (event.data['lineNumber']);
363 const columnNumber = /** @type {number} */ (event.data['columnNumber']);
364
365 const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
366 if (uiSourceCode) {
367 Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
368 return;
369 }
370
371 /**
372 * @param {!Common.Event} event
373 */
374 function listener(event) {
375 const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
376 if (uiSourceCode.url() === url) {
377 Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
378 Workspace.workspace.removeEventListener(Workspace.Workspace.Events.UISourceCodeAdded, listener);
379 }
380 }
381
382 Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, listener);
383 }
384
385 _registerShortcuts() {
386 const shortcut = UI.KeyboardShortcut;
387 const section = UI.shortcutsScreen.section(Common.UIString('All Panels'));
388 let keys = [
389 shortcut.makeDescriptor('[', shortcut.Modifiers.CtrlOrMeta),
390 shortcut.makeDescriptor(']', shortcut.Modifiers.CtrlOrMeta)
391 ];
392 section.addRelatedKeys(keys, Common.UIString('Go to the panel to the left/right'));
393
394 const toggleConsoleLabel = Common.UIString('Show console');
395 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
396 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), Common.UIString('Toggle drawer'));
397 if (Components.dockController.canDock()) {
398 section.addKey(
399 shortcut.makeDescriptor('M', shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift),
400 Common.UIString('Toggle device mode'));
401 section.addKey(
402 shortcut.makeDescriptor('D', shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift),
403 Common.UIString('Toggle dock side'));
404 }
405 section.addKey(shortcut.makeDescriptor('f', shortcut.Modifiers.CtrlOrMeta), Common.UIString('Search'));
406
407 const advancedSearchShortcutModifier = Host.isMac() ?
408 UI.KeyboardShortcut.Modifiers.Meta | UI.KeyboardShortcut.Modifiers.Alt :
409 UI.KeyboardShortcut.Modifiers.Ctrl | UI.KeyboardShortcut.Modifiers.Shift;
410 const advancedSearchShortcut = shortcut.makeDescriptor('f', advancedSearchShortcutModifier);
411 section.addKey(advancedSearchShortcut, Common.UIString('Search across all sources'));
412
413 const inspectElementModeShortcuts =
414 UI.shortcutRegistry.shortcutDescriptorsForAction('elements.toggle-element-search');
Tim van der Lippe1d6e57a2019-09-30 11:55:34415 if (inspectElementModeShortcuts.length) {
Blink Reformat4c46d092018-04-07 15:32:37416 section.addKey(inspectElementModeShortcuts[0], Common.UIString('Select node to inspect'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34417 }
Blink Reformat4c46d092018-04-07 15:32:37418
419 const openResourceShortcut = UI.KeyboardShortcut.makeDescriptor('p', UI.KeyboardShortcut.Modifiers.CtrlOrMeta);
420 section.addKey(openResourceShortcut, Common.UIString('Go to source'));
421
422 if (Host.isMac()) {
423 keys = [
424 shortcut.makeDescriptor('g', shortcut.Modifiers.Meta),
425 shortcut.makeDescriptor('g', shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
426 ];
427 section.addRelatedKeys(keys, Common.UIString('Find next/previous'));
428 }
429 }
430
431 _postDocumentKeyDown(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34432 if (!event.handled) {
Joel Einbindera66e5bf2018-05-31 01:26:37433 UI.shortcutRegistry.handleShortcut(event);
Tim van der Lippe1d6e57a2019-09-30 11:55:34434 }
Blink Reformat4c46d092018-04-07 15:32:37435 }
436
437 /**
438 * @param {!Event} event
439 */
440 _redispatchClipboardEvent(event) {
441 const eventCopy = new CustomEvent('clipboard-' + event.type, {bubbles: true});
442 eventCopy['original'] = event;
443 const document = event.target && event.target.ownerDocument;
444 const target = document ? document.deepActiveElement() : null;
Tim van der Lippe1d6e57a2019-09-30 11:55:34445 if (target) {
Blink Reformat4c46d092018-04-07 15:32:37446 target.dispatchEvent(eventCopy);
Tim van der Lippe1d6e57a2019-09-30 11:55:34447 }
448 if (eventCopy.handled) {
Blink Reformat4c46d092018-04-07 15:32:37449 event.preventDefault();
Tim van der Lippe1d6e57a2019-09-30 11:55:34450 }
Blink Reformat4c46d092018-04-07 15:32:37451 }
452
453 _contextMenuEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34454 if (event.handled || event.target.classList.contains('popup-glasspane')) {
Blink Reformat4c46d092018-04-07 15:32:37455 event.preventDefault();
Tim van der Lippe1d6e57a2019-09-30 11:55:34456 }
Blink Reformat4c46d092018-04-07 15:32:37457 }
458
459 /**
460 * @param {!Document} document
461 */
462 _addMainEventListeners(document) {
463 document.addEventListener('keydown', this._postDocumentKeyDown.bind(this), false);
464 document.addEventListener('beforecopy', this._redispatchClipboardEvent.bind(this), true);
465 document.addEventListener('copy', this._redispatchClipboardEvent.bind(this), false);
466 document.addEventListener('cut', this._redispatchClipboardEvent.bind(this), false);
467 document.addEventListener('paste', this._redispatchClipboardEvent.bind(this), false);
468 document.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), true);
469 }
470
471 _onSuspendStateChanged() {
472 const suspended = SDK.targetManager.allTargetsSuspended();
473 UI.inspectorView.onSuspendStateChanged(suspended);
474 }
475};
476
477/**
478 * @implements {UI.ActionDelegate}
479 * @unrestricted
480 */
481Main.Main.ZoomActionDelegate = class {
482 /**
483 * @override
484 * @param {!UI.Context} context
485 * @param {string} actionId
486 * @return {boolean}
487 */
488 handleAction(context, actionId) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58489 if (Host.InspectorFrontendHost.isHostedMode()) {
Blink Reformat4c46d092018-04-07 15:32:37490 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34491 }
Blink Reformat4c46d092018-04-07 15:32:37492
493 switch (actionId) {
494 case 'main.zoom-in':
Tim van der Lippe50cfa9b2019-10-01 10:40:58495 Host.InspectorFrontendHost.zoomIn();
Blink Reformat4c46d092018-04-07 15:32:37496 return true;
497 case 'main.zoom-out':
Tim van der Lippe50cfa9b2019-10-01 10:40:58498 Host.InspectorFrontendHost.zoomOut();
Blink Reformat4c46d092018-04-07 15:32:37499 return true;
500 case 'main.zoom-reset':
Tim van der Lippe50cfa9b2019-10-01 10:40:58501 Host.InspectorFrontendHost.resetZoom();
Blink Reformat4c46d092018-04-07 15:32:37502 return true;
503 }
504 return false;
505 }
506};
507
508/**
509 * @implements {UI.ActionDelegate}
510 * @unrestricted
511 */
512Main.Main.SearchActionDelegate = class {
513 /**
514 * @override
515 * @param {!UI.Context} context
516 * @param {string} actionId
517 * @return {boolean}
518 * @suppressGlobalPropertiesCheck
519 */
520 handleAction(context, actionId) {
521 const searchableView = UI.SearchableView.fromElement(document.deepActiveElement()) ||
522 UI.inspectorView.currentPanelDeprecated().searchableView();
Tim van der Lippe1d6e57a2019-09-30 11:55:34523 if (!searchableView) {
Blink Reformat4c46d092018-04-07 15:32:37524 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34525 }
Blink Reformat4c46d092018-04-07 15:32:37526 switch (actionId) {
527 case 'main.search-in-panel.find':
528 return searchableView.handleFindShortcut();
529 case 'main.search-in-panel.cancel':
530 return searchableView.handleCancelSearchShortcut();
531 case 'main.search-in-panel.find-next':
532 return searchableView.handleFindNextShortcut();
533 case 'main.search-in-panel.find-previous':
534 return searchableView.handleFindPreviousShortcut();
535 }
536 return false;
537 }
538};
539
540/**
541 * @implements {UI.ToolbarItem.Provider}
542 */
543Main.Main.MainMenuItem = class {
544 constructor() {
545 this._item = new UI.ToolbarMenuButton(this._handleContextMenu.bind(this), true);
546 this._item.setTitle(Common.UIString('Customize and control DevTools'));
547 }
548
549 /**
550 * @override
551 * @return {?UI.ToolbarItem}
552 */
553 item() {
554 return this._item;
555 }
556
557 /**
558 * @param {!UI.ContextMenu} contextMenu
559 */
560 _handleContextMenu(contextMenu) {
561 if (Components.dockController.canDock()) {
562 const dockItemElement = createElementWithClass('div', 'flex-centered flex-auto');
Joel Einbinder57b9fad2019-02-08 23:31:35563 dockItemElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:37564 const titleElement = dockItemElement.createChild('span', 'flex-auto');
565 titleElement.textContent = Common.UIString('Dock side');
566 const toggleDockSideShorcuts = UI.shortcutRegistry.shortcutDescriptorsForAction('main.toggle-dock');
567 titleElement.title = Common.UIString(
568 'Placement of DevTools relative to the page. (%s to restore last position)', toggleDockSideShorcuts[0].name);
569 dockItemElement.appendChild(titleElement);
570 const dockItemToolbar = new UI.Toolbar('', dockItemElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34571 if (Host.isMac() && !UI.themeSupport.hasTheme()) {
Joel Einbinder9a6bead2018-08-06 18:02:35572 dockItemToolbar.makeBlueOnHover();
Tim van der Lippe1d6e57a2019-09-30 11:55:34573 }
Blink Reformat4c46d092018-04-07 15:32:37574 const undock = new UI.ToolbarToggle(Common.UIString('Undock into separate window'), 'largeicon-undock');
575 const bottom = new UI.ToolbarToggle(Common.UIString('Dock to bottom'), 'largeicon-dock-to-bottom');
576 const right = new UI.ToolbarToggle(Common.UIString('Dock to right'), 'largeicon-dock-to-right');
577 const left = new UI.ToolbarToggle(Common.UIString('Dock to left'), 'largeicon-dock-to-left');
578 undock.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
579 bottom.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
580 right.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
581 left.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
582 undock.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35583 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.Undocked));
Blink Reformat4c46d092018-04-07 15:32:37584 bottom.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35585 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.DockedToBottom));
Blink Reformat4c46d092018-04-07 15:32:37586 right.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35587 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.DockedToRight));
Blink Reformat4c46d092018-04-07 15:32:37588 left.addEventListener(
Joel Einbinder57b9fad2019-02-08 23:31:35589 UI.ToolbarButton.Events.Click, setDockSide.bind(null, Components.DockController.State.DockedToLeft));
Blink Reformat4c46d092018-04-07 15:32:37590 undock.setToggled(Components.dockController.dockSide() === Components.DockController.State.Undocked);
591 bottom.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToBottom);
592 right.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToRight);
593 left.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToLeft);
594 dockItemToolbar.appendToolbarItem(undock);
595 dockItemToolbar.appendToolbarItem(left);
596 dockItemToolbar.appendToolbarItem(bottom);
597 dockItemToolbar.appendToolbarItem(right);
Joel Einbinder57b9fad2019-02-08 23:31:35598 dockItemElement.addEventListener('keydown', event => {
599 let dir = 0;
Tim van der Lippe1d6e57a2019-09-30 11:55:34600 if (event.key === 'ArrowLeft') {
Joel Einbinder57b9fad2019-02-08 23:31:35601 dir = -1;
Tim van der Lippe1d6e57a2019-09-30 11:55:34602 } else if (event.key === 'ArrowRight') {
Joel Einbinder57b9fad2019-02-08 23:31:35603 dir = 1;
Tim van der Lippe1d6e57a2019-09-30 11:55:34604 } else {
Joel Einbinder57b9fad2019-02-08 23:31:35605 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34606 }
Joel Einbinder57b9fad2019-02-08 23:31:35607
608 const buttons = [undock, left, bottom, right];
609 let index = buttons.findIndex(button => button.element.hasFocus());
610 index = Number.constrain(index + dir, 0, buttons.length - 1);
611
612 buttons[index].element.focus();
613 event.consume(true);
614 });
Blink Reformat4c46d092018-04-07 15:32:37615 contextMenu.headerSection().appendCustomItem(dockItemElement);
616 }
617
618 /**
619 * @param {string} side
620 */
621 function setDockSide(side) {
622 Components.dockController.setDockSide(side);
623 contextMenu.discard();
624 }
625
626 if (Components.dockController.dockSide() === Components.DockController.State.Undocked &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34627 SDK.targetManager.mainTarget() && SDK.targetManager.mainTarget().type() === SDK.Target.Type.Frame) {
Blink Reformat4c46d092018-04-07 15:32:37628 contextMenu.defaultSection().appendAction('inspector_main.focus-debuggee', Common.UIString('Focus debuggee'));
Tim van der Lippe1d6e57a2019-09-30 11:55:34629 }
Blink Reformat4c46d092018-04-07 15:32:37630
631 contextMenu.defaultSection().appendAction(
632 'main.toggle-drawer',
633 UI.inspectorView.drawerVisible() ? Common.UIString('Hide console drawer') :
634 Common.UIString('Show console drawer'));
635 contextMenu.appendItemsAtLocation('mainMenu');
636 const moreTools = contextMenu.defaultSection().appendSubMenuItem(Common.UIString('More tools'));
637 const extensions = self.runtime.extensions('view', undefined, true);
638 for (const extension of extensions) {
639 const descriptor = extension.descriptor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34640 if (descriptor['persistence'] !== 'closeable') {
Blink Reformat4c46d092018-04-07 15:32:37641 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34642 }
643 if (descriptor['location'] !== 'drawer-view' && descriptor['location'] !== 'panel') {
Blink Reformat4c46d092018-04-07 15:32:37644 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34645 }
Blink Reformat4c46d092018-04-07 15:32:37646 moreTools.defaultSection().appendItem(
647 extension.title(), UI.viewManager.showView.bind(UI.viewManager, descriptor['id']));
648 }
649
650 const helpSubMenu = contextMenu.footerSection().appendSubMenuItem(Common.UIString('Help'));
651 helpSubMenu.appendItemsAtLocation('mainMenuHelp');
652 }
653};
654
655/**
656 * @unrestricted
657 */
658Main.Main.PauseListener = class {
659 constructor() {
660 SDK.targetManager.addModelListener(
661 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
662 }
663
664 /**
665 * @param {!Common.Event} event
666 */
667 _debuggerPaused(event) {
668 SDK.targetManager.removeModelListener(
669 SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
670 const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
671 const debuggerPausedDetails = debuggerModel.debuggerPausedDetails();
672 UI.context.setFlavor(SDK.Target, debuggerModel.target());
673 Common.Revealer.reveal(debuggerPausedDetails);
674 }
675};
676
677/**
678 * @param {string} method
679 * @param {?Object} params
680 * @return {!Promise}
681 */
682Main.sendOverProtocol = function(method, params) {
683 return new Promise((resolve, reject) => {
Dmitry Gozman99d7a6c2018-11-12 17:55:11684 Protocol.test.sendRawMessage(method, params, (err, ...results) => {
Tim van der Lippe1d6e57a2019-09-30 11:55:34685 if (err) {
Blink Reformat4c46d092018-04-07 15:32:37686 return reject(err);
Tim van der Lippe1d6e57a2019-09-30 11:55:34687 }
Blink Reformat4c46d092018-04-07 15:32:37688 return resolve(results);
689 });
690 });
691};
692
693/**
694 * @implements {UI.ActionDelegate}
695 * @unrestricted
696 */
697Main.ReloadActionDelegate = class {
698 /**
699 * @override
700 * @param {!UI.Context} context
701 * @param {string} actionId
702 * @return {boolean}
703 */
704 handleAction(context, actionId) {
705 switch (actionId) {
706 case 'main.debug-reload':
707 Components.reload();
708 return true;
709 }
710 return false;
711 }
712};
713
714new Main.Main();