b6434bf713855d0d5e03b2ce7812035d42afad32
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / Main.js
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
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1.  Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  * 2.  Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16  *     its contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /**
32  * @constructor
33  * @implements {InspectorAgent.Dispatcher}
34  */
35 WebInspector.Main = function()
36 {
37     var boundListener = windowLoaded.bind(this);
38
39     /**
40      * @this {WebInspector.Main}
41      */
42     function windowLoaded()
43     {
44         this._loaded();
45         window.removeEventListener("DOMContentLoaded", boundListener, false);
46     }
47     window.addEventListener("DOMContentLoaded", boundListener, false);
48 }
49
50 WebInspector.Main.prototype = {
51     _registerModules: function()
52     {
53         var configuration;
54         if (!Capabilities.isMainFrontend) {
55             configuration = ["main", "sources", "timeline", "profiles", "console", "codemirror"];
56         } else {
57             configuration = ["main", "elements", "network", "sources", "timeline", "profiles", "resources", "audits", "console", "codemirror", "extensions", "settings"];
58             if (WebInspector.experimentsSettings.layersPanel.isEnabled())
59                 configuration.push("layers");
60         }
61         WebInspector.moduleManager.registerModules(configuration);
62     },
63
64     _createGlobalStatusBarItems: function()
65     {
66         if (WebInspector.inspectElementModeController)
67             WebInspector.inspectorView.appendToLeftToolbar(WebInspector.inspectElementModeController.toggleSearchButton.element);
68
69         WebInspector.inspectorView.appendToRightToolbar(WebInspector.settingsController.statusBarItem);
70         if (WebInspector.dockController.element)
71             WebInspector.inspectorView.appendToRightToolbar(WebInspector.dockController.element);
72
73         if (WebInspector._screencastController)
74             WebInspector.inspectorView.appendToRightToolbar(WebInspector._screencastController.statusBarItem());
75     },
76
77     _createRootView: function()
78     {
79         var rootView = new WebInspector.RootView();
80
81         this._rootSplitView = new WebInspector.SplitView(false, true, WebInspector.dockController.canDock() ? "InspectorView.splitViewState" : "InspectorView.dummySplitViewState", 300, 300);
82         this._rootSplitView.show(rootView.element);
83
84         WebInspector.inspectorView.show(this._rootSplitView.sidebarElement());
85
86         var inspectedPagePlaceholder = new WebInspector.InspectedPagePlaceholder();
87         inspectedPagePlaceholder.show(this._rootSplitView.mainElement());
88
89         WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._updateRootSplitViewOnDockSideChange, this);
90         this._updateRootSplitViewOnDockSideChange();
91
92         rootView.attachToBody();
93     },
94
95     _updateRootSplitViewOnDockSideChange: function()
96     {
97         var dockSide = WebInspector.dockController.dockSide();
98         if (dockSide === WebInspector.DockController.State.Undocked) {
99             this._rootSplitView.toggleResizer(this._rootSplitView.resizerElement(), false);
100             this._rootSplitView.toggleResizer(WebInspector.inspectorView.topResizerElement(), false);
101             this._rootSplitView.hideMain();
102             return;
103         }
104
105         this._rootSplitView.setVertical(dockSide === WebInspector.DockController.State.DockedToLeft || dockSide === WebInspector.DockController.State.DockedToRight);
106         this._rootSplitView.setSecondIsSidebar(dockSide === WebInspector.DockController.State.DockedToRight || dockSide === WebInspector.DockController.State.DockedToBottom);
107         this._rootSplitView.toggleResizer(this._rootSplitView.resizerElement(), true);
108         this._rootSplitView.toggleResizer(WebInspector.inspectorView.topResizerElement(), dockSide === WebInspector.DockController.State.DockedToBottom);
109         this._rootSplitView.showBoth();
110     },
111
112     _calculateWorkerInspectorTitle: function()
113     {
114         var expression = "location.href";
115         if (WebInspector.queryParam("isSharedWorker"))
116             expression += " + (this.name ? ' (' + this.name + ')' : '')";
117         RuntimeAgent.invoke_evaluate({expression:expression, doNotPauseOnExceptionsAndMuteConsole:true, returnByValue: true}, evalCallback);
118
119         /**
120          * @param {?Protocol.Error} error
121          * @param {!RuntimeAgent.RemoteObject} result
122          * @param {boolean=} wasThrown
123          */
124         function evalCallback(error, result, wasThrown)
125         {
126             if (error || wasThrown) {
127                 console.error(error);
128                 return;
129             }
130             InspectorFrontendHost.inspectedURLChanged(result.value);
131         }
132     },
133
134     _loadCompletedForWorkers: function()
135     {
136         // Make sure script execution of dedicated worker is resumed and then paused
137         // on the first script statement in case we autoattached to it.
138         if (WebInspector.queryParam("workerPaused")) {
139             DebuggerAgent.pause();
140             RuntimeAgent.run(calculateTitle.bind(this));
141         } else if (!Capabilities.isMainFrontend) {
142             calculateTitle.call(this);
143         }
144
145         /**
146          * @this {WebInspector.Main}
147          */
148         function calculateTitle()
149         {
150             this._calculateWorkerInspectorTitle();
151         }
152     },
153
154     _resetErrorAndWarningCounts: function()
155     {
156         WebInspector.inspectorView.setErrorAndWarningCounts(0, 0);
157     },
158
159     _updateErrorAndWarningCounts: function()
160     {
161         var errors = WebInspector.console.errors;
162         var warnings = WebInspector.console.warnings;
163         WebInspector.inspectorView.setErrorAndWarningCounts(errors, warnings);
164     },
165
166     _debuggerPaused: function()
167     {
168         WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
169         WebInspector.inspectorView.showPanel("sources");
170     },
171
172     _loaded: function()
173     {
174         if (!InspectorFrontendHost.sendMessageToEmbedder) {
175             var helpScreen = new WebInspector.HelpScreen(WebInspector.UIString("Incompatible Chrome version"));
176             var p = helpScreen.contentElement.createChild("p", "help-section");
177             p.textContent = WebInspector.UIString("Please upgrade to a newer Chrome version (you might need a Dev or Canary build).");
178             helpScreen.showModal();
179             return;
180         }
181
182         InspectorBackend.loadFromJSONIfNeeded("../protocol.json");
183         WebInspector.dockController = new WebInspector.DockController(!!WebInspector.queryParam("can_dock"));
184
185         var onConnectionReady = this._doLoadedDone.bind(this);
186
187         var workerId = WebInspector.queryParam("dedicatedWorkerId");
188         if (workerId) {
189             new WebInspector.ExternalWorkerConnection(workerId, onConnectionReady);
190             return;
191         }
192
193         var ws;
194         if (WebInspector.queryParam("ws")) {
195             ws = "ws://" + WebInspector.queryParam("ws");
196         } else if (WebInspector.queryParam("page")) {
197             var page = WebInspector.queryParam("page");
198             var host = WebInspector.queryParam("host") || window.location.host;
199             ws = "ws://" + host + "/devtools/page/" + page;
200         }
201
202         if (ws) {
203             document.body.classList.add("remote");
204             new InspectorBackendClass.WebSocketConnection(ws, onConnectionReady);
205             return;
206         }
207
208         if (!InspectorFrontendHost.isStub) {
209             new InspectorBackendClass.MainConnection(onConnectionReady);
210             return;
211         }
212
213         InspectorFrontendAPI.dispatchQueryParameters(WebInspector.queryParam("dispatch"));
214         new InspectorBackendClass.StubConnection(onConnectionReady);
215     },
216
217     /**
218      * @param {!InspectorBackendClass.Connection} connection
219      */
220     _doLoadedDone: function(connection)
221     {
222         connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected, onDisconnected);
223
224         /**
225          * @param {!WebInspector.Event} event
226          */
227         function onDisconnected(event)
228         {
229             if (WebInspector._disconnectedScreenWithReasonWasShown)
230                 return;
231             new WebInspector.RemoteDebuggingTerminatedScreen(event.data.reason).showModal();
232         }
233
234         InspectorBackend.setConnection(connection);
235
236         // Install styles and themes
237         WebInspector.installPortStyles();
238
239         if (WebInspector.queryParam("toolbarColor") && WebInspector.queryParam("textColor"))
240             WebInspector.setToolbarColors(WebInspector.queryParam("toolbarColor"), WebInspector.queryParam("textColor"));
241
242         WebInspector.targetManager = new WebInspector.TargetManager();
243         WebInspector.targetManager.createTarget(connection, this._doLoadedDoneWithCapabilities.bind(this));
244     },
245
246     _doLoadedDoneWithCapabilities: function(mainTarget)
247     {
248         new WebInspector.VersionController().updateVersion();
249         WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
250         this._registerShortcuts();
251
252         // set order of some sections explicitly
253         WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
254         WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
255         WebInspector.ShortcutsScreen.registerShortcuts();
256
257         if (WebInspector.experimentsSettings.workersInMainWindow.isEnabled())
258             new WebInspector.WorkerTargetManager(mainTarget, WebInspector.targetManager);
259
260         WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._resetErrorAndWarningCounts, this);
261         WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
262
263         WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
264         WebInspector.networkLog = new WebInspector.NetworkLog();
265
266         WebInspector.zoomManager = new WebInspector.ZoomManager();
267
268         WebInspector.advancedSearchController = new WebInspector.AdvancedSearchController();
269
270         InspectorBackend.registerInspectorDispatcher(this);
271
272         WebInspector.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager();
273         WebInspector.isolatedFileSystemDispatcher = new WebInspector.IsolatedFileSystemDispatcher(WebInspector.isolatedFileSystemManager);
274         WebInspector.workspace = new WebInspector.Workspace(WebInspector.isolatedFileSystemManager.mapping());
275
276         WebInspector.cssModel = new WebInspector.CSSStyleModel(WebInspector.workspace);
277         WebInspector.timelineManager = new WebInspector.TimelineManager();
278         WebInspector.tracingAgent = new WebInspector.TracingAgent();
279
280         if (Capabilities.isMainFrontend) {
281             WebInspector.inspectElementModeController = new WebInspector.InspectElementModeController();
282             WebInspector.workerFrontendManager = new WebInspector.WorkerFrontendManager();
283         } else {
284             mainTarget.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerDisconnected, onWorkerDisconnected);
285         }
286
287         function onWorkerDisconnected()
288         {
289             var screen = new WebInspector.WorkerTerminatedScreen();
290             var listener = hideScreen.bind(null, screen);
291             mainTarget.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener);
292
293             /**
294              * @param {!WebInspector.WorkerTerminatedScreen} screen
295              */
296             function hideScreen(screen)
297             {
298                 mainTarget.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener);
299                 screen.hide();
300             }
301
302             screen.showModal();
303         }
304
305         WebInspector.settingsController = new WebInspector.SettingsController();
306
307         WebInspector.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
308
309         var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
310         var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
311         WebInspector.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
312         WebInspector.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
313         WebInspector.Linkifier.setLinkHandler(new WebInspector.HandlerRegistry.LinkHandler());
314
315         new WebInspector.WorkspaceController(WebInspector.workspace);
316
317         WebInspector.fileSystemWorkspaceProvider = new WebInspector.FileSystemWorkspaceProvider(WebInspector.isolatedFileSystemManager, WebInspector.workspace);
318
319         WebInspector.networkWorkspaceProvider = new WebInspector.SimpleWorkspaceProvider(WebInspector.workspace, WebInspector.projectTypes.Network);
320         new WebInspector.NetworkUISourceCodeProvider(WebInspector.networkWorkspaceProvider, WebInspector.workspace);
321
322         WebInspector.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, WebInspector.debuggerModel, WebInspector.workspace);
323
324         WebInspector.scriptSnippetModel = new WebInspector.ScriptSnippetModel(WebInspector.workspace);
325
326         WebInspector.overridesSupport = new WebInspector.OverridesSupport();
327         WebInspector.overridesSupport.applyInitialOverrides();
328
329         new WebInspector.DebuggerScriptMapping(WebInspector.debuggerModel, WebInspector.workspace, WebInspector.networkWorkspaceProvider);
330         WebInspector.liveEditSupport = new WebInspector.LiveEditSupport(WebInspector.workspace);
331         new WebInspector.CSSStyleSheetMapping(WebInspector.cssModel, WebInspector.workspace, WebInspector.networkWorkspaceProvider);
332         new WebInspector.PresentationConsoleMessageHelper(WebInspector.workspace);
333
334         // Create settings before loading modules.
335         WebInspector.settings.initializeBackendSettings();
336
337         this._registerModules();
338         WebInspector.KeyboardShortcut.registerActions();
339
340         WebInspector.panels = {};
341         WebInspector.inspectorView = new WebInspector.InspectorView();
342         // Screencast controller creates a root view itself.
343         if (mainTarget.canScreencast)
344             this._screencastController = new WebInspector.ScreencastController();
345         else
346             this._createRootView();
347         this._createGlobalStatusBarItems();
348
349         this._addMainEventListeners(document);
350
351         function onResize()
352         {
353             if (WebInspector.settingsController)
354                 WebInspector.settingsController.resize();
355         }
356         window.addEventListener("resize", onResize, true);
357
358         var errorWarningCount = document.getElementById("error-warning-count");
359
360         function showConsole()
361         {
362             WebInspector.console.show();
363         }
364         errorWarningCount.addEventListener("click", showConsole, false);
365         this._updateErrorAndWarningCounts();
366
367         WebInspector.extensionServerProxy.setFrontendReady();
368
369         WebInspector.databaseModel = new WebInspector.DatabaseModel();
370         WebInspector.domStorageModel = new WebInspector.DOMStorageModel();
371         WebInspector.cpuProfilerModel = new WebInspector.CPUProfilerModel();
372
373         InspectorAgent.enable(inspectorAgentEnableCallback.bind(this));
374
375         /**
376          * @this {WebInspector.Main}
377          */
378         function inspectorAgentEnableCallback()
379         {
380             WebInspector.inspectorView.showInitialPanel();
381
382             if (WebInspector.overridesSupport.hasActiveOverrides())
383                 WebInspector.inspectorView.showViewInDrawer("emulation", true);
384
385             WebInspector.settings.showMetricsRulers.addChangeListener(showRulersChanged);
386             function showRulersChanged()
387             {
388                 PageAgent.setShowViewportSizeOnResize(true, WebInspector.settings.showMetricsRulers.get());
389             }
390             showRulersChanged();
391
392             if (this._screencastController)
393                 this._screencastController.initialize();
394         }
395
396         this._loadCompletedForWorkers();
397         InspectorFrontendAPI.loadCompleted();
398         WebInspector.notifications.dispatchEventToListeners(WebInspector.NotificationService.Events.InspectorLoaded);
399     },
400
401     _documentClick: function(event)
402     {
403         var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
404         if (!anchor || !anchor.href || (anchor.target === "_blank"))
405             return;
406
407         // Prevent the link from navigating, since we don't do any navigation by following links normally.
408         event.consume(true);
409
410         function followLink()
411         {
412             if (WebInspector.isBeingEdited(event.target))
413                 return;
414             if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
415                 return;
416
417             var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(anchor.href);
418             if (uiSourceCode) {
419                 WebInspector.Revealer.reveal(new WebInspector.UILocation(uiSourceCode, anchor.lineNumber || 0, anchor.columnNumber || 0));
420                 return;
421             }
422
423             var resource = WebInspector.resourceForURL(anchor.href);
424             if (resource) {
425                 WebInspector.Revealer.reveal(resource);
426                 return;
427             }
428
429             var request = WebInspector.networkLog.requestForURL(anchor.href);
430             if (request) {
431                 WebInspector.Revealer.reveal(request);
432                 return;
433             }
434             InspectorFrontendHost.openInNewTab(anchor.href);
435         }
436
437         if (WebInspector.followLinkTimeout)
438             clearTimeout(WebInspector.followLinkTimeout);
439
440         if (anchor.preventFollowOnDoubleClick) {
441             // Start a timeout if this is the first click, if the timeout is canceled
442             // before it fires, then a double clicked happened or another link was clicked.
443             if (event.detail === 1)
444                 WebInspector.followLinkTimeout = setTimeout(followLink, 333);
445             return;
446         }
447
448         followLink();
449     },
450
451     _registerShortcuts: function()
452     {
453         var shortcut = WebInspector.KeyboardShortcut;
454         var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
455         var keys = [
456             shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta),
457             shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta)
458         ];
459         section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
460
461         keys = [
462             shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
463             shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
464         ];
465         section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
466
467         var toggleConsoleLabel = WebInspector.UIString("Show console");
468         section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
469         var doNotOpenDrawerOnEsc = WebInspector.experimentsSettings.doNotOpenDrawerOnEsc.isEnabled();
470         var toggleDrawerLabel = doNotOpenDrawerOnEsc ? WebInspector.UIString("Hide drawer") : WebInspector.UIString("Toggle drawer");
471         section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), toggleDrawerLabel);
472         section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
473
474         var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut();
475         section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources"));
476
477         var inspectElementModeShortcut = WebInspector.InspectElementModeController.createShortcut();
478         section.addKey(inspectElementModeShortcut, WebInspector.UIString("Select node to inspect"));
479
480         var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
481         section.addKey(openResourceShortcut, WebInspector.UIString("Go to source"));
482
483         if (WebInspector.isMac()) {
484             keys = [
485                 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta),
486                 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
487             ];
488             section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
489         }
490     },
491
492     /**
493      * @param {?Event} event
494      * @return {boolean}
495      */
496     _handleZoomEvent: function(event)
497     {
498         switch (event.keyCode) {
499         case 107: // +
500         case 187: // +
501             InspectorFrontendHost.zoomIn();
502             return true;
503         case 109: // -
504         case 189: // -
505             InspectorFrontendHost.zoomOut();
506             return true;
507         case 48: // 0
508         case 96: // Numpad 0
509             // Zoom reset shortcut does not allow "Shift" when handled by the browser.
510             if (!event.shiftKey) {
511                 InspectorFrontendHost.resetZoom();
512                 return true;
513             }
514             break;
515         }
516         return false;
517     },
518
519     _postDocumentKeyDown: function(event)
520     {
521         if (event.handled)
522             return;
523
524         if (!WebInspector.Dialog.currentInstance() && WebInspector.inspectorView.currentPanel()) {
525             WebInspector.inspectorView.currentPanel().handleShortcut(event);
526             if (event.handled) {
527                 event.consume(true);
528                 return;
529             }
530         }
531
532         if (!WebInspector.Dialog.currentInstance() && WebInspector.advancedSearchController.handleShortcut(event))
533             return;
534         if (!WebInspector.Dialog.currentInstance() && WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.handleShortcut(event))
535             return;
536
537         var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) &&
538             !event.altKey &&
539             !InspectorFrontendHost.isStub;
540         if (!WebInspector.Dialog.currentInstance() && isValidZoomShortcut && this._handleZoomEvent(event)) {
541             event.consume(true);
542             return;
543         }
544         WebInspector.KeyboardShortcut.handleShortcut(event);
545     },
546
547     _documentCanCopy: function(event)
548     {
549         if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel()["handleCopyEvent"])
550             event.preventDefault();
551     },
552
553     _documentCopy: function(event)
554     {
555         if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel()["handleCopyEvent"])
556             WebInspector.inspectorView.currentPanel()["handleCopyEvent"](event);
557     },
558
559     _contextMenuEventFired: function(event)
560     {
561         if (event.handled || event.target.classList.contains("popup-glasspane"))
562             event.preventDefault();
563     },
564
565     _inspectNodeRequested: function(event)
566     {
567         this._updateFocusedNode(event.data);
568     },
569
570     _updateFocusedNode: function(nodeId)
571     {
572         var node = WebInspector.domModel.nodeForId(nodeId);
573         console.assert(node);
574         WebInspector.Revealer.reveal(node);
575     },
576
577     _addMainEventListeners: function(doc)
578     {
579         doc.addEventListener("keydown", this._postDocumentKeyDown.bind(this), false);
580         doc.addEventListener("beforecopy", this._documentCanCopy.bind(this), true);
581         doc.addEventListener("copy", this._documentCopy.bind(this), false);
582         doc.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
583         doc.addEventListener("click", this._documentClick.bind(this), false);
584     },
585
586     /**
587      * @override
588      * @param {!RuntimeAgent.RemoteObject} payload
589      * @param {!Object=} hints
590      */
591     inspect: function(payload, hints)
592     {
593         var object = WebInspector.RemoteObject.fromPayload(payload);
594         if (object.subtype === "node") {
595             object.pushNodeToFrontend(callback);
596             var elementsPanel = /** @type {!WebInspector.ElementsPanel} */ (WebInspector.inspectorView.panel("elements"));
597             elementsPanel.omitDefaultSelection();
598             WebInspector.inspectorView.setCurrentPanel(elementsPanel);
599             return;
600         }
601
602         function callback(nodeId)
603         {
604             elementsPanel.stopOmittingDefaultSelection();
605             WebInspector.Revealer.reveal(WebInspector.domModel.nodeForId(nodeId));
606             if (!WebInspector.inspectorView.drawerVisible() && !WebInspector._notFirstInspectElement)
607                 InspectorFrontendHost.inspectElementCompleted();
608             WebInspector._notFirstInspectElement = true;
609             object.release();
610         }
611
612         if (object.type === "function") {
613             /**
614              * @param {?Protocol.Error} error
615              * @param {!DebuggerAgent.FunctionDetails} response
616              */
617             DebuggerAgent.getFunctionDetails(object.objectId, didGetDetails);
618             return;
619         }
620
621         function didGetDetails(error, response)
622         {
623             object.release();
624
625             if (error) {
626                 console.error(error);
627                 return;
628             }
629
630             var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(response.location);
631             if (!uiLocation)
632                 return;
633
634             // FIXME: Dependency violation.
635             /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.panel("sources")).showUILocation(uiLocation, true);
636         }
637
638         if (hints.copyToClipboard)
639             InspectorFrontendHost.copyText(object.value);
640         object.release();
641     },
642
643     /**
644      * @override
645      * @param {string} reason
646      */
647     detached: function(reason)
648     {
649         WebInspector._disconnectedScreenWithReasonWasShown = true;
650         new WebInspector.RemoteDebuggingTerminatedScreen(reason).showModal();
651     },
652
653     /**
654      * @override
655      */
656     targetCrashed: function()
657     {
658         (new WebInspector.HelpScreenUntilReload(
659             WebInspector.UIString("Inspected target crashed"),
660             WebInspector.UIString("Inspected target has crashed. Once it reloads we will attach to it automatically."))).showModal();
661     },
662
663     /**
664      * @override
665      * @param {number} callId
666      * @param {string} script
667      */
668     evaluateForTestInFrontend: function(callId, script)
669     {
670         WebInspector.evaluateForTestInFrontend(callId, script);
671     }
672 }
673
674 WebInspector.reload = function()
675 {
676     InspectorAgent.reset();
677     window.location.reload();
678 }
679
680 /**
681  * @constructor
682  * @implements {WebInspector.ActionDelegate}
683  */
684 WebInspector.Main.ReloadActionDelegate = function()
685 {
686 }
687
688 WebInspector.Main.ReloadActionDelegate.prototype = {
689     /**
690      * @return {boolean}
691      */
692     handleAction: function()
693     {
694         if (!WebInspector.Dialog.currentInstance()) {
695             WebInspector.debuggerModel.skipAllPauses(true, true);
696             WebInspector.resourceTreeModel.reloadPage(false);
697         }
698         return true;
699     }
700 }
701
702 /**
703  * @constructor
704  * @implements {WebInspector.ActionDelegate}
705  */
706 WebInspector.Main.HardReloadActionDelegate = function()
707 {
708 }
709
710 WebInspector.Main.HardReloadActionDelegate.prototype = {
711     /**
712      * @return {boolean}
713      */
714     handleAction: function()
715     {
716         if (!WebInspector.Dialog.currentInstance()) {
717             WebInspector.debuggerModel.skipAllPauses(true, true);
718             WebInspector.resourceTreeModel.reloadPage(true);
719         }
720         return true;
721     }
722 }
723
724 /**
725  * @constructor
726  * @implements {WebInspector.ActionDelegate}
727  */
728 WebInspector.Main.DebugReloadActionDelegate = function()
729 {
730 }
731
732 WebInspector.Main.DebugReloadActionDelegate.prototype = {
733     /**
734      * @return {boolean}
735      */
736     handleAction: function()
737     {
738         WebInspector.reload();
739         return true;
740     }
741 }
742
743 new WebInspector.Main();
744
745 window.DEBUG = true;
746
747 // These methods are added for backwards compatibility with Devtools CodeSchool extension.
748 // DO NOT REMOVE
749
750 WebInspector.__defineGetter__("inspectedPageURL", function()
751 {
752     return WebInspector.resourceTreeModel.inspectedPageURL();
753 });
754
755 WebInspector.panel = function(name)
756 {
757     return WebInspector.inspectorView.panel(name);
758 }