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
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.
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 = {
47 * @return {!Promise.<undefined>}
49 showConsole: function()
51 return WebInspector
.Revealer
.revealPromise(WebInspector
.console
);
56 console
.timeStamp("Main._loaded");
58 if (InspectorFrontendHost
.isUnderTest())
59 self
.runtime
.useTestBase();
60 InspectorFrontendHost
.getPreferences(this._gotPreferences
.bind(this));
64 * @param {!Object<string, string>} prefs
66 _gotPreferences: function(prefs
)
68 console
.timeStamp("Main._gotPreferences");
69 this._createSettings(prefs
);
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");
83 var settings
= JSON
.parse(window
.decodeURI(settingsParam
));
84 for (var key
in settings
)
85 prefs
[key
] = settings
[key
];
87 // Ignore malformed settings.
91 this._initializeExperiments(prefs
);
94 * @param {!Array<{name: string}>} changes
96 function trackPrefsObject(changes
)
98 if (!Object
.keys(prefs
).length
) {
99 InspectorFrontendHost
.clearPreferences();
103 for (var change
of changes
) {
104 var name
= change
.name
;
106 InspectorFrontendHost
.setPreference(name
, prefs
[name
]);
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("timelineDetailsChart", "Costly functions view in Timeline details", true);
130 Runtime
.experiments
.register("colorPalettes", "Color palettes");
131 Runtime
.experiments
.register("customObjectFormatters", "Custom object formatters", true);
132 Runtime
.experiments
.register("emptySourceMapAutoStepping", "Empty sourcemap auto-stepping");
133 Runtime
.experiments
.register("fileSystemInspection", "FileSystem inspection");
134 Runtime
.experiments
.register("gpuTimeline", "GPU data on timeline", true);
135 Runtime
.experiments
.register("inputEventsOnTimelineOverview", "Input events on Timeline overview", true);
136 Runtime
.experiments
.register("layersPanel", "Layers panel");
137 Runtime
.experiments
.register("layoutEditor", "Layout editor", true);
138 Runtime
.experiments
.register("mainMenu", "Main menu", true);
139 Runtime
.experiments
.register("materialDesign", "Material design");
140 Runtime
.experiments
.register("networkRequestHeadersFilterInDetailsView", "Network request headers filter in details view", true);
141 Runtime
.experiments
.register("networkRequestsOnTimeline", "Network requests on Timeline", true);
142 Runtime
.experiments
.register("privateScriptInspection", "Private script inspection");
143 Runtime
.experiments
.register("promiseTracker", "Promise inspector");
144 Runtime
.experiments
.register("securityPanel", "Security panel", true);
145 Runtime
.experiments
.register("serviceWorkersInPageFrontend", "Service workers in DevTools for page");
146 Runtime
.experiments
.register("serviceWorkersInResources", "Service workers in Resources panel", true);
147 Runtime
.experiments
.register("showPrimaryLoadWaterfallInNetworkTimeline", "Show primary load waterfall in Network timeline", true);
148 Runtime
.experiments
.register("stepIntoAsync", "Step into async");
149 Runtime
.experiments
.register("timelineInvalidationTracking", "Timeline invalidation tracking", true);
150 Runtime
.experiments
.register("timelineTracingJSProfile", "Timeline tracing based JS profiler", true);
151 Runtime
.experiments
.register("timelineFlowEvents", "Timeline flow events", true);
152 Runtime
.experiments
.register("tooltips", "Tooltips", true);
153 Runtime
.experiments
.register("inlineVariableValues", "Display variable values inline while debugging");
155 Runtime
.experiments
.cleanUpStaleExperiments();
157 if (InspectorFrontendHost
.isUnderTest()) {
158 var testPath
= JSON
.parse(prefs
["testPath"] || "\"\"");
159 // Enable experiments for testing.
160 if (testPath
.indexOf("debugger/promise") !== -1)
161 Runtime
.experiments
.enableForTest("promiseTracker");
162 if (testPath
.indexOf("elements/") !== -1)
163 Runtime
.experiments
.enableForTest("animationInspection");
164 if (testPath
.indexOf("layers/") !== -1)
165 Runtime
.experiments
.enableForTest("layersPanel");
166 if (testPath
.indexOf("service-workers/") !== -1)
167 Runtime
.experiments
.enableForTest("serviceWorkersInResources");
168 if (testPath
.indexOf("timeline/") !== -1 || testPath
.indexOf("layers/") !== -1)
169 Runtime
.experiments
.enableForTest("layersPanel");
172 Runtime
.experiments
.setDefaultExperiments([
173 "inlineVariableValues",
174 "serviceWorkersInPageFrontend"
179 * @suppressGlobalPropertiesCheck
181 _createAppUI: function()
183 console
.timeStamp("Main._createApp");
185 WebInspector
.initializeUIUtils(window
);
186 WebInspector
.installComponentRootStyles(/** @type {!Element} */ (document
.body
));
188 this._addMainEventListeners(document
);
190 var canDock
= !!Runtime
.queryParam("can_dock");
191 WebInspector
.zoomManager
= new WebInspector
.ZoomManager(window
, InspectorFrontendHost
);
192 WebInspector
.inspectorView
= new WebInspector
.InspectorView();
193 WebInspector
.ContextMenu
.initialize();
194 WebInspector
.ContextMenu
.installHandler(document
);
195 if (Runtime
.experiments
.isEnabled("tooltips"))
196 WebInspector
.Tooltip
.installHandler(document
);
197 WebInspector
.dockController
= new WebInspector
.DockController(canDock
);
198 WebInspector
.overridesSupport
= new WebInspector
.OverridesSupport();
199 WebInspector
.emulatedDevicesList
= new WebInspector
.EmulatedDevicesList();
200 WebInspector
.multitargetConsoleModel
= new WebInspector
.MultitargetConsoleModel();
201 WebInspector
.multitargetNetworkManager
= new WebInspector
.MultitargetNetworkManager();
203 WebInspector
.shortcutsScreen
= new WebInspector
.ShortcutsScreen();
204 // set order of some sections explicitly
205 WebInspector
.shortcutsScreen
.section(WebInspector
.UIString("Console"));
206 WebInspector
.shortcutsScreen
.section(WebInspector
.UIString("Elements Panel"));
208 WebInspector
.fileManager
= new WebInspector
.FileManager();
209 WebInspector
.isolatedFileSystemManager
= new WebInspector
.IsolatedFileSystemManager();
210 WebInspector
.workspace
= new WebInspector
.Workspace(WebInspector
.isolatedFileSystemManager
.mapping());
211 WebInspector
.networkMapping
= new WebInspector
.NetworkMapping(WebInspector
.workspace
, WebInspector
.isolatedFileSystemManager
.mapping());
212 WebInspector
.networkProjectManager
= new WebInspector
.NetworkProjectManager(WebInspector
.targetManager
, WebInspector
.workspace
, WebInspector
.networkMapping
);
213 WebInspector
.presentationConsoleMessageHelper
= new WebInspector
.PresentationConsoleMessageHelper(WebInspector
.workspace
);
214 WebInspector
.cssWorkspaceBinding
= new WebInspector
.CSSWorkspaceBinding(WebInspector
.targetManager
, WebInspector
.workspace
, WebInspector
.networkMapping
);
215 WebInspector
.debuggerWorkspaceBinding
= new WebInspector
.DebuggerWorkspaceBinding(WebInspector
.targetManager
, WebInspector
.workspace
, WebInspector
.networkMapping
);
216 WebInspector
.fileSystemWorkspaceBinding
= new WebInspector
.FileSystemWorkspaceBinding(WebInspector
.isolatedFileSystemManager
, WebInspector
.workspace
, WebInspector
.networkMapping
);
217 WebInspector
.breakpointManager
= new WebInspector
.BreakpointManager(null, WebInspector
.workspace
, WebInspector
.networkMapping
, WebInspector
.targetManager
, WebInspector
.debuggerWorkspaceBinding
);
218 WebInspector
.extensionServer
= new WebInspector
.ExtensionServer();
220 new WebInspector
.OverlayController();
221 new WebInspector
.ContentScriptProjectDecorator();
222 new WebInspector
.ExecutionContextSelector(WebInspector
.targetManager
, WebInspector
.context
);
224 var autoselectPanel
= WebInspector
.UIString("a panel chosen automatically");
225 var openAnchorLocationSetting
= WebInspector
.settings
.createSetting("openLinkHandler", autoselectPanel
);
226 WebInspector
.openAnchorLocationRegistry
= new WebInspector
.HandlerRegistry(openAnchorLocationSetting
);
227 WebInspector
.openAnchorLocationRegistry
.registerHandler(autoselectPanel
, function() { return false; });
228 WebInspector
.Linkifier
.setLinkHandler(new WebInspector
.HandlerRegistry
.LinkHandler());
230 new WebInspector
.WorkspaceController(WebInspector
.workspace
);
231 new WebInspector
.RenderingOptions();
232 new WebInspector
.Main
.PauseListener();
233 new WebInspector
.Main
.InspectedNodeRevealer();
234 new WebInspector
.ThrottlingIndicator();
235 WebInspector
.domBreakpointsSidebarPane
= new WebInspector
.DOMBreakpointsSidebarPane();
237 WebInspector
.actionRegistry
= new WebInspector
.ActionRegistry();
238 WebInspector
.shortcutRegistry
= new WebInspector
.ShortcutRegistry(WebInspector
.actionRegistry
, document
);
239 WebInspector
.ShortcutsScreen
.registerShortcuts();
240 this._registerForwardedShortcuts();
241 this._registerMessageSinkListener();
243 var appExtension
= self
.runtime
.extensions(WebInspector
.AppProvider
)[0];
244 appExtension
.instancePromise().then(this._showAppUI
.bind(this));
248 * @param {!Object} appProvider
249 * @suppressGlobalPropertiesCheck
251 _showAppUI: function(appProvider
)
253 var app
= /** @type {!WebInspector.AppProvider} */ (appProvider
).createApp();
254 // It is important to kick controller lifetime after apps are instantiated.
255 WebInspector
.dockController
.initialize();
256 console
.timeStamp("Main._presentUI");
257 app
.presentUI(document
);
259 if (!Runtime
.queryParam("isSharedWorker"))
260 WebInspector
.inspectElementModeController
= new WebInspector
.InspectElementModeController();
261 WebInspector
.inspectorView
.createToolbars();
262 InspectorFrontendHost
.loadCompleted();
264 var extensions
= self
.runtime
.extensions(WebInspector
.QueryParamHandler
);
265 for (var extension
of extensions
) {
266 var value
= Runtime
.queryParam(extension
.descriptor()["name"]);
268 extension
.instancePromise().then(handleQueryParam
.bind(null, value
));
270 // Give UI cycles to repaint, then proceed with creating connection.
271 setTimeout(this._createConnection
.bind(this), 0);
274 * @param {string} value
275 * @param {!WebInspector.QueryParamHandler} handler
277 function handleQueryParam(value
, handler
)
279 handler
.handleQueryParam(value
);
283 _createConnection: function()
285 console
.timeStamp("Main._createConnection");
286 InspectorBackend
.loadFromJSONIfNeeded("../protocol.json");
288 if (Runtime
.queryParam("ws")) {
289 var ws
= "ws://" + Runtime
.queryParam("ws");
290 InspectorBackendClass
.WebSocketConnection
.Create(ws
, this._connectionEstablished
.bind(this));
294 if (!InspectorFrontendHost
.isHostedMode()) {
295 this._connectionEstablished(new InspectorBackendClass
.MainConnection());
299 this._connectionEstablished(new InspectorBackendClass
.StubConnection());
303 * @param {!InspectorBackendClass.Connection} connection
305 _connectionEstablished: function(connection
)
307 console
.timeStamp("Main._connectionEstablished");
308 connection
.addEventListener(InspectorBackendClass
.Connection
.Events
.Disconnected
, onDisconnected
);
311 * @param {!WebInspector.Event} event
313 function onDisconnected(event
)
315 if (WebInspector
._disconnectedScreenWithReasonWasShown
)
317 new WebInspector
.RemoteDebuggingTerminatedScreen(event
.data
.reason
).showModal();
320 InspectorBackend
.setConnection(connection
);
321 var targetType
= Runtime
.queryParam("isSharedWorker") ? WebInspector
.Target
.Type
.ServiceWorker
: WebInspector
.Target
.Type
.Page
;
322 WebInspector
.targetManager
.createTarget(WebInspector
.UIString("Main"), targetType
, connection
, null, this._mainTargetCreated
.bind(this));
326 * @param {?WebInspector.Target} target
328 _mainTargetCreated: function(target
)
330 console
.timeStamp("Main._mainTargetCreated");
331 this._mainTarget
= /** @type {!WebInspector.Target} */(target
);
332 this._registerShortcuts();
334 this._mainTarget
.registerInspectorDispatcher(this);
336 if (this._mainTarget
.isServiceWorker())
337 this._mainTarget
.runtimeAgent().run();
339 WebInspector
.overridesSupport
.init(this._mainTarget
, overridesReady
);
341 function overridesReady()
343 if (!WebInspector
.dockController
.canDock() && WebInspector
.overridesSupport
.emulationEnabled())
344 WebInspector
.inspectorView
.showViewInDrawer("emulation", true);
346 target
.inspectorAgent().enable(inspectorAgentEnableCallback
);
349 function inspectorAgentEnableCallback()
351 console
.timeStamp("Main.inspectorAgentEnableCallback");
352 WebInspector
.notifications
.dispatchEventToListeners(WebInspector
.NotificationService
.Events
.InspectorAgentEnabledForTests
);
353 // Asynchronously run the extensions.
354 setTimeout(function() { WebInspector
.extensionServer
.initializeExtensions(); }, 0);
358 _registerForwardedShortcuts: function()
360 /** @const */ var forwardedActions
= ["main.reload", "main.hard-reload", "main.toggle-dock"];
361 var actionKeys
= WebInspector
.shortcutRegistry
.keysForActions(forwardedActions
).map(WebInspector
.KeyboardShortcut
.keyCodeAndModifiersFromKey
);
363 actionKeys
.push({keyCode
: WebInspector
.KeyboardShortcut
.Keys
.F8
.code
});
364 InspectorFrontendHost
.setWhitelistedShortcuts(JSON
.stringify(actionKeys
));
367 _registerMessageSinkListener: function()
369 WebInspector
.console
.addEventListener(WebInspector
.Console
.Events
.MessageAdded
, messageAdded
);
372 * @param {!WebInspector.Event} event
374 function messageAdded(event
)
376 var message
= /** @type {!WebInspector.Console.Message} */ (event
.data
);
378 WebInspector
.console
.show();
382 _documentClick: function(event
)
384 var target
= event
.target
;
385 if (target
.shadowRoot
)
386 target
= event
.deepElementFromPoint();
390 var anchor
= target
.enclosingNodeOrSelfWithNodeName("a");
391 if (!anchor
|| !anchor
.href
)
394 // Prevent the link from navigating, since we don't do any navigation by following links normally.
397 if (anchor
.preventFollow
)
400 function followLink()
402 if (WebInspector
.isBeingEdited(target
))
404 if (WebInspector
.openAnchorLocationRegistry
.dispatch({ url
: anchor
.href
, lineNumber
: anchor
.lineNumber
}))
407 var uiSourceCode
= WebInspector
.networkMapping
.uiSourceCodeForURLForAnyTarget(anchor
.href
);
409 WebInspector
.Revealer
.reveal(uiSourceCode
.uiLocation(anchor
.lineNumber
|| 0, anchor
.columnNumber
|| 0));
413 var resource
= WebInspector
.resourceForURL(anchor
.href
);
415 WebInspector
.Revealer
.reveal(resource
);
419 var request
= WebInspector
.NetworkLog
.requestForURL(anchor
.href
);
421 WebInspector
.Revealer
.reveal(request
);
424 InspectorFrontendHost
.openInNewTab(anchor
.href
);
427 if (WebInspector
.followLinkTimeout
)
428 clearTimeout(WebInspector
.followLinkTimeout
);
430 if (anchor
.preventFollowOnDoubleClick
) {
431 // Start a timeout if this is the first click, if the timeout is canceled
432 // before it fires, then a double clicked happened or another link was clicked.
433 if (event
.detail
=== 1)
434 WebInspector
.followLinkTimeout
= setTimeout(followLink
, 333);
438 if (!anchor
.classList
.contains("webkit-html-external-link"))
441 InspectorFrontendHost
.openInNewTab(anchor
.href
);
444 _registerShortcuts: function()
446 var shortcut
= WebInspector
.KeyboardShortcut
;
447 var section
= WebInspector
.shortcutsScreen
.section(WebInspector
.UIString("All Panels"));
449 shortcut
.makeDescriptor("[", shortcut
.Modifiers
.CtrlOrMeta
),
450 shortcut
.makeDescriptor("]", shortcut
.Modifiers
.CtrlOrMeta
)
452 section
.addRelatedKeys(keys
, WebInspector
.UIString("Go to the panel to the left/right"));
455 shortcut
.makeDescriptor("[", shortcut
.Modifiers
.CtrlOrMeta
| shortcut
.Modifiers
.Alt
),
456 shortcut
.makeDescriptor("]", shortcut
.Modifiers
.CtrlOrMeta
| shortcut
.Modifiers
.Alt
)
458 section
.addRelatedKeys(keys
, WebInspector
.UIString("Go back/forward in panel history"));
460 var toggleConsoleLabel
= WebInspector
.UIString("Show console");
461 section
.addKey(shortcut
.makeDescriptor(shortcut
.Keys
.Tilde
, shortcut
.Modifiers
.Ctrl
), toggleConsoleLabel
);
462 section
.addKey(shortcut
.makeDescriptor(shortcut
.Keys
.Esc
), WebInspector
.UIString("Toggle drawer"));
463 if (WebInspector
.dockController
.canDock()) {
464 section
.addKey(shortcut
.makeDescriptor("M", shortcut
.Modifiers
.CtrlOrMeta
| shortcut
.Modifiers
.Shift
), WebInspector
.UIString("Toggle device mode"));
465 section
.addKey(shortcut
.makeDescriptor("D", shortcut
.Modifiers
.CtrlOrMeta
| shortcut
.Modifiers
.Shift
), WebInspector
.UIString("Toggle dock side"));
467 section
.addKey(shortcut
.makeDescriptor("f", shortcut
.Modifiers
.CtrlOrMeta
), WebInspector
.UIString("Search"));
469 var advancedSearchShortcutModifier
= WebInspector
.isMac()
470 ? WebInspector
.KeyboardShortcut
.Modifiers
.Meta
| WebInspector
.KeyboardShortcut
.Modifiers
.Alt
471 : WebInspector
.KeyboardShortcut
.Modifiers
.Ctrl
| WebInspector
.KeyboardShortcut
.Modifiers
.Shift
;
472 var advancedSearchShortcut
= shortcut
.makeDescriptor("f", advancedSearchShortcutModifier
);
473 section
.addKey(advancedSearchShortcut
, WebInspector
.UIString("Search across all sources"));
475 var inspectElementModeShortcut
= WebInspector
.InspectElementModeController
.createShortcut();
476 section
.addKey(inspectElementModeShortcut
, WebInspector
.UIString("Select node to inspect"));
478 var openResourceShortcut
= WebInspector
.KeyboardShortcut
.makeDescriptor("p", WebInspector
.KeyboardShortcut
.Modifiers
.CtrlOrMeta
);
479 section
.addKey(openResourceShortcut
, WebInspector
.UIString("Go to source"));
481 if (WebInspector
.isMac()) {
483 shortcut
.makeDescriptor("g", shortcut
.Modifiers
.Meta
),
484 shortcut
.makeDescriptor("g", shortcut
.Modifiers
.Meta
| shortcut
.Modifiers
.Shift
)
486 section
.addRelatedKeys(keys
, WebInspector
.UIString("Find next/previous"));
490 _postDocumentKeyDown: function(event
)
495 var target
= event
.deepActiveElement();
497 var anchor
= target
.enclosingNodeOrSelfWithNodeName("a");
498 if (anchor
&& anchor
.preventFollow
)
499 event
.preventDefault();
502 if (!WebInspector
.Dialog
.currentInstance() && WebInspector
.inspectorView
.currentPanel()) {
503 WebInspector
.inspectorView
.currentPanel().handleShortcut(event
);
510 WebInspector
.shortcutRegistry
.handleShortcut(event
);
513 _documentCanCopy: function(event
)
515 var panel
= WebInspector
.inspectorView
.currentPanel();
516 if (panel
&& panel
["handleCopyEvent"])
517 event
.preventDefault();
520 _documentCopy: function(event
)
522 var panel
= WebInspector
.inspectorView
.currentPanel();
523 if (panel
&& panel
["handleCopyEvent"])
524 panel
["handleCopyEvent"](event
);
527 _documentCut: function(event
)
529 var panel
= WebInspector
.inspectorView
.currentPanel();
530 if (panel
&& panel
["handleCutEvent"])
531 panel
["handleCutEvent"](event
);
534 _documentPaste: function(event
)
536 var panel
= WebInspector
.inspectorView
.currentPanel();
537 if (panel
&& panel
["handlePasteEvent"])
538 panel
["handlePasteEvent"](event
);
541 _contextMenuEventFired: function(event
)
543 if (event
.handled
|| event
.target
.classList
.contains("popup-glasspane"))
544 event
.preventDefault();
548 * @param {!Document} document
550 _addMainEventListeners: function(document
)
552 document
.addEventListener("keydown", this._postDocumentKeyDown
.bind(this), false);
553 document
.addEventListener("beforecopy", this._documentCanCopy
.bind(this), true);
554 document
.addEventListener("copy", this._documentCopy
.bind(this), false);
555 document
.addEventListener("cut", this._documentCut
.bind(this), false);
556 document
.addEventListener("paste", this._documentPaste
.bind(this), false);
557 document
.addEventListener("contextmenu", this._contextMenuEventFired
.bind(this), true);
558 document
.addEventListener("click", this._documentClick
.bind(this), false);
563 * @param {!RuntimeAgent.RemoteObject} payload
564 * @param {!Object=} hints
566 inspect: function(payload
, hints
)
568 var object
= this._mainTarget
.runtimeModel
.createRemoteObject(payload
);
569 if (object
.isNode()) {
570 WebInspector
.Revealer
.revealPromise(object
).then(object
.release
.bind(object
));
574 if (object
.type
=== "function") {
575 object
.functionDetails(didGetDetails
);
580 * @param {?WebInspector.DebuggerModel.FunctionDetails} response
582 function didGetDetails(response
)
586 if (!response
|| !response
.location
)
589 WebInspector
.Revealer
.reveal(WebInspector
.debuggerWorkspaceBinding
.rawLocationToUILocation(response
.location
));
592 if (hints
.copyToClipboard
)
593 InspectorFrontendHost
.copyText(object
.value
);
599 * @param {string} reason
601 detached: function(reason
)
603 WebInspector
._disconnectedScreenWithReasonWasShown
= true;
604 new WebInspector
.RemoteDebuggingTerminatedScreen(reason
).showModal();
610 targetCrashed: function()
612 var debuggerModel
= WebInspector
.DebuggerModel
.fromTarget(this._mainTarget
);
615 (new WebInspector
.HelpScreenUntilReload(
617 WebInspector
.UIString("Inspected target disconnected"),
618 WebInspector
.UIString("Inspected target disconnected. Once it reloads we will attach to it automatically."))).showModal();
623 * @param {number} callId
624 * @param {string} script
626 evaluateForTestInFrontend: function(callId
, script
)
628 WebInspector
.evaluateForTestInFrontend(callId
, script
);
632 WebInspector
.reload = function()
634 if (WebInspector
.dockController
.canDock() && WebInspector
.dockController
.dockSide() === WebInspector
.DockController
.State
.Undocked
)
635 InspectorFrontendHost
.setIsDocked(true, function() {});
636 window
.location
.reload();
641 * @implements {WebInspector.ActionDelegate}
643 WebInspector
.Main
.ReloadActionDelegate = function()
647 WebInspector
.Main
.ReloadActionDelegate
.prototype = {
650 * @param {!WebInspector.Context} context
651 * @param {string} actionId
653 handleAction: function(context
, actionId
)
657 WebInspector
.Main
._reloadPage(false);
659 case "main.hard-reload":
660 WebInspector
.Main
._reloadPage(true);
662 case "main.debug-reload":
663 WebInspector
.reload();
671 * @implements {WebInspector.ActionDelegate}
673 WebInspector
.Main
.ZoomActionDelegate = function()
677 WebInspector
.Main
.ZoomActionDelegate
.prototype = {
680 * @param {!WebInspector.Context} context
681 * @param {string} actionId
683 handleAction: function(context
, actionId
)
685 if (InspectorFrontendHost
.isHostedMode())
690 InspectorFrontendHost
.zoomIn();
692 case "main.zoom-out":
693 InspectorFrontendHost
.zoomOut();
695 case "main.zoom-reset":
696 InspectorFrontendHost
.resetZoom();
703 * @param {boolean} hard
705 WebInspector
.Main
._reloadPage = function(hard
)
707 if (!WebInspector
.targetManager
.hasTargets())
709 if (WebInspector
.targetManager
.mainTarget().isServiceWorker())
711 WebInspector
.targetManager
.reloadPage(hard
);
717 WebInspector
.Main
._addWebSocketTarget = function(ws
)
720 * @param {!InspectorBackendClass.Connection} connection
722 function callback(connection
)
724 WebInspector
.targetManager
.createTarget(ws
, WebInspector
.Target
.Type
.Page
, connection
, null);
726 new InspectorBackendClass
.WebSocketConnection(ws
, callback
);
731 * @implements {WebInspector.ToolbarItem.Provider}
733 WebInspector
.Main
.WarningErrorCounter = function()
735 this._counter
= new WebInspector
.ToolbarCounter(["error-icon", "revokedError-icon", "warning-icon"]);
736 WebInspector
.Main
.WarningErrorCounter
._instanceForTest
= this._counter
;
737 this._counter
.addEventListener("click", showConsole
);
739 function showConsole()
741 WebInspector
.console
.show();
744 WebInspector
.multitargetConsoleModel
.addEventListener(WebInspector
.ConsoleModel
.Events
.ConsoleCleared
, this._updateErrorAndWarningCounts
, this);
745 WebInspector
.multitargetConsoleModel
.addEventListener(WebInspector
.ConsoleModel
.Events
.MessageAdded
, this._updateErrorAndWarningCounts
, this);
748 WebInspector
.Main
.WarningErrorCounter
.prototype = {
749 _updateErrorAndWarningCounts: function()
752 var revokedErrors
= 0;
754 var targets
= WebInspector
.targetManager
.targets();
755 for (var i
= 0; i
< targets
.length
; ++i
) {
756 errors
+= targets
[i
].consoleModel
.errors();
757 revokedErrors
+= targets
[i
].consoleModel
.revokedErrors();
758 warnings
+= targets
[i
].consoleModel
.warnings();
760 this._counter
.setCounter("error-icon", errors
, WebInspector
.UIString(errors
=== 1 ? "%d error" : "%d errors", errors
));
761 this._counter
.setCounter("revokedError-icon", revokedErrors
, WebInspector
.UIString(revokedErrors
=== 1 ? "%d handled promise rejection" : "%d handled promise rejections", revokedErrors
));
762 this._counter
.setCounter("warning-icon", warnings
, WebInspector
.UIString(warnings
=== 1 ? "%d warning" : "%d warnings", warnings
));
763 WebInspector
.inspectorView
.toolbarItemResized();
768 * @return {?WebInspector.ToolbarItem}
772 return this._counter
;
778 * @implements {WebInspector.ToolbarItem.Provider}
780 WebInspector
.Main
.MainMenuItem = function()
782 this._item
= new WebInspector
.ToolbarButton(WebInspector
.UIString("Customize and control DevTools"), "menu-toolbar-item");
783 this._item
.addEventListener("click", this._click
, this);
786 WebInspector
.Main
.MainMenuItem
.prototype = {
789 * @return {?WebInspector.ToolbarItem}
797 * @param {!WebInspector.Event} event
799 _click: function(event
)
801 var contextMenu
= new WebInspector
.ContextMenu(/** @type {!Event} */(event
.data
),
803 this._item
.element
.totalOffsetLeft(),
804 this._item
.element
.totalOffsetTop() + this._item
.element
.offsetHeight
);
805 var dockItemElement
= createElementWithClass("div", "flex-centered flex-auto");
806 var titleElement
= dockItemElement
.createChild("span", "flex-auto");
807 titleElement
.textContent
= WebInspector
.UIString("Dock side");
808 dockItemElement
.appendChild(titleElement
);
809 var dockItemToolbar
= new WebInspector
.Toolbar(dockItemElement
);
810 var undock
= new WebInspector
.ToolbarButton( WebInspector
.UIString("Undock into separate window"), "dock-toolbar-item-undock");
811 var bottom
= new WebInspector
.ToolbarButton(WebInspector
.UIString("Dock to bottom"), "dock-toolbar-item-bottom");
812 var right
= new WebInspector
.ToolbarButton(WebInspector
.UIString("Dock to right"), "dock-toolbar-item-right");
813 undock
.addEventListener("click", setDockSide
.bind(null, WebInspector
.DockController
.State
.Undocked
));
814 bottom
.addEventListener("click", setDockSide
.bind(null, WebInspector
.DockController
.State
.DockedToBottom
));
815 right
.addEventListener("click", setDockSide
.bind(null, WebInspector
.DockController
.State
.DockedToRight
));
816 undock
.setToggled(WebInspector
.dockController
.dockSide() === WebInspector
.DockController
.State
.Undocked
);
817 bottom
.setToggled(WebInspector
.dockController
.dockSide() === WebInspector
.DockController
.State
.DockedToBottom
);
818 right
.setToggled(WebInspector
.dockController
.dockSide() === WebInspector
.DockController
.State
.DockedToRight
);
821 * @param {string} side
823 function setDockSide(side
)
825 WebInspector
.dockController
.setDockSide(side
);
826 contextMenu
.discard();
829 dockItemToolbar
.appendToolbarItem(undock
);
830 dockItemToolbar
.appendToolbarItem(bottom
);
831 dockItemToolbar
.appendToolbarItem(right
);
833 contextMenu
.appendCustomItem(dockItemElement
);
834 contextMenu
.appendSeparator();
835 contextMenu
.appendItemsAtLocation("mainMenu");
843 WebInspector
.ThrottlingIndicator = function()
845 var networkConditionsSetting
= WebInspector
.moduleSetting("networkConditions");
846 networkConditionsSetting
.addChangeListener(updateVisibility
);
849 function updateVisibility()
851 var throttlingEnabled
= WebInspector
.NetworkManager
.IsThrottlingEnabled(networkConditionsSetting
.get());
852 WebInspector
.inspectorView
.setPanelIcon("network", throttlingEnabled
? "warning-icon" : "", WebInspector
.UIString("Network throttling is enabled"));
859 WebInspector
.Main
.PauseListener = function()
861 WebInspector
.targetManager
.addModelListener(WebInspector
.DebuggerModel
, WebInspector
.DebuggerModel
.Events
.DebuggerPaused
, this._debuggerPaused
, this);
864 WebInspector
.Main
.PauseListener
.prototype = {
866 * @param {!WebInspector.Event} event
868 _debuggerPaused: function(event
)
870 WebInspector
.targetManager
.removeModelListener(WebInspector
.DebuggerModel
, WebInspector
.DebuggerModel
.Events
.DebuggerPaused
, this._debuggerPaused
, this);
871 var debuggerPausedDetails
= /** @type {!WebInspector.DebuggerPausedDetails} */ (event
.data
);
872 var debuggerModel
= /** @type {!WebInspector.DebuggerModel} */ (event
.target
);
873 WebInspector
.context
.setFlavor(WebInspector
.Target
, debuggerModel
.target());
874 WebInspector
.Revealer
.reveal(debuggerPausedDetails
);
881 WebInspector
.Main
.InspectedNodeRevealer = function()
883 WebInspector
.targetManager
.addModelListener(WebInspector
.DOMModel
, WebInspector
.DOMModel
.Events
.NodeInspected
, this._inspectNode
, this);
886 WebInspector
.Main
.InspectedNodeRevealer
.prototype = {
888 * @param {!WebInspector.Event} event
890 _inspectNode: function(event
)
892 var deferredNode
= /** @type {!WebInspector.DeferredDOMNode} */ (event
.data
);
893 WebInspector
.Revealer
.reveal(deferredNode
);
899 * @extends {WebInspector.HelpScreen}
901 WebInspector
.RemoteDebuggingTerminatedScreen = function(reason
)
903 WebInspector
.HelpScreen
.call(this, WebInspector
.UIString("Detached from the target"));
904 var p
= this.helpContentElement
.createChild("p");
905 p
.classList
.add("help-section");
906 p
.createChild("span").textContent
= WebInspector
.UIString("Remote debugging has been terminated with reason: ");
907 p
.createChild("span", "error-message").textContent
= reason
;
909 p
.createChild("span").textContent
= WebInspector
.UIString("Please re-attach to the new target.");
912 WebInspector
.RemoteDebuggingTerminatedScreen
.prototype = {
913 __proto__
: WebInspector
.HelpScreen
.prototype
918 * @extends {WebInspector.HelpScreen}
920 WebInspector
.WorkerTerminatedScreen = function()
922 WebInspector
.HelpScreen
.call(this, WebInspector
.UIString("Inspected worker terminated"));
923 var p
= this.helpContentElement
.createChild("p");
924 p
.classList
.add("help-section");
925 p
.textContent
= WebInspector
.UIString("Inspected worker has terminated. Once it restarts we will attach to it automatically.");
928 WebInspector
.WorkerTerminatedScreen
.prototype = {
930 __proto__
: WebInspector
.HelpScreen
.prototype
933 new WebInspector
.Main();