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