Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / main / Main.js
blob5ecd8c29d4c5459b5b46b8d744d55c351abb07c7
1 /*
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
4 * Copyright (C) 2009 Joseph Pecoraro
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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.
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.
31 /**
32 * @constructor
33 * @implements {InspectorAgent.Dispatcher}
34 * @implements {WebInspector.Console.UIDelegate}
35 * @suppressGlobalPropertiesCheck
37 WebInspector.Main = function()
39 WebInspector.console.setUIDelegate(this);
40 WebInspector.Main._instanceForTest = this;
41 runOnWindowLoad(this._loaded.bind(this));
44 WebInspector.Main.prototype = {
45 /**
46 * @override
47 * @return {!Promise.<undefined>}
49 showConsole: function()
51 return WebInspector.Revealer.revealPromise(WebInspector.console);
54 _loaded: function()
56 console.timeStamp("Main._loaded");
58 if (InspectorFrontendHost.isUnderTest())
59 self.runtime.useTestBase();
60 InspectorFrontendHost.getPreferences(this._gotPreferences.bind(this));
63 /**
64 * @param {!Object<string, string>} prefs
66 _gotPreferences: function(prefs)
68 console.timeStamp("Main._gotPreferences");
69 this._createSettings(prefs);
70 this._createAppUI();
73 /**
74 * @param {!Object<string, string>} prefs
75 * Note: this function is called from testSettings in Tests.js.
77 _createSettings: function(prefs)
79 // Patch settings from the URL param (for tests).
80 var settingsParam = Runtime.queryParam("settings");
81 if (settingsParam) {
82 try {
83 var settings = JSON.parse(window.decodeURI(settingsParam));
84 for (var key in settings)
85 prefs[key] = settings[key];
86 } catch(e) {
87 // Ignore malformed settings.
91 this._initializeExperiments(prefs);
93 /**
94 * @param {!Array<{name: string}>} changes
96 function trackPrefsObject(changes)
98 if (!Object.keys(prefs).length) {
99 InspectorFrontendHost.clearPreferences();
100 return;
103 for (var change of changes) {
104 var name = change.name;
105 if (name in prefs)
106 InspectorFrontendHost.setPreference(name, prefs[name]);
107 else
108 InspectorFrontendHost.removePreference(name);
112 Object.observe(prefs, trackPrefsObject);
113 WebInspector.settings = new WebInspector.Settings(prefs);
115 if (!InspectorFrontendHost.isUnderTest())
116 new WebInspector.VersionController().updateVersion();
120 * @param {!Object<string, string>} prefs
122 _initializeExperiments: function(prefs)
124 Runtime.experiments.register("accessibilityInspection", "Accessibility Inspection");
125 Runtime.experiments.register("animationInspection", "Animation Inspection");
126 Runtime.experiments.register("applyCustomStylesheet", "Allow custom UI themes");
127 Runtime.experiments.register("blackboxJSFramesOnTimeline", "Blackbox JavaScript frames on Timeline", true);
128 Runtime.experiments.register("colorContrastRatio", "Contrast ratio line in color picker", true);
129 Runtime.experiments.register("emptySourceMapAutoStepping", "Empty sourcemap auto-stepping");
130 Runtime.experiments.register("fileSystemInspection", "FileSystem inspection");
131 Runtime.experiments.register("gpuTimeline", "GPU data on timeline", true);
132 Runtime.experiments.register("inspectDevicesDialog", "Inspect devices dialog", true);
133 Runtime.experiments.register("inputEventsOnTimelineOverview", "Input events on Timeline overview", true);
134 Runtime.experiments.register("layersPanel", "Layers panel");
135 Runtime.experiments.register("layoutEditor", "Layout editor", true);
136 Runtime.experiments.register("materialDesign", "Material design");
137 Runtime.experiments.register("multipleTimelineViews", "Multiple main views on Timeline", true);
138 Runtime.experiments.register("networkRequestHeadersFilterInDetailsView", "Network request headers filter in details view", true);
139 Runtime.experiments.register("networkRequestsOnTimeline", "Network requests on Timeline", true);
140 Runtime.experiments.register("privateScriptInspection", "Private script inspection");
141 Runtime.experiments.register("promiseTracker", "Promise inspector");
142 Runtime.experiments.register("securityPanel", "Security panel");
143 Runtime.experiments.register("serviceWorkersInResources", "Service workers in Resources panel", true);
144 Runtime.experiments.register("showPrimaryLoadWaterfallInNetworkTimeline", "Show primary load waterfall in Network timeline", true);
145 Runtime.experiments.register("stepIntoAsync", "Step into async");
146 Runtime.experiments.register("timelineInvalidationTracking", "Timeline invalidation tracking", true);
147 Runtime.experiments.register("timelineTracingJSProfile", "Timeline tracing based JS profiler", true);
148 Runtime.experiments.register("timelineFlowEvents", "Timeline flow events", true);
150 Runtime.experiments.cleanUpStaleExperiments();
152 if (InspectorFrontendHost.isUnderTest()) {
153 var testPath = JSON.parse(prefs["testPath"] || "\"\"");
154 // Enable experiments for testing.
155 if (testPath.indexOf("debugger/promise") !== -1)
156 Runtime.experiments.enableForTest("promiseTracker");
157 if (testPath.indexOf("elements/") !== -1)
158 Runtime.experiments.enableForTest("animationInspection");
159 if (testPath.indexOf("layers/") !== -1)
160 Runtime.experiments.enableForTest("layersPanel");
161 if (testPath.indexOf("service-workers/") !== -1)
162 Runtime.experiments.enableForTest("serviceWorkersInResources");
163 if (testPath.indexOf("timeline/") !== -1 || testPath.indexOf("layers/") !== -1)
164 Runtime.experiments.enableForTest("layersPanel");
165 if (testPath.indexOf("security/") !== -1)
166 Runtime.experiments.enableForTest("securityPanel");
169 Runtime.experiments.setDefaultExperiments([
174 * @suppressGlobalPropertiesCheck
176 _createAppUI: function()
178 console.timeStamp("Main._createApp");
180 WebInspector.initializeUIUtils(window);
181 WebInspector.installComponentRootStyles(/** @type {!Element} */ (document.body));
183 this._addMainEventListeners(document);
185 var canDock = !!Runtime.queryParam("can_dock");
186 WebInspector.zoomManager = new WebInspector.ZoomManager(window, InspectorFrontendHost);
187 WebInspector.inspectorView = new WebInspector.InspectorView();
188 WebInspector.ContextMenu.initialize();
189 WebInspector.ContextMenu.installHandler(document);
190 WebInspector.Tooltip.installHandler(document);
191 WebInspector.dockController = new WebInspector.DockController(canDock);
192 WebInspector.overridesSupport = new WebInspector.OverridesSupport();
193 WebInspector.emulatedDevicesList = new WebInspector.EmulatedDevicesList();
194 WebInspector.multitargetConsoleModel = new WebInspector.MultitargetConsoleModel();
195 WebInspector.multitargetNetworkManager = new WebInspector.MultitargetNetworkManager();
197 WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
198 // set order of some sections explicitly
199 WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
200 WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane"));
201 WebInspector.shortcutsScreen.section(WebInspector.UIString("Debugger"));
202 WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
204 WebInspector.fileManager = new WebInspector.FileManager();
205 WebInspector.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager();
206 WebInspector.workspace = new WebInspector.Workspace(WebInspector.isolatedFileSystemManager.mapping());
207 WebInspector.networkMapping = new WebInspector.NetworkMapping(WebInspector.workspace, WebInspector.isolatedFileSystemManager.mapping());
208 WebInspector.networkProjectManager = new WebInspector.NetworkProjectManager(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkMapping);
209 WebInspector.presentationConsoleMessageHelper = new WebInspector.PresentationConsoleMessageHelper(WebInspector.workspace);
210 WebInspector.cssWorkspaceBinding = new WebInspector.CSSWorkspaceBinding(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkMapping);
211 WebInspector.debuggerWorkspaceBinding = new WebInspector.DebuggerWorkspaceBinding(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkMapping);
212 WebInspector.fileSystemWorkspaceBinding = new WebInspector.FileSystemWorkspaceBinding(WebInspector.isolatedFileSystemManager, WebInspector.workspace, WebInspector.networkMapping);
213 WebInspector.breakpointManager = new WebInspector.BreakpointManager(null, WebInspector.workspace, WebInspector.networkMapping, WebInspector.targetManager, WebInspector.debuggerWorkspaceBinding);
214 WebInspector.extensionServer = new WebInspector.ExtensionServer();
216 new WebInspector.OverlayController();
217 new WebInspector.ContentScriptProjectDecorator();
218 new WebInspector.ExecutionContextSelector(WebInspector.targetManager, WebInspector.context);
220 var autoselectPanel = WebInspector.UIString("auto");
221 var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
222 WebInspector.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
223 WebInspector.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
224 WebInspector.Linkifier.setLinkHandler(new WebInspector.HandlerRegistry.LinkHandler());
226 new WebInspector.WorkspaceController(WebInspector.workspace);
227 new WebInspector.RenderingOptions();
228 new WebInspector.Main.PauseListener();
229 new WebInspector.Main.InspectedNodeRevealer();
230 new WebInspector.NetworkPanelIndicator();
231 WebInspector.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
233 WebInspector.actionRegistry = new WebInspector.ActionRegistry();
234 WebInspector.shortcutRegistry = new WebInspector.ShortcutRegistry(WebInspector.actionRegistry, document);
235 WebInspector.ShortcutsScreen.registerShortcuts();
236 this._registerForwardedShortcuts();
237 this._registerMessageSinkListener();
239 var appExtension = self.runtime.extensions(WebInspector.AppProvider)[0];
240 appExtension.instancePromise().then(this._showAppUI.bind(this));
244 * @param {!Object} appProvider
245 * @suppressGlobalPropertiesCheck
247 _showAppUI: function(appProvider)
249 var app = /** @type {!WebInspector.AppProvider} */ (appProvider).createApp();
250 // It is important to kick controller lifetime after apps are instantiated.
251 WebInspector.dockController.initialize();
252 console.timeStamp("Main._presentUI");
253 app.presentUI(document);
255 if (!Runtime.queryParam("isSharedWorker"))
256 WebInspector.inspectElementModeController = new WebInspector.InspectElementModeController();
257 WebInspector.inspectorView.createToolbars();
258 InspectorFrontendHost.loadCompleted();
260 var extensions = self.runtime.extensions(WebInspector.QueryParamHandler);
261 for (var extension of extensions) {
262 var value = Runtime.queryParam(extension.descriptor()["name"]);
263 if (value !== null)
264 extension.instancePromise().then(handleQueryParam.bind(null, value));
266 // Give UI cycles to repaint, then proceed with creating connection.
267 setTimeout(this._createConnection.bind(this), 0);
270 * @param {string} value
271 * @param {!WebInspector.QueryParamHandler} handler
273 function handleQueryParam(value, handler)
275 handler.handleQueryParam(value);
279 _createConnection: function()
281 console.timeStamp("Main._createConnection");
282 InspectorBackend.loadFromJSONIfNeeded("../protocol.json");
284 if (Runtime.queryParam("ws")) {
285 var ws = "ws://" + Runtime.queryParam("ws");
286 InspectorBackendClass.WebSocketConnection.Create(ws, this._connectionEstablished.bind(this));
287 return;
290 if (!InspectorFrontendHost.isHostedMode()) {
291 this._connectionEstablished(new InspectorBackendClass.MainConnection());
292 return;
295 this._connectionEstablished(new InspectorBackendClass.StubConnection());
299 * @param {!InspectorBackendClass.Connection} connection
301 _connectionEstablished: function(connection)
303 console.timeStamp("Main._connectionEstablished");
304 connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected, onDisconnected);
307 * @param {!WebInspector.Event} event
309 function onDisconnected(event)
311 if (WebInspector._disconnectedScreenWithReasonWasShown)
312 return;
313 new WebInspector.RemoteDebuggingTerminatedScreen(event.data.reason).showModal();
316 InspectorBackend.setConnection(connection);
317 var targetType = Runtime.queryParam("isSharedWorker") ? WebInspector.Target.Type.ServiceWorker : WebInspector.Target.Type.Page;
318 WebInspector.targetManager.createTarget(WebInspector.UIString("Main"), targetType, connection, null, this._mainTargetCreated.bind(this));
322 * @param {?WebInspector.Target} target
324 _mainTargetCreated: function(target)
326 console.timeStamp("Main._mainTargetCreated");
327 this._mainTarget = /** @type {!WebInspector.Target} */(target);
328 this._registerShortcuts();
329 var main = this;
331 this._mainTarget.registerInspectorDispatcher(this);
332 InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ReloadInspectedPage, this._reloadInspectedPage, this);
334 if (this._mainTarget.isServiceWorker())
335 this._mainTarget.runtimeAgent().run();
337 WebInspector.overridesSupport.init(this._mainTarget, overridesReady);
339 function overridesReady()
341 if (!WebInspector.dockController.canDock() && WebInspector.overridesSupport.emulationEnabled())
342 WebInspector.inspectorView.showViewInDrawer("emulation", true);
344 target.inspectorAgent().enable(inspectorAgentEnableCallback);
347 function inspectorAgentEnableCallback()
349 console.timeStamp("Main.inspectorAgentEnableCallback");
350 WebInspector.notifications.dispatchEventToListeners(WebInspector.NotificationService.Events.InspectorAgentEnabledForTests);
351 // Asynchronously run the extensions.
352 setTimeout(lateInitialization, 0);
355 function lateInitialization()
357 WebInspector.extensionServer.initializeExtensions();
358 new WebInspector.FrontendWebSocketAPI();
362 _registerForwardedShortcuts: function()
364 /** @const */ var forwardedActions = ["main.reload", "main.hard-reload", "main.toggle-dock", "debugger.toggle-breakpoints-active", "debugger.toggle-pause"];
365 var actionKeys = WebInspector.shortcutRegistry.keysForActions(forwardedActions).map(WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey);
367 actionKeys.push({keyCode: WebInspector.KeyboardShortcut.Keys.F8.code});
368 InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));
371 _registerMessageSinkListener: function()
373 WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdded, messageAdded);
376 * @param {!WebInspector.Event} event
378 function messageAdded(event)
380 var message = /** @type {!WebInspector.Console.Message} */ (event.data);
381 if (message.show)
382 WebInspector.console.show();
386 _documentClick: function(event)
388 var target = event.target;
389 if (target.shadowRoot)
390 target = event.deepElementFromPoint();
391 if (!target)
392 return;
394 var anchor = target.enclosingNodeOrSelfWithNodeName("a");
395 if (!anchor || !anchor.href)
396 return;
398 // Prevent the link from navigating, since we don't do any navigation by following links normally.
399 event.consume(true);
401 if (anchor.preventFollow)
402 return;
404 function followLink()
406 if (WebInspector.isBeingEdited(target))
407 return;
408 if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
409 return;
411 var uiSourceCode = WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(anchor.href);
412 if (uiSourceCode) {
413 WebInspector.Revealer.reveal(uiSourceCode.uiLocation(anchor.lineNumber || 0, anchor.columnNumber || 0));
414 return;
417 var resource = WebInspector.resourceForURL(anchor.href);
418 if (resource) {
419 WebInspector.Revealer.reveal(resource);
420 return;
423 var request = WebInspector.NetworkLog.requestForURL(anchor.href);
424 if (request) {
425 WebInspector.Revealer.reveal(request);
426 return;
428 InspectorFrontendHost.openInNewTab(anchor.href);
431 if (WebInspector.followLinkTimeout)
432 clearTimeout(WebInspector.followLinkTimeout);
434 if (anchor.preventFollowOnDoubleClick) {
435 // Start a timeout if this is the first click, if the timeout is canceled
436 // before it fires, then a double clicked happened or another link was clicked.
437 if (event.detail === 1)
438 WebInspector.followLinkTimeout = setTimeout(followLink, 333);
439 return;
442 if (!anchor.classList.contains("webkit-html-external-link"))
443 followLink();
444 else
445 InspectorFrontendHost.openInNewTab(anchor.href);
448 _registerShortcuts: function()
450 var shortcut = WebInspector.KeyboardShortcut;
451 var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
452 var keys = [
453 shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta),
454 shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta)
456 section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
458 keys = [
459 shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
460 shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
462 section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
464 var toggleConsoleLabel = WebInspector.UIString("Show console");
465 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
466 section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), WebInspector.UIString("Toggle drawer"));
467 if (WebInspector.dockController.canDock()) {
468 section.addKey(shortcut.makeDescriptor("M", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift), WebInspector.UIString("Toggle device mode"));
469 section.addKey(shortcut.makeDescriptor("D", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift), WebInspector.UIString("Toggle dock side"));
471 section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
473 var advancedSearchShortcutModifier = WebInspector.isMac()
474 ? WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt
475 : WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift;
476 var advancedSearchShortcut = shortcut.makeDescriptor("f", advancedSearchShortcutModifier);
477 section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources"));
479 var inspectElementModeShortcut = WebInspector.InspectElementModeController.createShortcut();
480 section.addKey(inspectElementModeShortcut, WebInspector.UIString("Select node to inspect"));
482 var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("p", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
483 section.addKey(openResourceShortcut, WebInspector.UIString("Go to source"));
485 if (WebInspector.isMac()) {
486 keys = [
487 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta),
488 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
490 section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
494 _postDocumentKeyDown: function(event)
496 if (event.handled)
497 return;
499 var target = event.deepActiveElement();
500 if (target) {
501 var anchor = target.enclosingNodeOrSelfWithNodeName("a");
502 if (anchor && anchor.preventFollow)
503 event.preventDefault();
506 if (!WebInspector.Dialog.currentInstance() && WebInspector.inspectorView.currentPanel()) {
507 WebInspector.inspectorView.currentPanel().handleShortcut(event);
508 if (event.handled) {
509 event.consume(true);
510 return;
514 WebInspector.shortcutRegistry.handleShortcut(event);
517 _documentCanCopy: function(event)
519 var panel = WebInspector.inspectorView.currentPanel();
520 if (panel && panel["handleCopyEvent"])
521 event.preventDefault();
524 _documentCopy: function(event)
526 var panel = WebInspector.inspectorView.currentPanel();
527 if (panel && panel["handleCopyEvent"])
528 panel["handleCopyEvent"](event);
531 _documentCut: function(event)
533 var panel = WebInspector.inspectorView.currentPanel();
534 if (panel && panel["handleCutEvent"])
535 panel["handleCutEvent"](event);
538 _documentPaste: function(event)
540 var panel = WebInspector.inspectorView.currentPanel();
541 if (panel && panel["handlePasteEvent"])
542 panel["handlePasteEvent"](event);
545 _contextMenuEventFired: function(event)
547 if (event.handled || event.target.classList.contains("popup-glasspane"))
548 event.preventDefault();
552 * @param {!Document} document
554 _addMainEventListeners: function(document)
556 document.addEventListener("keydown", this._postDocumentKeyDown.bind(this), false);
557 document.addEventListener("beforecopy", this._documentCanCopy.bind(this), true);
558 document.addEventListener("copy", this._documentCopy.bind(this), false);
559 document.addEventListener("cut", this._documentCut.bind(this), false);
560 document.addEventListener("paste", this._documentPaste.bind(this), false);
561 document.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
562 document.addEventListener("click", this._documentClick.bind(this), false);
566 * @param {!WebInspector.Event} event
568 _reloadInspectedPage: function(event)
570 var hard = /** @type {boolean} */ (event.data);
571 WebInspector.Main._reloadPage(hard);
575 * @override
576 * @param {!RuntimeAgent.RemoteObject} payload
577 * @param {!Object=} hints
579 inspect: function(payload, hints)
581 var object = this._mainTarget.runtimeModel.createRemoteObject(payload);
582 if (object.isNode()) {
583 WebInspector.Revealer.revealPromise(object).then(object.release.bind(object));
584 return;
587 if (object.type === "function") {
588 object.functionDetails(didGetDetails);
589 return;
593 * @param {?WebInspector.DebuggerModel.FunctionDetails} response
595 function didGetDetails(response)
597 object.release();
599 if (!response || !response.location)
600 return;
602 WebInspector.Revealer.reveal(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(response.location));
605 if (hints.copyToClipboard)
606 InspectorFrontendHost.copyText(object.value);
607 object.release();
611 * @override
612 * @param {string} reason
614 detached: function(reason)
616 WebInspector._disconnectedScreenWithReasonWasShown = true;
617 new WebInspector.RemoteDebuggingTerminatedScreen(reason).showModal();
621 * @override
623 targetCrashed: function()
625 var debuggerModel = WebInspector.DebuggerModel.fromTarget(this._mainTarget);
626 if (!debuggerModel)
627 return;
628 (new WebInspector.HelpScreenUntilReload(
629 debuggerModel,
630 WebInspector.UIString("Inspected target disconnected"),
631 WebInspector.UIString("Inspected target disconnected. Once it reloads we will attach to it automatically."))).showModal();
635 * @override
636 * @param {number} callId
637 * @param {string} script
639 evaluateForTestInFrontend: function(callId, script)
641 WebInspector.evaluateForTestInFrontend(callId, script);
645 WebInspector.reload = function()
647 if (WebInspector.dockController.canDock() && WebInspector.dockController.dockSide() === WebInspector.DockController.State.Undocked)
648 InspectorFrontendHost.setIsDocked(true, function() {});
649 window.location.reload();
653 * @constructor
654 * @implements {WebInspector.ActionDelegate}
656 WebInspector.Main.ReloadActionDelegate = function()
660 WebInspector.Main.ReloadActionDelegate.prototype = {
662 * @override
663 * @param {!WebInspector.Context} context
664 * @param {string} actionId
666 handleAction: function(context, actionId)
668 switch (actionId) {
669 case "main.reload":
670 WebInspector.Main._reloadPage(false);
671 break;
672 case "main.hard-reload":
673 WebInspector.Main._reloadPage(true);
674 break;
675 case "main.debug-reload":
676 WebInspector.reload();
677 break;
683 * @constructor
684 * @implements {WebInspector.ActionDelegate}
686 WebInspector.Main.ZoomActionDelegate = function()
690 WebInspector.Main.ZoomActionDelegate.prototype = {
692 * @override
693 * @param {!WebInspector.Context} context
694 * @param {string} actionId
696 handleAction: function(context, actionId)
698 if (InspectorFrontendHost.isHostedMode())
699 return;
701 switch (actionId) {
702 case "main.zoom-in":
703 InspectorFrontendHost.zoomIn();
704 break;
705 case "main.zoom-out":
706 InspectorFrontendHost.zoomOut();
707 break;
708 case "main.zoom-reset":
709 InspectorFrontendHost.resetZoom();
710 break;
716 * @constructor
717 * @implements {WebInspector.ActionDelegate}
719 WebInspector.Main.InspectDevicesActionDelegate = function()
723 WebInspector.Main.InspectDevicesActionDelegate.prototype = {
725 * @override
726 * @param {!WebInspector.Context} context
727 * @param {string} actionId
729 handleAction: function(context, actionId)
731 InspectorFrontendHost.openInNewTab("chrome://inspect#devices");
736 * @param {boolean} hard
738 WebInspector.Main._reloadPage = function(hard)
740 if (!WebInspector.targetManager.hasTargets())
741 return;
742 if (WebInspector.targetManager.mainTarget().isServiceWorker())
743 return;
744 WebInspector.targetManager.reloadPage(hard);
748 * @param {string} ws
750 WebInspector.Main._addWebSocketTarget = function(ws)
753 * @param {!InspectorBackendClass.Connection} connection
755 function callback(connection)
757 WebInspector.targetManager.createTarget(ws, WebInspector.Target.Type.Page, connection, null);
759 new InspectorBackendClass.WebSocketConnection(ws, callback);
763 * @constructor
764 * @implements {WebInspector.ToolbarItem.Provider}
766 WebInspector.Main.WarningErrorCounter = function()
768 this._counter = new WebInspector.ToolbarCounter(["error-icon", "revokedError-icon", "warning-icon"]);
769 WebInspector.Main.WarningErrorCounter._instanceForTest = this._counter;
770 this._counter.addEventListener("click", showConsole);
772 function showConsole()
774 WebInspector.console.show();
777 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this);
778 WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
781 WebInspector.Main.WarningErrorCounter.prototype = {
782 _updateErrorAndWarningCounts: function()
784 var errors = 0;
785 var revokedErrors = 0;
786 var warnings = 0;
787 var targets = WebInspector.targetManager.targets();
788 for (var i = 0; i < targets.length; ++i) {
789 errors += targets[i].consoleModel.errors();
790 revokedErrors += targets[i].consoleModel.revokedErrors();
791 warnings += targets[i].consoleModel.warnings();
793 this._counter.setCounter("error-icon", errors, WebInspector.UIString(errors === 1 ? "%d error" : "%d errors", errors));
794 this._counter.setCounter("revokedError-icon", revokedErrors, WebInspector.UIString(revokedErrors === 1 ? "%d handled promise rejection" : "%d handled promise rejections", revokedErrors));
795 this._counter.setCounter("warning-icon", warnings, WebInspector.UIString(warnings === 1 ? "%d warning" : "%d warnings", warnings));
796 WebInspector.inspectorView.toolbarItemResized();
800 * @override
801 * @return {?WebInspector.ToolbarItem}
803 item: function()
805 return this._counter;
810 * @constructor
811 * @implements {WebInspector.ToolbarItem.Provider}
813 WebInspector.Main.MainMenuItem = function()
815 this._item = new WebInspector.ToolbarButton(WebInspector.UIString("Customize and control DevTools"), "menu-toolbar-item");
816 this._item.addEventListener("mousedown", this._mouseDown, this);
819 WebInspector.Main.MainMenuItem.prototype = {
821 * @override
822 * @return {?WebInspector.ToolbarItem}
824 item: function()
826 return this._item;
830 * @param {!WebInspector.Event} event
832 _mouseDown: function(event)
834 var contextMenu = new WebInspector.ContextMenu(/** @type {!Event} */(event.data),
835 true,
836 this._item.element.totalOffsetLeft(),
837 this._item.element.totalOffsetTop() + this._item.element.offsetHeight);
839 if (WebInspector.dockController.canDock()) {
840 var dockItemElement = createElementWithClass("div", "flex-centered flex-auto");
841 var titleElement = dockItemElement.createChild("span", "flex-auto");
842 titleElement.textContent = WebInspector.UIString("Dock side");
843 var toggleDockSideShorcuts = WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.toggle-dock");
844 titleElement.title = WebInspector.UIString("Placement of DevTools relative to the page. (%s to restore last position)", toggleDockSideShorcuts[0].name);
845 dockItemElement.appendChild(titleElement);
846 var dockItemToolbar = new WebInspector.Toolbar(dockItemElement);
847 dockItemToolbar.makeBlueOnHover();
848 var undock = new WebInspector.ToolbarButton(WebInspector.UIString("Undock into separate window"), "dock-toolbar-item-undock");
849 var bottom = new WebInspector.ToolbarButton(WebInspector.UIString("Dock to bottom"), "dock-toolbar-item-bottom");
850 var right = new WebInspector.ToolbarButton(WebInspector.UIString("Dock to right"), "dock-toolbar-item-right");
851 undock.addEventListener("mouseup", setDockSide.bind(null, WebInspector.DockController.State.Undocked));
852 bottom.addEventListener("mouseup", setDockSide.bind(null, WebInspector.DockController.State.DockedToBottom));
853 right.addEventListener("mouseup", setDockSide.bind(null, WebInspector.DockController.State.DockedToRight));
854 undock.setToggled(WebInspector.dockController.dockSide() === WebInspector.DockController.State.Undocked);
855 bottom.setToggled(WebInspector.dockController.dockSide() === WebInspector.DockController.State.DockedToBottom);
856 right.setToggled(WebInspector.dockController.dockSide() === WebInspector.DockController.State.DockedToRight);
857 dockItemToolbar.appendToolbarItem(undock);
858 dockItemToolbar.appendToolbarItem(bottom);
859 dockItemToolbar.appendToolbarItem(right);
860 contextMenu.appendCustomItem(dockItemElement);
861 contextMenu.appendSeparator();
865 * @param {string} side
867 function setDockSide(side)
869 WebInspector.dockController.setDockSide(side);
870 contextMenu.discard();
873 contextMenu.appendAction("main.toggle-drawer", WebInspector.inspectorView.drawerVisible() ? WebInspector.UIString("Hide console") : WebInspector.UIString("Show console"));
874 contextMenu.appendItemsAtLocation("mainMenu");
875 contextMenu.show();
880 * @constructor
882 WebInspector.NetworkPanelIndicator = function()
884 var networkConditionsSetting = WebInspector.moduleSetting("networkConditions");
885 networkConditionsSetting.addChangeListener(updateVisibility);
886 var blockedURLsSetting = WebInspector.moduleSetting("blockedURLs");
887 blockedURLsSetting.addChangeListener(updateVisibility);
888 updateVisibility();
890 function updateVisibility()
892 if (WebInspector.NetworkManager.IsThrottlingEnabled(networkConditionsSetting.get())) {
893 WebInspector.inspectorView.setPanelIcon("network", "warning-icon", WebInspector.UIString("Network throttling is enabled"));
894 } else if (blockedURLsSetting.get().length) {
895 WebInspector.inspectorView.setPanelIcon("network", "warning-icon", WebInspector.UIString("Requests may be blocked"));
896 } else {
897 WebInspector.inspectorView.setPanelIcon("network", "", "");
903 * @constructor
905 WebInspector.Main.PauseListener = function()
907 WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
910 WebInspector.Main.PauseListener.prototype = {
912 * @param {!WebInspector.Event} event
914 _debuggerPaused: function(event)
916 WebInspector.targetManager.removeModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
917 var debuggerPausedDetails = /** @type {!WebInspector.DebuggerPausedDetails} */ (event.data);
918 var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
919 WebInspector.context.setFlavor(WebInspector.Target, debuggerModel.target());
920 WebInspector.Revealer.reveal(debuggerPausedDetails);
925 * @constructor
927 WebInspector.Main.InspectedNodeRevealer = function()
929 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeInspected, this._inspectNode, this);
932 WebInspector.Main.InspectedNodeRevealer.prototype = {
934 * @param {!WebInspector.Event} event
936 _inspectNode: function(event)
938 var deferredNode = /** @type {!WebInspector.DeferredDOMNode} */ (event.data);
939 WebInspector.Revealer.reveal(deferredNode);
944 * @constructor
945 * @extends {WebInspector.HelpScreen}
947 WebInspector.RemoteDebuggingTerminatedScreen = function(reason)
949 WebInspector.HelpScreen.call(this, WebInspector.UIString("Detached from the target"));
950 var p = this.helpContentElement.createChild("p");
951 p.classList.add("help-section");
952 p.createChild("span").textContent = WebInspector.UIString("Remote debugging has been terminated with reason: ");
953 p.createChild("span", "error-message").textContent = reason;
954 p.createChild("br");
955 p.createChild("span").textContent = WebInspector.UIString("Please re-attach to the new target.");
958 WebInspector.RemoteDebuggingTerminatedScreen.prototype = {
959 __proto__: WebInspector.HelpScreen.prototype
963 * @constructor
964 * @extends {WebInspector.HelpScreen}
966 WebInspector.WorkerTerminatedScreen = function()
968 WebInspector.HelpScreen.call(this, WebInspector.UIString("Inspected worker terminated"));
969 var p = this.helpContentElement.createChild("p");
970 p.classList.add("help-section");
971 p.textContent = WebInspector.UIString("Inspected worker has terminated. Once it restarts we will attach to it automatically.");
974 WebInspector.WorkerTerminatedScreen.prototype = {
976 __proto__: WebInspector.HelpScreen.prototype
979 new WebInspector.Main();