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("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"]);
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));
290 if (!InspectorFrontendHost
.isHostedMode()) {
291 this._connectionEstablished(new InspectorBackendClass
.MainConnection());
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
)
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();
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
);
382 WebInspector
.console
.show();
386 _documentClick: function(event
)
388 var target
= event
.target
;
389 if (target
.shadowRoot
)
390 target
= event
.deepElementFromPoint();
394 var anchor
= target
.enclosingNodeOrSelfWithNodeName("a");
395 if (!anchor
|| !anchor
.href
)
398 // Prevent the link from navigating, since we don't do any navigation by following links normally.
401 if (anchor
.preventFollow
)
404 function followLink()
406 if (WebInspector
.isBeingEdited(target
))
408 if (WebInspector
.openAnchorLocationRegistry
.dispatch({ url
: anchor
.href
, lineNumber
: anchor
.lineNumber
}))
411 var uiSourceCode
= WebInspector
.networkMapping
.uiSourceCodeForURLForAnyTarget(anchor
.href
);
413 WebInspector
.Revealer
.reveal(uiSourceCode
.uiLocation(anchor
.lineNumber
|| 0, anchor
.columnNumber
|| 0));
417 var resource
= WebInspector
.resourceForURL(anchor
.href
);
419 WebInspector
.Revealer
.reveal(resource
);
423 var request
= WebInspector
.NetworkLog
.requestForURL(anchor
.href
);
425 WebInspector
.Revealer
.reveal(request
);
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);
442 if (!anchor
.classList
.contains("webkit-html-external-link"))
445 InspectorFrontendHost
.openInNewTab(anchor
.href
);
448 _registerShortcuts: function()
450 var shortcut
= WebInspector
.KeyboardShortcut
;
451 var section
= WebInspector
.shortcutsScreen
.section(WebInspector
.UIString("All Panels"));
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"));
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()) {
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
)
499 var target
= event
.deepActiveElement();
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
);
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
);
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
));
587 if (object
.type
=== "function") {
588 object
.functionDetails(didGetDetails
);
593 * @param {?WebInspector.DebuggerModel.FunctionDetails} response
595 function didGetDetails(response
)
599 if (!response
|| !response
.location
)
602 WebInspector
.Revealer
.reveal(WebInspector
.debuggerWorkspaceBinding
.rawLocationToUILocation(response
.location
));
605 if (hints
.copyToClipboard
)
606 InspectorFrontendHost
.copyText(object
.value
);
612 * @param {string} reason
614 detached: function(reason
)
616 WebInspector
._disconnectedScreenWithReasonWasShown
= true;
617 new WebInspector
.RemoteDebuggingTerminatedScreen(reason
).showModal();
623 targetCrashed: function()
625 var debuggerModel
= WebInspector
.DebuggerModel
.fromTarget(this._mainTarget
);
628 (new WebInspector
.HelpScreenUntilReload(
630 WebInspector
.UIString("Inspected target disconnected"),
631 WebInspector
.UIString("Inspected target disconnected. Once it reloads we will attach to it automatically."))).showModal();
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();
654 * @implements {WebInspector.ActionDelegate}
656 WebInspector
.Main
.ReloadActionDelegate = function()
660 WebInspector
.Main
.ReloadActionDelegate
.prototype = {
663 * @param {!WebInspector.Context} context
664 * @param {string} actionId
666 handleAction: function(context
, actionId
)
670 WebInspector
.Main
._reloadPage(false);
672 case "main.hard-reload":
673 WebInspector
.Main
._reloadPage(true);
675 case "main.debug-reload":
676 WebInspector
.reload();
684 * @implements {WebInspector.ActionDelegate}
686 WebInspector
.Main
.ZoomActionDelegate = function()
690 WebInspector
.Main
.ZoomActionDelegate
.prototype = {
693 * @param {!WebInspector.Context} context
694 * @param {string} actionId
696 handleAction: function(context
, actionId
)
698 if (InspectorFrontendHost
.isHostedMode())
703 InspectorFrontendHost
.zoomIn();
705 case "main.zoom-out":
706 InspectorFrontendHost
.zoomOut();
708 case "main.zoom-reset":
709 InspectorFrontendHost
.resetZoom();
717 * @implements {WebInspector.ActionDelegate}
719 WebInspector
.Main
.InspectDevicesActionDelegate = function()
723 WebInspector
.Main
.InspectDevicesActionDelegate
.prototype = {
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())
742 if (WebInspector
.targetManager
.mainTarget().isServiceWorker())
744 WebInspector
.targetManager
.reloadPage(hard
);
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
);
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()
785 var revokedErrors
= 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();
801 * @return {?WebInspector.ToolbarItem}
805 return this._counter
;
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 = {
822 * @return {?WebInspector.ToolbarItem}
830 * @param {!WebInspector.Event} event
832 _mouseDown: function(event
)
834 var contextMenu
= new WebInspector
.ContextMenu(/** @type {!Event} */(event
.data
),
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");
882 WebInspector
.NetworkPanelIndicator = function()
884 var networkConditionsSetting
= WebInspector
.moduleSetting("networkConditions");
885 networkConditionsSetting
.addChangeListener(updateVisibility
);
886 var blockedURLsSetting
= WebInspector
.moduleSetting("blockedURLs");
887 blockedURLsSetting
.addChangeListener(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"));
897 WebInspector
.inspectorView
.setPanelIcon("network", "", "");
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
);
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
);
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
;
955 p
.createChild("span").textContent
= WebInspector
.UIString("Please re-attach to the new target.");
958 WebInspector
.RemoteDebuggingTerminatedScreen
.prototype = {
959 __proto__
: WebInspector
.HelpScreen
.prototype
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();