Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / main / 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     _createGlobalStatusBarItems: function()
52     {
53         var extensions = self.runtime.extensions(WebInspector.StatusBarItem.Provider);
54
55         /**
56          * @param {!Runtime.Extension} left
57          * @param {!Runtime.Extension} right
58          */
59         function orderComparator(left, right)
60         {
61             return left.descriptor()["order"] - right.descriptor()["order"];
62         }
63         extensions.sort(orderComparator);
64         extensions.forEach(function(extension) {
65             var item;
66             switch (extension.descriptor()["location"]) {
67             case "toolbar-left":
68                 item = createItem(extension);
69                 if (item)
70                     WebInspector.inspectorView.appendToLeftToolbar(item);
71                 break;
72             case "toolbar-right":
73                 item = createItem(extension);
74                 if (item)
75                     WebInspector.inspectorView.appendToRightToolbar(item);
76                 break;
77             }
78             if (item && extension.descriptor()["actionId"]) {
79                 item.addEventListener("click", function() {
80                     WebInspector.actionRegistry.execute(extension.descriptor()["actionId"]);
81                 });
82             }
83         });
84
85         function createItem(extension)
86         {
87             var descriptor = extension.descriptor();
88             if (descriptor.className)
89                 return extension.instance().item();
90             return new WebInspector.StatusBarButton(WebInspector.UIString(descriptor["title"]), descriptor["elementClass"]);
91         }
92     },
93
94     _calculateWorkerInspectorTitle: function()
95     {
96         var expression = "location.href";
97         if (WebInspector.queryParam("isSharedWorker"))
98             expression += " + (this.name ? ' (' + this.name + ')' : '')";
99         RuntimeAgent.invoke_evaluate({expression:expression, doNotPauseOnExceptionsAndMuteConsole:true, returnByValue: true}, evalCallback);
100
101         /**
102          * @param {?Protocol.Error} error
103          * @param {!RuntimeAgent.RemoteObject} result
104          * @param {boolean=} wasThrown
105          */
106         function evalCallback(error, result, wasThrown)
107         {
108             if (error || wasThrown) {
109                 console.error(error);
110                 return;
111             }
112             InspectorFrontendHost.inspectedURLChanged(String(result.value));
113         }
114     },
115
116     _loadCompletedForWorkers: function()
117     {
118         // Make sure script execution of dedicated worker or service worker is
119         // resumed and then paused on the first script statement in case we
120         // autoattached to it.
121         if (WebInspector.queryParam("workerPaused")) {
122             pauseAndResume.call(this);
123         } else{
124             RuntimeAgent.isRunRequired(isRunRequiredCallback.bind(this));
125         }
126
127         /**
128          * @this {WebInspector.Main}
129          */
130         function isRunRequiredCallback(error, result)
131         {
132             if (result) {
133                 pauseAndResume.call(this);
134             } else if (WebInspector.isWorkerFrontend()) {
135                 calculateTitle.call(this);
136             }
137         }
138
139         /**
140          * @this {WebInspector.Main}
141          */
142         function pauseAndResume()
143         {
144             DebuggerAgent.pause();
145             RuntimeAgent.run(calculateTitle.bind(this));
146         }
147
148         /**
149          * @this {WebInspector.Main}
150          */
151         function calculateTitle()
152         {
153             this._calculateWorkerInspectorTitle();
154         }
155     },
156
157     _loaded: function()
158     {
159         console.timeStamp("Main._loaded");
160
161         // FIXME: Make toolbox a real app.
162         if (WebInspector.queryParam("toolbox"))
163             return;
164
165         this._createSettings();
166         this._createModuleManager();
167         this._createAppUI();
168     },
169
170     _createSettings: function()
171     {
172         WebInspector.settings = new WebInspector.Settings();
173         WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings(WebInspector.queryParam("experiments") !== null);
174         // This setting is needed for backwards compatibility with Devtools CodeSchool extension. DO NOT REMOVE
175         WebInspector.settings.pauseOnExceptionStateString = new WebInspector.PauseOnExceptionStateSetting();
176         new WebInspector.VersionController().updateVersion();
177     },
178
179     _createModuleManager: function()
180     {
181         console.timeStamp("Main._createModuleManager");
182         self.runtime = new Runtime(allDescriptors);
183
184         // FIXME: define html-per-app, make configuration a part of the app.
185         var configuration = ["main", "elements", "network", "sources", "timeline", "profiler", "resources", "audits", "console", "source_frame", "extensions", "settings"];
186         if (WebInspector.experimentsSettings.layersPanel.isEnabled())
187             configuration.push("layers");
188         if (WebInspector.experimentsSettings.devicesPanel.isEnabled() && !!WebInspector.queryParam("can_dock"))
189             configuration.push("devices");
190         if (WebInspector.experimentsSettings.documentation.isEnabled())
191             configuration.push("documentation");
192         if (WebInspector.isWorkerFrontend())
193             configuration = ["main", "sources", "timeline", "profiler", "console", "source_frame", "extensions"];
194         self.runtime.registerModules(configuration);
195     },
196
197     _createAppUI: function()
198     {
199         console.timeStamp("Main._createApp");
200
201         WebInspector.installPortStyles();
202         if (WebInspector.queryParam("toolbarColor") && WebInspector.queryParam("textColor"))
203             WebInspector.setToolbarColors(WebInspector.queryParam("toolbarColor"), WebInspector.queryParam("textColor"));
204         InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetToolbarColors, updateToolbarColors);
205         /**
206          * @param {!WebInspector.Event} event
207          */
208         function updateToolbarColors(event)
209         {
210             WebInspector.setToolbarColors(/** @type {string} */ (event.data["backgroundColor"]), /** @type {string} */ (event.data["color"]));
211         }
212
213         var canDock = !!WebInspector.queryParam("can_dock");
214         WebInspector.zoomManager = new WebInspector.ZoomManager(InspectorFrontendHost);
215         WebInspector.inspectorView = new WebInspector.InspectorView();
216         WebInspector.ContextMenu.initialize();
217         WebInspector.dockController = new WebInspector.DockController(canDock);
218         WebInspector.overridesSupport = new WebInspector.OverridesSupport(canDock);
219         WebInspector.multitargetConsoleModel = new WebInspector.MultitargetConsoleModel();
220
221         WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
222         // set order of some sections explicitly
223         WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
224         WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
225
226         if (canDock)
227             WebInspector.app = new WebInspector.AdvancedApp();
228         else if (WebInspector.queryParam("remoteFrontend"))
229             WebInspector.app = new WebInspector.ScreencastApp();
230         else
231             WebInspector.app = new WebInspector.SimpleApp();
232
233         // It is important to kick controller lifetime after apps are instantiated.
234         WebInspector.dockController.initialize();
235         WebInspector.app.createRootView();
236
237         // Give UI cycles to repaint, then proceed with creating connection.
238         setTimeout(this._createConnection.bind(this), 0);
239     },
240
241     _createConnection: function()
242     {
243         console.timeStamp("Main._createConnection");
244         InspectorBackend.loadFromJSONIfNeeded("../protocol.json");
245
246         var workerId = WebInspector.queryParam("dedicatedWorkerId");
247         if (workerId) {
248             this._connectionEstablished(new WebInspector.ExternalWorkerConnection(workerId));
249             return;
250         }
251
252         if (WebInspector.queryParam("ws")) {
253             var ws = "ws://" + WebInspector.queryParam("ws");
254             InspectorBackendClass.WebSocketConnection.Create(ws, this._connectionEstablished.bind(this));
255             return;
256         }
257
258         if (!InspectorFrontendHost.isHostedMode()) {
259             this._connectionEstablished(new InspectorBackendClass.MainConnection());
260             return;
261         }
262
263         this._connectionEstablished(new InspectorBackendClass.StubConnection());
264     },
265
266     /**
267      * @param {!InspectorBackendClass.Connection} connection
268      */
269     _connectionEstablished: function(connection)
270     {
271         console.timeStamp("Main._connectionEstablished");
272         connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected, onDisconnected);
273
274         /**
275          * @param {!WebInspector.Event} event
276          */
277         function onDisconnected(event)
278         {
279             if (WebInspector._disconnectedScreenWithReasonWasShown)
280                 return;
281             new WebInspector.RemoteDebuggingTerminatedScreen(event.data.reason).showModal();
282         }
283
284         InspectorBackend.setConnection(connection);
285
286         // Install styles and themes
287         WebInspector.installPortStyles();
288
289         if (WebInspector.queryParam("toolbarColor") && WebInspector.queryParam("textColor"))
290             WebInspector.setToolbarColors(WebInspector.queryParam("toolbarColor"), WebInspector.queryParam("textColor"));
291         InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetToolbarColors, updateToolbarColors);
292         /**
293          * @param {!WebInspector.Event} event
294          */
295         function updateToolbarColors(event)
296         {
297             WebInspector.setToolbarColors(/** @type {string} */ (event.data["backgroundColor"]), /** @type {string} */ (event.data["color"]));
298         }
299         WebInspector.ContextMenu.initialize();
300         WebInspector.targetManager.createTarget(WebInspector.UIString("Main"), connection, this._mainTargetCreated.bind(this));
301         WebInspector.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager();
302         WebInspector.workspace = new WebInspector.Workspace(WebInspector.isolatedFileSystemManager.mapping());
303         WebInspector.networkWorkspaceBinding = new WebInspector.NetworkWorkspaceBinding(WebInspector.workspace);
304         new WebInspector.NetworkUISourceCodeProvider(WebInspector.networkWorkspaceBinding, WebInspector.workspace);
305         new WebInspector.PresentationConsoleMessageHelper(WebInspector.workspace);
306         WebInspector.cssWorkspaceBinding = new WebInspector.CSSWorkspaceBinding();
307         WebInspector.debuggerWorkspaceBinding = new WebInspector.DebuggerWorkspaceBinding(WebInspector.targetManager, WebInspector.workspace, WebInspector.networkWorkspaceBinding);
308         WebInspector.fileSystemWorkspaceBinding = new WebInspector.FileSystemWorkspaceBinding(WebInspector.isolatedFileSystemManager, WebInspector.workspace);
309         WebInspector.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, WebInspector.workspace, WebInspector.targetManager, WebInspector.debuggerWorkspaceBinding);
310         WebInspector.scriptSnippetModel = new WebInspector.ScriptSnippetModel(WebInspector.workspace);
311         this._executionContextSelector = new WebInspector.ExecutionContextSelector();
312
313         if (!WebInspector.isWorkerFrontend())
314             WebInspector.inspectElementModeController = new WebInspector.InspectElementModeController();
315         this._createGlobalStatusBarItems();
316     },
317
318     /**
319      * @param {!WebInspector.Target} mainTarget
320      */
321     _mainTargetCreated: function(mainTarget)
322     {
323         console.timeStamp("Main._mainTargetCreated");
324
325         this._registerShortcuts();
326
327         WebInspector.workerTargetManager = new WebInspector.WorkerTargetManager(mainTarget, WebInspector.targetManager);
328
329         InspectorBackend.registerInspectorDispatcher(this);
330
331         if (WebInspector.isWorkerFrontend())
332             mainTarget.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerDisconnected, onWorkerDisconnected);
333
334         function onWorkerDisconnected()
335         {
336             var screen = new WebInspector.WorkerTerminatedScreen();
337             var listener = hideScreen.bind(null, screen);
338             mainTarget.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener);
339
340             /**
341              * @param {!WebInspector.WorkerTerminatedScreen} screen
342              */
343             function hideScreen(screen)
344             {
345                 mainTarget.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener);
346                 screen.hide();
347             }
348
349             screen.showModal();
350         }
351
352         WebInspector.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
353         var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
354         var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
355         WebInspector.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
356         WebInspector.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
357         WebInspector.Linkifier.setLinkHandler(new WebInspector.HandlerRegistry.LinkHandler());
358         new WebInspector.WorkspaceController(WebInspector.workspace);
359         new WebInspector.RenderingOptions();
360         new WebInspector.Main.PauseListener();
361         new WebInspector.Main.InspectedNodeRevealer();
362
363         this._addMainEventListeners(document);
364
365         WebInspector.extensionServerProxy.setFrontendReady();
366
367         InspectorAgent.enable(inspectorAgentEnableCallback);
368
369         function inspectorAgentEnableCallback()
370         {
371             console.timeStamp("Main.inspectorAgentEnableCallback");
372             WebInspector.app.presentUI(mainTarget);
373             console.timeStamp("Main.inspectorAgentEnableCallbackPresentUI");
374             WebInspector.notifications.dispatchEventToListeners(WebInspector.NotificationService.Events.InspectorUILoadedForTests);
375         }
376
377         WebInspector.actionRegistry = new WebInspector.ActionRegistry();
378         WebInspector.shortcutRegistry = new WebInspector.ShortcutRegistry(WebInspector.actionRegistry);
379         WebInspector.ShortcutsScreen.registerShortcuts();
380         this._registerForwardedShortcuts();
381         this._registerMessageSinkListener();
382
383         this._loadCompletedForWorkers();
384         InspectorFrontendAPI.loadCompleted();
385     },
386
387     _registerForwardedShortcuts: function()
388     {
389         /** @const */ var forwardedActions = ["main.reload", "main.hard-reload"];
390         var actionKeys = WebInspector.shortcutRegistry.keysForActions(forwardedActions).map(WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey);
391
392         actionKeys.push({keyCode: WebInspector.KeyboardShortcut.Keys.F8.code});
393         InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));
394     },
395
396     _registerMessageSinkListener: function()
397     {
398         WebInspector.console.addEventListener(WebInspector.Console.Events.MessageAdded, messageAdded);
399
400         /**
401          * @param {!WebInspector.Event} event
402          */
403         function messageAdded(event)
404         {
405             var message = /** @type {!WebInspector.Console.Message} */ (event.data);
406             if (message.show)
407                 WebInspector.console.show();
408         }
409     },
410
411     _documentClick: function(event)
412     {
413         var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
414         if (!anchor || !anchor.href)
415             return;
416
417         // Prevent the link from navigating, since we don't do any navigation by following links normally.
418         event.consume(true);
419
420         if (anchor.target === "_blank") {
421             InspectorFrontendHost.openInNewTab(anchor.href);
422             return;
423         }
424
425         function followLink()
426         {
427             if (WebInspector.isBeingEdited(event.target))
428                 return;
429             if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
430                 return;
431
432             var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(anchor.href);
433             if (uiSourceCode) {
434                 WebInspector.Revealer.reveal(uiSourceCode.uiLocation(anchor.lineNumber || 0, anchor.columnNumber || 0));
435                 return;
436             }
437
438             var resource = WebInspector.resourceForURL(anchor.href);
439             if (resource) {
440                 WebInspector.Revealer.reveal(resource);
441                 return;
442             }
443
444             var request = WebInspector.networkLog.requestForURL(anchor.href);
445             if (request) {
446                 WebInspector.Revealer.reveal(request);
447                 return;
448             }
449             InspectorFrontendHost.openInNewTab(anchor.href);
450         }
451
452         if (WebInspector.followLinkTimeout)
453             clearTimeout(WebInspector.followLinkTimeout);
454
455         if (anchor.preventFollowOnDoubleClick) {
456             // Start a timeout if this is the first click, if the timeout is canceled
457             // before it fires, then a double clicked happened or another link was clicked.
458             if (event.detail === 1)
459                 WebInspector.followLinkTimeout = setTimeout(followLink, 333);
460             return;
461         }
462
463         followLink();
464     },
465
466     _registerShortcuts: function()
467     {
468         var shortcut = WebInspector.KeyboardShortcut;
469         var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
470         var keys = [
471             shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta),
472             shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta)
473         ];
474         section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
475
476         keys = [
477             shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
478             shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
479         ];
480         section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
481
482         var toggleConsoleLabel = WebInspector.UIString("Show console");
483         section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
484         section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), WebInspector.UIString("Toggle drawer"));
485         if (WebInspector.overridesSupport.responsiveDesignAvailable())
486             section.addKey(shortcut.makeDescriptor("M", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift), WebInspector.UIString("Toggle device mode"));
487         section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
488
489         var advancedSearchShortcutModifier = WebInspector.isMac()
490                 ? WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt
491                 : WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift;
492         var advancedSearchShortcut = shortcut.makeDescriptor("f", advancedSearchShortcutModifier);
493         section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources"));
494
495         var inspectElementModeShortcut = WebInspector.InspectElementModeController.createShortcut();
496         section.addKey(inspectElementModeShortcut, WebInspector.UIString("Select node to inspect"));
497
498         var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("p", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
499         section.addKey(openResourceShortcut, WebInspector.UIString("Go to source"));
500
501         if (WebInspector.isMac()) {
502             keys = [
503                 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta),
504                 shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
505             ];
506             section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
507         }
508     },
509
510     _postDocumentKeyDown: function(event)
511     {
512         if (event.handled)
513             return;
514
515         if (!WebInspector.Dialog.currentInstance() && WebInspector.inspectorView.currentPanel()) {
516             WebInspector.inspectorView.currentPanel().handleShortcut(event);
517             if (event.handled) {
518                 event.consume(true);
519                 return;
520             }
521         }
522
523         WebInspector.shortcutRegistry.handleShortcut(event);
524     },
525
526     _documentCanCopy: function(event)
527     {
528         var panel = WebInspector.inspectorView.currentPanel();
529         if (panel && panel["handleCopyEvent"])
530             event.preventDefault();
531     },
532
533     _documentCopy: function(event)
534     {
535         var panel = WebInspector.inspectorView.currentPanel();
536         if (panel && panel["handleCopyEvent"])
537             panel["handleCopyEvent"](event);
538     },
539
540     _documentCut: function(event)
541     {
542         var panel = WebInspector.inspectorView.currentPanel();
543         if (panel && panel["handleCutEvent"])
544             panel["handleCutEvent"](event);
545     },
546
547     _documentPaste: function(event)
548     {
549         var panel = WebInspector.inspectorView.currentPanel();
550         if (panel && panel["handlePasteEvent"])
551             panel["handlePasteEvent"](event);
552     },
553
554     _contextMenuEventFired: function(event)
555     {
556         if (event.handled || event.target.classList.contains("popup-glasspane"))
557             event.preventDefault();
558     },
559
560     _addMainEventListeners: function(doc)
561     {
562         doc.addEventListener("keydown", this._postDocumentKeyDown.bind(this), false);
563         doc.addEventListener("beforecopy", this._documentCanCopy.bind(this), true);
564         doc.addEventListener("copy", this._documentCopy.bind(this), false);
565         doc.addEventListener("cut", this._documentCut.bind(this), false);
566         doc.addEventListener("paste", this._documentPaste.bind(this), false);
567         doc.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
568         doc.addEventListener("click", this._documentClick.bind(this), false);
569     },
570
571     /**
572      * @override
573      * @param {!RuntimeAgent.RemoteObject} payload
574      * @param {!Object=} hints
575      */
576     inspect: function(payload, hints)
577     {
578         var object = WebInspector.runtimeModel.createRemoteObject(payload);
579         if (object.isNode()) {
580             var nodeObjectInspector = runtime.instance(WebInspector.NodeRemoteObjectInspector, object);
581             if (nodeObjectInspector)
582                 nodeObjectInspector.inspectNodeObject(object);
583             return;
584         }
585
586         if (object.type === "function") {
587             object.functionDetails(didGetDetails);
588             return;
589         }
590
591         /**
592          * @param {?WebInspector.DebuggerModel.FunctionDetails} response
593          */
594         function didGetDetails(response)
595         {
596             object.release();
597
598             if (!response || !response.location)
599                 return;
600
601             WebInspector.Revealer.reveal(WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(response.location));
602         }
603
604         if (hints.copyToClipboard)
605             InspectorFrontendHost.copyText(object.value);
606         object.release();
607     },
608
609     /**
610      * @override
611      * @param {string} reason
612      */
613     detached: function(reason)
614     {
615         WebInspector._disconnectedScreenWithReasonWasShown = true;
616         new WebInspector.RemoteDebuggingTerminatedScreen(reason).showModal();
617     },
618
619     /**
620      * @override
621      */
622     targetCrashed: function()
623     {
624         (new WebInspector.HelpScreenUntilReload(
625             WebInspector.UIString("Inspected target crashed"),
626             WebInspector.UIString("Inspected target has crashed. Once it reloads we will attach to it automatically."))).showModal();
627     },
628
629     /**
630      * @override
631      * @param {number} callId
632      * @param {string} script
633      */
634     evaluateForTestInFrontend: function(callId, script)
635     {
636         WebInspector.evaluateForTestInFrontend(callId, script);
637     }
638 }
639
640 WebInspector.reload = function()
641 {
642     InspectorAgent.reset();
643     window.location.reload();
644 }
645
646 /**
647  * @constructor
648  * @implements {WebInspector.ActionDelegate}
649  */
650 WebInspector.Main.ReloadActionDelegate = function()
651 {
652 }
653
654 WebInspector.Main.ReloadActionDelegate.prototype = {
655     /**
656      * @return {boolean}
657      */
658     handleAction: function()
659     {
660         WebInspector.debuggerModel.skipAllPauses(true, true);
661         WebInspector.resourceTreeModel.reloadPage(false);
662         return true;
663     }
664 }
665
666 /**
667  * @constructor
668  * @implements {WebInspector.ActionDelegate}
669  */
670 WebInspector.Main.HardReloadActionDelegate = function()
671 {
672 }
673
674 WebInspector.Main.HardReloadActionDelegate.prototype = {
675     /**
676      * @return {boolean}
677      */
678     handleAction: function()
679     {
680         WebInspector.debuggerModel.skipAllPauses(true, true);
681         WebInspector.resourceTreeModel.reloadPage(true);
682         return true;
683     }
684 }
685
686 /**
687  * @constructor
688  * @implements {WebInspector.ActionDelegate}
689  */
690 WebInspector.Main.DebugReloadActionDelegate = function()
691 {
692 }
693
694 WebInspector.Main.DebugReloadActionDelegate.prototype = {
695     /**
696      * @return {boolean}
697      */
698     handleAction: function()
699     {
700         WebInspector.reload();
701         return true;
702     }
703 }
704
705 /**
706  * @constructor
707  * @implements {WebInspector.ActionDelegate}
708  */
709 WebInspector.Main.ZoomInActionDelegate = function()
710 {
711 }
712
713 WebInspector.Main.ZoomInActionDelegate.prototype = {
714     /**
715      * @return {boolean}
716      */
717     handleAction: function()
718     {
719         if (InspectorFrontendHost.isHostedMode())
720             return false;
721
722         InspectorFrontendHost.zoomIn();
723         return true;
724     }
725 }
726
727 /**
728  * @constructor
729  * @implements {WebInspector.ActionDelegate}
730  */
731 WebInspector.Main.ZoomOutActionDelegate = function()
732 {
733 }
734
735 WebInspector.Main.ZoomOutActionDelegate.prototype = {
736     /**
737      * @return {boolean}
738      */
739     handleAction: function()
740     {
741         if (InspectorFrontendHost.isHostedMode())
742             return false;
743
744         InspectorFrontendHost.zoomOut();
745         return true;
746     }
747 }
748
749 /**
750  * @constructor
751  * @implements {WebInspector.ActionDelegate}
752  */
753 WebInspector.Main.ZoomResetActionDelegate = function()
754 {
755 }
756
757 WebInspector.Main.ZoomResetActionDelegate.prototype = {
758     /**
759      * @return {boolean}
760      */
761     handleAction: function()
762     {
763         if (InspectorFrontendHost.isHostedMode())
764             return false;
765
766         InspectorFrontendHost.resetZoom();
767         return true;
768     }
769 }
770
771 /**
772  * @constructor
773  * @extends {WebInspector.UISettingDelegate}
774  */
775 WebInspector.Main.ShortcutPanelSwitchSettingDelegate = function()
776 {
777     WebInspector.UISettingDelegate.call(this);
778 }
779
780 WebInspector.Main.ShortcutPanelSwitchSettingDelegate.prototype = {
781     /**
782      * @override
783      * @return {!Element}
784      */
785     settingElement: function()
786     {
787         var modifier = WebInspector.platform() === "mac" ? "Cmd" : "Ctrl";
788         return WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Enable %s + 1-9 shortcut to switch panels", modifier), WebInspector.settings.shortcutPanelSwitch);
789     },
790
791     __proto__: WebInspector.UISettingDelegate.prototype
792 }
793
794 /**
795  * @param {string} ws
796  */
797 WebInspector.Main._addWebSocketTarget = function(ws)
798 {
799     /**
800      * @param {!InspectorBackendClass.Connection} connection
801      */
802     function callback(connection)
803     {
804         WebInspector.targetManager.createTarget(ws, connection);
805     }
806     new InspectorBackendClass.WebSocketConnection(ws, callback);
807 }
808
809 new WebInspector.Main();
810
811 // These methods are added for backwards compatibility with Devtools CodeSchool extension.
812 // DO NOT REMOVE
813
814 WebInspector.__defineGetter__("inspectedPageURL", function()
815 {
816     return WebInspector.resourceTreeModel.inspectedPageURL();
817 });
818
819 /**
820  * @param {string} name
821  * @return {?WebInspector.Panel}
822  */
823 WebInspector.panel = function(name)
824 {
825     return WebInspector.inspectorView.panel(name);
826 }
827
828 /**
829  * @constructor
830  * @implements {WebInspector.StatusBarItem.Provider}
831  */
832 WebInspector.Main.WarningErrorCounter = function()
833 {
834     this._counter = new WebInspector.StatusBarCounter(["error-icon-small", "warning-icon-small"]);
835     this._counter.addEventListener("click", showConsole);
836
837     function showConsole()
838     {
839         WebInspector.console.show();
840     }
841
842     WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this);
843     WebInspector.multitargetConsoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
844 }
845
846 WebInspector.Main.WarningErrorCounter.prototype = {
847     _updateErrorAndWarningCounts: function()
848     {
849         var errors = 0;
850         var warnings = 0;
851         var targets = WebInspector.targetManager.targets();
852         for (var i = 0; i < targets.length; ++i) {
853             errors = errors + targets[i].consoleModel.errors;
854             warnings = warnings + targets[i].consoleModel.warnings;
855         }
856         this._counter.setCounter("error-icon-small", errors, WebInspector.UIString(errors > 1 ? "%d errors" : "%d error", errors));
857         this._counter.setCounter("warning-icon-small", warnings, WebInspector.UIString(warnings > 1 ? "%d warnings" : "%d warning", warnings));
858         WebInspector.inspectorView.toolbarItemResized();
859     },
860
861     /**
862      * @return {?WebInspector.StatusBarItem}
863      */
864     item: function()
865     {
866         return this._counter;
867     }
868 }
869
870 /**
871  * @constructor
872  */
873 WebInspector.Main.PauseListener = function()
874 {
875     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
876 }
877
878 WebInspector.Main.PauseListener.prototype = {
879     /**
880      * @param {!WebInspector.Event} event
881      */
882     _debuggerPaused: function(event)
883     {
884         WebInspector.targetManager.removeModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
885         var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target);
886         WebInspector.context.setFlavor(WebInspector.Target, debuggerModel.target());
887         WebInspector.inspectorView.showPanel("sources");
888     }
889 }
890
891 /**
892  * @constructor
893  */
894 WebInspector.Main.InspectedNodeRevealer = function()
895 {
896     WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeInspected, this._inspectNode, this);
897 }
898
899 WebInspector.Main.InspectedNodeRevealer.prototype = {
900     /**
901      * @param {!WebInspector.Event} event
902      */
903     _inspectNode: function(event)
904     {
905         WebInspector.Revealer.reveal(/** @type {!WebInspector.DOMNode} */ (event.data));
906     }
907 }