Web Inspector: Workspace should support several projects and should not have temporar...
[WebKit-https.git] / Source / WebCore / inspector / front-end / ScriptsPanel.js
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2011 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 importScript("BreakpointsSidebarPane.js");
28 importScript("CallStackSidebarPane.js");
29 importScript("FilteredItemSelectionDialog.js");
30 importScript("JavaScriptSourceFrame.js");
31 importScript("NavigatorOverlayController.js");
32 importScript("NavigatorView.js");
33 importScript("RevisionHistoryView.js");
34 importScript("ScopeChainSidebarPane.js");
35 importScript("ScriptsNavigator.js");
36 importScript("ScriptsSearchScope.js");
37 importScript("SnippetJavaScriptSourceFrame.js");
38 importScript("StyleSheetOutlineDialog.js");
39 importScript("TabbedEditorContainer.js");
40 importScript("UISourceCodeFrame.js");
41 importScript("WatchExpressionsSidebarPane.js");
42 importScript("WorkersSidebarPane.js");
43
44 /**
45  * @constructor
46  * @implements {WebInspector.TabbedEditorContainerDelegate}
47  * @implements {WebInspector.ContextMenu.Provider}
48  * @extends {WebInspector.Panel}
49  * @param {WebInspector.Workspace=} workspaceForTest
50  */
51 WebInspector.ScriptsPanel = function(workspaceForTest)
52 {
53     WebInspector.Panel.call(this, "scripts");
54     this.registerRequiredCSS("scriptsPanel.css");
55
56     WebInspector.settings.navigatorWasOnceHidden = WebInspector.settings.createSetting("navigatorWasOnceHidden", false);
57     WebInspector.settings.debuggerSidebarHidden = WebInspector.settings.createSetting("debuggerSidebarHidden", false);
58
59     this._workspace = workspaceForTest || WebInspector.workspace;
60
61     function viewGetter()
62     {
63         return this.visibleView;
64     }
65     WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
66
67     var helpSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
68     this.debugToolbar = this._createDebugToolbar();
69
70     const initialDebugSidebarWidth = 225;
71     const minimumDebugSidebarWidthPercent = 50;
72     this.createSidebarView(this.element, WebInspector.SidebarView.SidebarPosition.Right, initialDebugSidebarWidth);
73     this.splitView.element.id = "scripts-split-view";
74     this.splitView.setMinimumSidebarWidth(Preferences.minScriptsSidebarWidth);
75     this.splitView.setMinimumMainWidthPercent(minimumDebugSidebarWidthPercent);
76
77     this.sidebarElement.appendChild(this.debugToolbar);
78
79     this.debugSidebarResizeWidgetElement = document.createElement("div");
80     this.debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget";
81     this.splitView.installResizer(this.debugSidebarResizeWidgetElement);
82
83     // Create scripts navigator
84     const initialNavigatorWidth = 225;
85     const minimumViewsContainerWidthPercent = 50;
86     this.editorView = new WebInspector.SidebarView(WebInspector.SidebarView.SidebarPosition.Left, "scriptsPanelNavigatorSidebarWidth", initialNavigatorWidth);
87     this.editorView.element.tabIndex = 0;
88
89     this.editorView.setMinimumSidebarWidth(Preferences.minScriptsSidebarWidth);
90     this.editorView.setMinimumMainWidthPercent(minimumViewsContainerWidthPercent);
91     this.editorView.show(this.splitView.mainElement);
92
93     this._navigator = new WebInspector.ScriptsNavigator();
94     this._navigator.view.show(this.editorView.sidebarElement);
95
96     this._editorContainer = new WebInspector.TabbedEditorContainer(this, "previouslyViewedFiles");
97     this._editorContainer.show(this.editorView.mainElement);
98
99     this._navigatorController = new WebInspector.NavigatorOverlayController(this.editorView, this._navigator.view, this._editorContainer.view);
100
101     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ScriptSelected, this._scriptSelected, this);
102     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.SnippetCreationRequested, this._snippetCreationRequested, this);
103     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ItemRenamingRequested, this._itemRenamingRequested, this);
104     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.FileRenamed, this._fileRenamed, this);
105
106     this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
107     this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
108
109     this.splitView.mainElement.appendChild(this.debugSidebarResizeWidgetElement);
110
111     this.sidebarPanes = {};
112     this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
113     this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
114     this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
115     this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.breakpointManager, this._showSourceLine.bind(this));
116     this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane;
117     this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
118     this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
119
120     if (InspectorFrontendHost.canInspectWorkers() && !WebInspector.WorkerManager.isWorkerFrontend()) {
121         WorkerAgent.enable();
122         this.sidebarPanes.workerList = new WebInspector.WorkersSidebarPane(WebInspector.workerManager);
123     }
124
125     this._debugSidebarContentsElement = document.createElement("div");
126     this._debugSidebarContentsElement.id = "scripts-debug-sidebar-contents";
127     this.sidebarElement.appendChild(this._debugSidebarContentsElement);
128
129     for (var pane in this.sidebarPanes) {
130         if (this.sidebarPanes[pane] === this.sidebarPanes.domBreakpoints)
131             continue;
132         this._debugSidebarContentsElement.appendChild(this.sidebarPanes[pane].element);
133     }
134
135     this.sidebarPanes.callstack.expanded = true;
136
137     this.sidebarPanes.scopechain.expanded = true;
138     this.sidebarPanes.jsBreakpoints.expanded = true;
139
140     this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));
141     this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.EvaluateSelectionInConsole, this._evaluateSelectionInConsole.bind(this));
142     this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.GoToMember, this._showOutlineDialog.bind(this));
143     this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
144
145     var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel.");
146     var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower.");
147     var panelEnablerButton = WebInspector.UIString("Enable Debugging");
148
149     this.panelEnablerView = new WebInspector.PanelEnablerView("scripts", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton);
150     this.panelEnablerView.addEventListener("enable clicked", this._enableDebugging, this);
151
152     this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item");
153     this.enableToggleButton.addEventListener("click", this._toggleDebugging, this);
154     if (!Capabilities.debuggerCausesRecompilation)
155         this.enableToggleButton.element.addStyleClass("hidden");
156
157     this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
158     this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this);
159
160     this._toggleFormatSourceButton = new WebInspector.StatusBarButton(WebInspector.UIString("Pretty print"), "scripts-toggle-pretty-print-status-bar-item");
161     this._toggleFormatSourceButton.toggled = false;
162     this._toggleFormatSourceButton.addEventListener("click", this._toggleFormatSource, this);
163
164     this._scriptViewStatusBarItemsContainer = document.createElement("div");
165     this._scriptViewStatusBarItemsContainer.style.display = "inline-block";
166
167     this._installDebuggerSidebarController();
168
169     this._sourceFramesByUISourceCode = new Map();
170     this._updateDebuggerButtons();
171     this._pauseOnExceptionStateChanged();
172     if (WebInspector.debuggerModel.isPaused())
173         this._debuggerPaused();
174
175     WebInspector.settings.pauseOnExceptionStateString.addChangeListener(this._pauseOnExceptionStateChanged, this);
176     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
177     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerWasDisabled, this);
178     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
179     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
180     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
181     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
182     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ExecutionLineChanged, this._executionLineChanged, this);
183     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
184
185     WebInspector.startBatchUpdate();
186     var uiSourceCodes = this._workspace.uiSourceCodes();
187     for (var i = 0; i < uiSourceCodes.length; ++i)
188         this._addUISourceCode(uiSourceCodes[i]);
189     WebInspector.endBatchUpdate();
190
191     this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
192     this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
193     this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset.bind(this), this);
194     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
195
196     WebInspector.advancedSearchController.registerSearchScope(new WebInspector.ScriptsSearchScope(this._workspace));
197 }
198
199 WebInspector.ScriptsPanel.prototype = {
200     get statusBarItems()
201     {
202         return [this.enableToggleButton.element, this._pauseOnExceptionButton.element, this._toggleFormatSourceButton.element, this._scriptViewStatusBarItemsContainer];
203     },
204
205     defaultFocusedElement: function()
206     {
207         return this._navigator.view.defaultFocusedElement();
208     },
209
210     get paused()
211     {
212         return this._paused;
213     },
214
215     wasShown: function()
216     {
217         WebInspector.Panel.prototype.wasShown.call(this);
218         this._debugSidebarContentsElement.insertBefore(this.sidebarPanes.domBreakpoints.element, this.sidebarPanes.xhrBreakpoints.element);
219         this.sidebarPanes.watchExpressions.show();
220
221         this._navigatorController.wasShown();
222     },
223
224     willHide: function()
225     {
226         WebInspector.Panel.prototype.willHide.call(this);
227         WebInspector.closeViewInDrawer();
228     },
229
230     /**
231      * @param {WebInspector.Event} event
232      */
233     _uiSourceCodeAdded: function(event)
234     {
235         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
236         this._addUISourceCode(uiSourceCode);
237     },
238
239     /**
240      * @param {WebInspector.UISourceCode} uiSourceCode
241      */
242     _addUISourceCode: function(uiSourceCode)
243     {
244         if (this._toggleFormatSourceButton.toggled)
245             uiSourceCode.setFormatted(true);
246         var projectName = uiSourceCode.project().name();
247         if (uiSourceCode.project().isServiceProject())
248             return;
249         this._editorContainer.addUISourceCode(uiSourceCode);
250         this._navigator.addUISourceCode(uiSourceCode);
251         // Replace debugger script-based uiSourceCode with a network-based one.
252         var currentUISourceCode = this._currentUISourceCode;
253         if (currentUISourceCode && currentUISourceCode.project().isServiceProject() && currentUISourceCode !== uiSourceCode && currentUISourceCode.url === uiSourceCode.url) {
254             this._showFile(uiSourceCode);
255             this._editorContainer.removeUISourceCode(currentUISourceCode);
256         }
257     },
258
259     _uiSourceCodeRemoved: function(event)
260     {
261         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
262         this._removeUISourceCodes([uiSourceCode]);
263     },
264
265     /**
266      * @param {Array.<WebInspector.UISourceCode>} uiSourceCodes
267      */
268     _removeUISourceCodes: function(uiSourceCodes)
269     {
270         for (var i = 0; i < uiSourceCodes.length; ++i) {
271             this._navigator.removeUISourceCode(uiSourceCodes[i]);
272             this._removeSourceFrame(uiSourceCodes[i]);
273         }
274         this._editorContainer.removeUISourceCodes(uiSourceCodes);
275     },
276
277     _consoleCommandEvaluatedInSelectedCallFrame: function(event)
278     {
279         this.sidebarPanes.scopechain.update(WebInspector.debuggerModel.selectedCallFrame());
280     },
281
282     _debuggerPaused: function()
283     {
284         var details = WebInspector.debuggerModel.debuggerPausedDetails();
285
286         this._paused = true;
287         this._waitingToPause = false;
288         this._stepping = false;
289
290         this._updateDebuggerButtons();
291
292         WebInspector.inspectorView.setCurrentPanel(this);
293         this.sidebarPanes.callstack.update(details.callFrames);
294
295         if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) {
296             this.sidebarPanes.domBreakpoints.highlightBreakpoint(details.auxData);
297             function didCreateBreakpointHitStatusMessage(element)
298             {
299                 this.sidebarPanes.callstack.setStatus(element);
300             }
301             this.sidebarPanes.domBreakpoints.createBreakpointHitStatusMessage(details.auxData, didCreateBreakpointHitStatusMessage.bind(this));
302         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) {
303             var eventName = details.auxData.eventName;
304             this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.auxData.eventName);
305             var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);
306             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
307         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) {
308             this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);
309             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
310         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception)
311             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData.description));
312         else if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert)
313             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));
314         else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation)
315             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"]));
316         else {
317             function didGetUILocation(uiLocation)
318             {
319                 var breakpoint = WebInspector.breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber);
320                 if (!breakpoint)
321                     return;
322                 this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);
323                 this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
324             }
325             if (details.callFrames.length) 
326                 details.callFrames[0].createLiveLocation(didGetUILocation.bind(this));
327             else
328                 console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
329         }
330
331         this._showDebuggerSidebar();
332         this._toggleDebuggerSidebarButton.setEnabled(false);
333         window.focus();
334         InspectorFrontendHost.bringToFront();
335     },
336
337     _debuggerResumed: function()
338     {
339         this._paused = false;
340         this._waitingToPause = false;
341         this._stepping = false;
342
343         this._clearInterface();
344         this._toggleDebuggerSidebarButton.setEnabled(true);
345     },
346
347     _debuggerWasEnabled: function()
348     {
349         this._updateDebuggerButtons();
350     },
351
352     _debuggerWasDisabled: function()
353     {
354         this._debuggerReset();
355     },
356
357     _debuggerReset: function()
358     {
359         this._debuggerResumed();
360         this.sidebarPanes.watchExpressions.reset();
361     },
362
363     _projectWillReset: function(event)
364     {
365         var project = event.data;
366         var uiSourceCodes = project.uiSourceCodes();
367         this._removeUISourceCodes(uiSourceCodes);
368         if (project.name() === WebInspector.projectNames.Network)
369             this._editorContainer.reset();
370     },
371
372     get visibleView()
373     {
374         return this._editorContainer.visibleView;
375     },
376
377     _updateScriptViewStatusBarItems: function()
378     {
379         this._scriptViewStatusBarItemsContainer.removeChildren();
380
381         var sourceFrame = this.visibleView;
382         if (sourceFrame) {
383             var statusBarItems = sourceFrame.statusBarItems() || [];
384             for (var i = 0; i < statusBarItems.length; ++i)
385                 this._scriptViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
386         }
387     },
388
389     canShowAnchorLocation: function(anchor)
390     {
391         if (WebInspector.debuggerModel.debuggerEnabled() && anchor.uiSourceCode)
392             return true;
393         var uiSourceCodes = this._workspace.project(WebInspector.projectNames.Network).uiSourceCodes();
394         for (var i = 0; i < uiSourceCodes.length; ++i) {
395             if (uiSourceCodes[i].url === anchor.href) {
396                 anchor.uiSourceCode = uiSourceCodes[i];
397                 return true;
398             }
399         }
400         return false;
401     },
402
403     showAnchorLocation: function(anchor)
404     {
405         this._showSourceLine(anchor.uiSourceCode, anchor.lineNumber);
406     },
407
408     /**
409      * @param {WebInspector.UISourceCode} uiSourceCode
410      * @param {number} lineNumber
411      */
412     showUISourceCode: function(uiSourceCode, lineNumber)
413     {
414         this._showSourceLine(uiSourceCode, lineNumber);
415     },
416
417     /**
418      * @param {WebInspector.UISourceCode} uiSourceCode
419      * @param {number=} lineNumber
420      */
421     _showSourceLine: function(uiSourceCode, lineNumber)
422     {
423         var sourceFrame = this._showFile(uiSourceCode);
424         if (typeof lineNumber === "number")
425             sourceFrame.highlightLine(lineNumber);
426         sourceFrame.focus();
427
428         WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
429             action: WebInspector.UserMetrics.UserActionNames.OpenSourceLink,
430             url: uiSourceCode.url,
431             lineNumber: lineNumber
432         });
433     },
434
435     /**
436      * @param {WebInspector.UISourceCode} uiSourceCode
437      * @return {WebInspector.SourceFrame}
438      */
439     _showFile: function(uiSourceCode)
440     {
441         var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
442         if (this._currentUISourceCode === uiSourceCode)
443             return sourceFrame;
444         this._currentUISourceCode = uiSourceCode;
445
446         if (this._navigator.isScriptSourceAdded(uiSourceCode))
447             this._navigator.revealUISourceCode(uiSourceCode);
448         this._editorContainer.showFile(uiSourceCode);
449         this._updateScriptViewStatusBarItems();
450
451         return sourceFrame;
452     },
453
454     /**
455      * @param {WebInspector.UISourceCode} uiSourceCode
456      * @return {WebInspector.SourceFrame}
457      */
458     _createSourceFrame: function(uiSourceCode)
459     {
460         var sourceFrame;
461         switch (uiSourceCode.contentType()) {
462         case WebInspector.resourceTypes.Script:
463             if (uiSourceCode.isSnippet)
464                 sourceFrame = new WebInspector.SnippetJavaScriptSourceFrame(this, uiSourceCode);
465             else
466                 sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
467             break;
468         case WebInspector.resourceTypes.Document:
469             sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
470             break;
471         case WebInspector.resourceTypes.Stylesheet:
472         default:
473             sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
474         break;
475         }
476         this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame);
477         return sourceFrame;
478     },
479
480     /**
481      * @param {WebInspector.UISourceCode} uiSourceCode
482      * @return {WebInspector.SourceFrame}
483      */
484     _getOrCreateSourceFrame: function(uiSourceCode)
485     {
486         return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._createSourceFrame(uiSourceCode);
487     },
488
489     /**
490      * @param {WebInspector.UISourceCode} uiSourceCode
491      * @return {WebInspector.SourceFrame}
492      */
493     viewForFile: function(uiSourceCode)
494     {
495         return this._getOrCreateSourceFrame(uiSourceCode);
496     },
497
498     /**
499      * @param {WebInspector.UISourceCode} uiSourceCode
500      */
501     _removeSourceFrame: function(uiSourceCode)
502     {
503         var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
504         if (!sourceFrame)
505             return;
506         this._sourceFramesByUISourceCode.remove(uiSourceCode);
507         sourceFrame.detach();
508     },
509
510     _clearCurrentExecutionLine: function()
511     {
512         if (this._executionSourceFrame)
513             this._executionSourceFrame.clearExecutionLine();
514         delete this._executionSourceFrame;
515     },
516
517     _executionLineChanged: function(event)
518     {
519         var uiLocation = event.data;
520
521         this._clearCurrentExecutionLine();
522         if (!uiLocation)
523             return;
524         var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode);
525         sourceFrame.setExecutionLine(uiLocation.lineNumber);
526         this._executionSourceFrame = sourceFrame;
527     },
528
529     _revealExecutionLine: function(uiLocation)
530     {
531         var uiSourceCode = uiLocation.uiSourceCode;
532         // Some scripts (anonymous and snippets evaluations) are not added to files select by default.
533         if (this._currentUISourceCode && this._currentUISourceCode.scriptFile() && this._currentUISourceCode.scriptFile().isDivergingFromVM())
534             return;
535         if (this._toggleFormatSourceButton.toggled && !uiSourceCode.formatted())
536             uiSourceCode.setFormatted(true);
537         var sourceFrame = this._showFile(uiSourceCode);
538         sourceFrame.revealLine(uiLocation.lineNumber);
539         sourceFrame.focus();
540     },
541
542     _callFrameSelected: function(event)
543     {
544         var callFrame = event.data;
545
546         if (!callFrame)
547             return;
548
549         this.sidebarPanes.scopechain.update(callFrame);
550         this.sidebarPanes.watchExpressions.refreshExpressions();
551         this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
552         callFrame.createLiveLocation(this._revealExecutionLine.bind(this));
553     },
554
555     _editorClosed: function(event)
556     {
557         this._navigatorController.hideNavigatorOverlay();
558         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
559
560         if (this._currentUISourceCode === uiSourceCode)
561             delete this._currentUISourceCode;
562
563         // ScriptsNavigator does not need to update on EditorClosed.
564         this._updateScriptViewStatusBarItems();
565         WebInspector.searchController.resetSearch();
566     },
567
568     _editorSelected: function(event)
569     {
570         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
571         var sourceFrame = this._showFile(uiSourceCode);
572         this._navigatorController.hideNavigatorOverlay();
573         sourceFrame.focus();
574         WebInspector.searchController.resetSearch();
575     },
576
577     _scriptSelected: function(event)
578     {
579         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data.uiSourceCode);
580         var sourceFrame = this._showFile(uiSourceCode);
581         this._navigatorController.hideNavigatorOverlay();
582         if (sourceFrame && event.data.focusSource)
583             sourceFrame.focus();
584     },
585
586     _pauseOnExceptionStateChanged: function()
587     {
588         var pauseOnExceptionsState = WebInspector.settings.pauseOnExceptionStateString.get();
589         switch (pauseOnExceptionsState) {
590         case WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions:
591             this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
592             break;
593         case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions:
594             this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
595             break;
596         case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions:
597             this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
598             break;
599         }
600         this._pauseOnExceptionButton.state = pauseOnExceptionsState;
601     },
602
603     _updateDebuggerButtons: function()
604     {
605         if (WebInspector.debuggerModel.debuggerEnabled()) {
606             this.enableToggleButton.title = WebInspector.UIString("Debugging enabled. Click to disable.");
607             this.enableToggleButton.toggled = true;
608             this._pauseOnExceptionButton.visible = true;
609             this.panelEnablerView.detach();
610         } else {
611             this.enableToggleButton.title = WebInspector.UIString("Debugging disabled. Click to enable.");
612             this.enableToggleButton.toggled = false;
613             this._pauseOnExceptionButton.visible = false;
614             this.panelEnablerView.show(this.element);
615         }
616
617         if (this._paused) {
618             this._updateButtonTitle(this.pauseButton, WebInspector.UIString("Resume script execution (%s)."))
619             this.pauseButton.addStyleClass("paused");
620
621             this.pauseButton.disabled = false;
622             this.stepOverButton.disabled = false;
623             this.stepIntoButton.disabled = false;
624             this.stepOutButton.disabled = false;
625
626             this.debuggerStatusElement.textContent = WebInspector.UIString("Paused");
627         } else {
628             this._updateButtonTitle(this.pauseButton, WebInspector.UIString("Pause script execution (%s)."))
629             this.pauseButton.removeStyleClass("paused");
630
631             this.pauseButton.disabled = this._waitingToPause;
632             this.stepOverButton.disabled = true;
633             this.stepIntoButton.disabled = true;
634             this.stepOutButton.disabled = true;
635
636             if (this._waitingToPause)
637                 this.debuggerStatusElement.textContent = WebInspector.UIString("Pausing");
638             else if (this._stepping)
639                 this.debuggerStatusElement.textContent = WebInspector.UIString("Stepping");
640             else
641                 this.debuggerStatusElement.textContent = "";
642         }
643     },
644
645     _clearInterface: function()
646     {
647         this.sidebarPanes.callstack.update(null);
648         this.sidebarPanes.scopechain.update(null);
649         this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
650         this.sidebarPanes.domBreakpoints.clearBreakpointHighlight();
651         this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
652         this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
653
654         this._clearCurrentExecutionLine();
655         this._updateDebuggerButtons();
656     },
657
658     _enableDebugging: function()
659     {
660         this._toggleDebugging(this.panelEnablerView.alwaysEnabled);
661     },
662
663     _toggleDebugging: function(optionalAlways)
664     {
665         this._paused = false;
666         this._waitingToPause = false;
667         this._stepping = false;
668
669         if (WebInspector.debuggerModel.debuggerEnabled()) {
670             WebInspector.settings.debuggerEnabled.set(false);
671             WebInspector.debuggerModel.disableDebugger();
672         } else {
673             WebInspector.settings.debuggerEnabled.set(!!optionalAlways);
674             WebInspector.debuggerModel.enableDebugger();
675         }
676     },
677
678     _togglePauseOnExceptions: function()
679     {
680         var nextStateMap = {};
681         var stateEnum = WebInspector.DebuggerModel.PauseOnExceptionsState;
682         nextStateMap[stateEnum.DontPauseOnExceptions] = stateEnum.PauseOnAllExceptions;
683         nextStateMap[stateEnum.PauseOnAllExceptions] = stateEnum.PauseOnUncaughtExceptions;
684         nextStateMap[stateEnum.PauseOnUncaughtExceptions] = stateEnum.DontPauseOnExceptions;
685         WebInspector.settings.pauseOnExceptionStateString.set(nextStateMap[this._pauseOnExceptionButton.state]);
686     },
687
688     _togglePause: function()
689     {
690         if (this._paused) {
691             this._paused = false;
692             this._waitingToPause = false;
693             DebuggerAgent.resume();
694         } else {
695             this._stepping = false;
696             this._waitingToPause = true;
697             DebuggerAgent.pause();
698         }
699
700         this._clearInterface();
701     },
702
703     _stepOverClicked: function()
704     {
705         if (!this._paused)
706             return;
707
708         this._paused = false;
709         this._stepping = true;
710
711         this._clearInterface();
712
713         DebuggerAgent.stepOver();
714     },
715
716     _stepIntoClicked: function()
717     {
718         if (!this._paused)
719             return;
720
721         this._paused = false;
722         this._stepping = true;
723
724         this._clearInterface();
725
726         DebuggerAgent.stepInto();
727     },
728
729     _stepOutClicked: function()
730     {
731         if (!this._paused)
732             return;
733
734         this._paused = false;
735         this._stepping = true;
736
737         this._clearInterface();
738
739         DebuggerAgent.stepOut();
740     },
741
742     _toggleBreakpointsClicked: function(event)
743     {
744         WebInspector.debuggerModel.setBreakpointsActive(!WebInspector.debuggerModel.breakpointsActive());
745     },
746
747     _breakpointsActiveStateChanged: function(event)
748     {
749         var active = event.data;
750         this._toggleBreakpointsButton.toggled = active;
751         if (active) {
752             this._toggleBreakpointsButton.title = WebInspector.UIString("Deactivate breakpoints.");
753             WebInspector.inspectorView.element.removeStyleClass("breakpoints-deactivated");
754             this.sidebarPanes.jsBreakpoints.listElement.removeStyleClass("breakpoints-list-deactivated");
755         } else {
756             this._toggleBreakpointsButton.title = WebInspector.UIString("Activate breakpoints.");
757             WebInspector.inspectorView.element.addStyleClass("breakpoints-deactivated");
758             this.sidebarPanes.jsBreakpoints.listElement.addStyleClass("breakpoints-list-deactivated");
759         }
760     },
761
762     _evaluateSelectionInConsole: function()
763     {
764         var selection = window.getSelection();
765         if (selection.type === "Range" && !selection.isCollapsed)
766             WebInspector.evaluateInConsole(selection.toString());
767     },
768
769     _createDebugToolbar: function()
770     {
771         var debugToolbar = document.createElement("div");
772         debugToolbar.className = "status-bar";
773         debugToolbar.id = "scripts-debug-toolbar";
774
775         var title, handler;
776         var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
777
778         // Continue.
779         handler = this._togglePause.bind(this);
780         this.pauseButton = this._createButtonAndRegisterShortcuts("scripts-pause", "", handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.PauseContinue);
781         debugToolbar.appendChild(this.pauseButton);
782
783         // Step over.
784         title = WebInspector.UIString("Step over next function call (%s).");
785         handler = this._stepOverClicked.bind(this);
786         this.stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOver);
787         debugToolbar.appendChild(this.stepOverButton);
788
789         // Step into.
790         title = WebInspector.UIString("Step into next function call (%s).");
791         handler = this._stepIntoClicked.bind(this);
792         this.stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepInto);
793         debugToolbar.appendChild(this.stepIntoButton);
794
795         // Step out.
796         title = WebInspector.UIString("Step out of current function (%s).");
797         handler = this._stepOutClicked.bind(this);
798         this.stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOut);
799         debugToolbar.appendChild(this.stepOutButton);
800
801         this._toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate breakpoints."), "toggle-breakpoints");
802         this._toggleBreakpointsButton.toggled = true;
803         this._toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this);
804         debugToolbar.appendChild(this._toggleBreakpointsButton.element);
805
806         this.debuggerStatusElement = document.createElement("div");
807         this.debuggerStatusElement.id = "scripts-debugger-status";
808         debugToolbar.appendChild(this.debuggerStatusElement);
809
810         return debugToolbar;
811     },
812
813     _updateButtonTitle: function(button, buttonTitle)
814     {
815         button.buttonTitle = buttonTitle;
816         var hasShortcuts = button.shortcuts && button.shortcuts.length;
817         if (hasShortcuts)
818             button.title = String.vsprintf(buttonTitle, [button.shortcuts[0].name]);
819         else
820             button.title = buttonTitle;
821     },
822
823     /**
824      * @param {string} buttonId
825      * @param {string} buttonTitle
826      * @param {function(Event)} handler
827      * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
828      */
829     _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts)
830     {
831         var button = document.createElement("button");
832         button.className = "status-bar-item";
833         button.id = buttonId;
834         button.shortcuts = shortcuts;
835         this._updateButtonTitle(button, buttonTitle);
836         button.disabled = true;
837         button.appendChild(document.createElement("img"));
838         button.addEventListener("click", handler, false);
839
840         this.registerShortcuts(shortcuts, handler);
841
842         return button;
843     },
844
845     searchCanceled: function()
846     {
847         if (this._searchView)
848             this._searchView.searchCanceled();
849
850         delete this._searchView;
851         delete this._searchQuery;
852     },
853
854     /**
855      * @param {string} query
856      */
857     performSearch: function(query)
858     {
859         WebInspector.searchController.updateSearchMatchesCount(0, this);
860
861         if (!this.visibleView)
862             return;
863
864         // Call searchCanceled since it will reset everything we need before doing a new search.
865         this.searchCanceled();
866
867         this._searchView = this.visibleView;
868         this._searchQuery = query;
869
870         function finishedCallback(view, searchMatches)
871         {
872             if (!searchMatches)
873                 return;
874
875             WebInspector.searchController.updateSearchMatchesCount(searchMatches, this);
876             view.jumpToNextSearchResult();
877             WebInspector.searchController.updateCurrentMatchIndex(view.currentSearchResultIndex, this);
878         }
879
880         this._searchView.performSearch(query, finishedCallback.bind(this));
881     },
882
883     jumpToNextSearchResult: function()
884     {
885         if (!this._searchView)
886             return;
887
888         if (this._searchView !== this.visibleView) {
889             this.performSearch(this._searchQuery);
890             return;
891         }
892
893         if (this._searchView.showingLastSearchResult())
894             this._searchView.jumpToFirstSearchResult();
895         else
896             this._searchView.jumpToNextSearchResult();
897         WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this);
898         return true;
899     },
900
901     jumpToPreviousSearchResult: function()
902     {
903         if (!this._searchView)
904             return false;
905
906         if (this._searchView !== this.visibleView) {
907             this.performSearch(this._searchQuery);
908             if (this._searchView)
909                 this._searchView.jumpToLastSearchResult();
910             return;
911         }
912
913         if (this._searchView.showingFirstSearchResult())
914             this._searchView.jumpToLastSearchResult();
915         else
916             this._searchView.jumpToPreviousSearchResult();
917         WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this);
918     },
919
920     /**
921      * @return {boolean}
922      */
923     canSearchAndReplace: function()
924     {
925         var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
926         return !!view && view.canEditSource();
927     },
928
929     /**
930      * @param {string} text
931      */
932     replaceSelectionWith: function(text)
933     {
934         var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
935         view.replaceSearchMatchWith(text);
936     },
937
938     /**
939      * @param {string} query
940      * @param {string} text
941      */
942     replaceAllWith: function(query, text)
943     {
944         var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
945         view.replaceAllWith(query, text);
946     },
947
948     _toggleFormatSource: function()
949     {
950         this._toggleFormatSourceButton.toggled = !this._toggleFormatSourceButton.toggled;
951         var uiSourceCodes = this._workspace.uiSourceCodes();
952         for (var i = 0; i < uiSourceCodes.length; ++i)
953             uiSourceCodes[i].setFormatted(this._toggleFormatSourceButton.toggled);
954
955         WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
956             action: WebInspector.UserMetrics.UserActionNames.TogglePrettyPrint,
957             enabled: this._toggleFormatSourceButton.toggled,
958             url: this._editorContainer.currentFile().url
959         });
960     },
961
962     addToWatch: function(expression)
963     {
964         this.sidebarPanes.watchExpressions.addExpression(expression);
965     },
966
967     _toggleBreakpoint: function()
968     {
969         var sourceFrame = this.visibleView;
970         if (!sourceFrame)
971             return;
972
973         if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
974             var javaScriptSourceFrame = /** @type {WebInspector.JavaScriptSourceFrame} */ (sourceFrame);
975             javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
976         }            
977     },
978
979     _showOutlineDialog: function()
980     {
981         var uiSourceCode = this._editorContainer.currentFile();
982         if (!uiSourceCode)
983             return;
984
985         switch (uiSourceCode.contentType()) {
986         case WebInspector.resourceTypes.Document:
987         case WebInspector.resourceTypes.Script:
988             WebInspector.JavaScriptOutlineDialog.show(this.visibleView, uiSourceCode);
989             break;
990         case WebInspector.resourceTypes.Stylesheet:
991             WebInspector.StyleSheetOutlineDialog.show(this.visibleView, uiSourceCode);
992             break;
993         }
994     },
995
996     _installDebuggerSidebarController: function()
997     {
998         this._toggleDebuggerSidebarButton = new WebInspector.StatusBarButton(WebInspector.UIString("Hide debugger"), "scripts-debugger-show-hide-button", 3);
999         this._toggleDebuggerSidebarButton.state = "shown";
1000         this._toggleDebuggerSidebarButton.addEventListener("click", clickHandler, this);
1001
1002         function clickHandler()
1003         {
1004             if (this._toggleDebuggerSidebarButton.state === "shown")
1005                 this._hideDebuggerSidebar();
1006             else
1007                 this._showDebuggerSidebar();
1008         }
1009         this.editorView.element.appendChild(this._toggleDebuggerSidebarButton.element);
1010
1011         if (WebInspector.settings.debuggerSidebarHidden.get())
1012             this._hideDebuggerSidebar();
1013
1014     },
1015
1016     _showDebuggerSidebar: function()
1017     {
1018         if (this._toggleDebuggerSidebarButton.state === "shown")
1019             return;
1020         this._toggleDebuggerSidebarButton.state = "shown";
1021         this._toggleDebuggerSidebarButton.title = WebInspector.UIString("Hide debugger");
1022         this.splitView.showSidebarElement();
1023         this.debugSidebarResizeWidgetElement.removeStyleClass("hidden");
1024         WebInspector.settings.debuggerSidebarHidden.set(false);
1025     },
1026
1027     _hideDebuggerSidebar: function()
1028     {
1029         if (this._toggleDebuggerSidebarButton.state === "hidden")
1030             return;
1031         this._toggleDebuggerSidebarButton.state = "hidden";
1032         this._toggleDebuggerSidebarButton.title = WebInspector.UIString("Show debugger");
1033         this.splitView.hideSidebarElement();
1034         this.debugSidebarResizeWidgetElement.addStyleClass("hidden");
1035         WebInspector.settings.debuggerSidebarHidden.set(true);
1036     },
1037
1038     _fileRenamed: function(event)
1039     {
1040         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data.uiSourceCode);
1041         var name = /** @type {string} */ (event.data.name);
1042         if (!uiSourceCode.isSnippet)
1043             return;
1044         WebInspector.scriptSnippetModel.renameScriptSnippet(uiSourceCode, name);
1045     },
1046         
1047     /**
1048      * @param {WebInspector.Event} event
1049      */
1050     _snippetCreationRequested: function(event)
1051     {
1052         var uiSourceCode = WebInspector.scriptSnippetModel.createScriptSnippet();
1053         this._showSourceLine(uiSourceCode);
1054         
1055         var shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
1056         if (this._navigatorController.isNavigatorHidden())
1057             this._navigatorController.showNavigatorOverlay();
1058         this._navigator.rename(uiSourceCode, callback.bind(this));
1059     
1060         /**
1061          * @param {boolean} committed
1062          */
1063         function callback(committed)
1064         {
1065             if (shouldHideNavigator)
1066                 this._navigatorController.hideNavigatorOverlay();
1067
1068             if (!committed) {
1069                 WebInspector.scriptSnippetModel.deleteScriptSnippet(uiSourceCode);
1070                 return;
1071             }
1072
1073             this._showSourceLine(uiSourceCode);
1074         }
1075     },
1076
1077     /**
1078      * @param {WebInspector.Event} event
1079      */
1080     _itemRenamingRequested: function(event)
1081     {
1082         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
1083         
1084         var shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
1085         if (this._navigatorController.isNavigatorHidden())
1086             this._navigatorController.showNavigatorOverlay();
1087         this._navigator.rename(uiSourceCode, callback.bind(this));
1088     
1089         /**
1090          * @param {boolean} committed
1091          */
1092         function callback(committed)
1093         {
1094             if (shouldHideNavigator && committed) {
1095                 this._navigatorController.hideNavigatorOverlay();
1096                 this._showSourceLine(uiSourceCode);
1097             }
1098         }
1099     },
1100
1101     /**
1102      * @param {WebInspector.UISourceCode} uiSourceCode
1103      */
1104     _showLocalHistory: function(uiSourceCode)
1105     {
1106         WebInspector.RevisionHistoryView.showHistory(uiSourceCode);
1107     },
1108
1109     /** 
1110      * @param {WebInspector.ContextMenu} contextMenu
1111      * @param {Object} target
1112      */
1113     appendApplicableItems: function(event, contextMenu, target)
1114     {
1115         this._appendUISourceCodeItems(contextMenu, target);
1116         this._appendFunctionItems(contextMenu, target);
1117     },
1118
1119     /** 
1120      * @param {WebInspector.ContextMenu} contextMenu
1121      * @param {Object} target
1122      */
1123     _appendUISourceCodeItems: function(contextMenu, target)
1124     {
1125         if (!(target instanceof WebInspector.UISourceCode))
1126             return;
1127
1128         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (target);
1129         contextMenu.appendItem(WebInspector.UIString("Local modifications..."), this._showLocalHistory.bind(this, uiSourceCode));
1130         var resource = WebInspector.resourceForURL(uiSourceCode.url);
1131         if (resource && resource.request)
1132             contextMenu.appendApplicableItems(resource.request);
1133     },
1134
1135     /** 
1136      * @param {WebInspector.ContextMenu} contextMenu
1137      * @param {Object} target
1138      */
1139     _appendFunctionItems: function(contextMenu, target)
1140     {
1141         if (!(target instanceof WebInspector.RemoteObject))
1142             return;
1143         var remoteObject = /** @type {WebInspector.RemoteObject} */ (target);
1144         if (remoteObject.type !== "function")
1145             return;
1146
1147         function didGetDetails(error, response)
1148         {
1149             if (error) {
1150                 console.error(error);
1151                 return;
1152             }
1153             WebInspector.inspectorView.showPanelForAnchorNavigation(this);
1154             var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(response.location);
1155             this._showSourceLine(uiLocation.uiSourceCode, uiLocation.lineNumber);
1156         }
1157
1158         function revealFunction()
1159         {
1160             DebuggerAgent.getFunctionDetails(remoteObject.objectId, didGetDetails.bind(this));
1161         }
1162
1163         contextMenu.appendItem(WebInspector.UIString("Show function definition"), revealFunction.bind(this));
1164     },
1165
1166     showGoToSourceDialog: function()
1167     {
1168         WebInspector.OpenResourceDialog.show(this, this.editorView.mainElement);
1169     },
1170
1171     __proto__: WebInspector.Panel.prototype
1172 }