Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / sources / SourcesPanel.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("SimpleHistoryManager.js");
30 importScript("EditingLocationHistoryManager.js");
31 importScript("FilePathScoreFunction.js");
32 importScript("FilteredItemSelectionDialog.js");
33 importScript("UISourceCodeFrame.js");
34 importScript("JavaScriptSourceFrame.js");
35 importScript("CSSSourceFrame.js");
36 importScript("NavigatorView.js");
37 importScript("RevisionHistoryView.js");
38 importScript("ScopeChainSidebarPane.js");
39 importScript("SourcesNavigator.js");
40 importScript("StyleSheetOutlineDialog.js");
41 importScript("TabbedEditorContainer.js");
42 importScript("WatchExpressionsSidebarPane.js");
43 importScript("WorkersSidebarPane.js");
44 importScript("ThreadsToolbar.js");
45 importScript("ScriptFormatterEditorAction.js");
46 importScript("InplaceFormatterEditorAction.js");
47 importScript("ScriptFormatter.js");
48 importScript("SourcesView.js");
49
50 /**
51  * @constructor
52  * @implements {WebInspector.ContextMenu.Provider}
53  * @extends {WebInspector.Panel}
54  * @param {!WebInspector.Workspace=} workspaceForTest
55  */
56 WebInspector.SourcesPanel = function(workspaceForTest)
57 {
58     WebInspector.Panel.call(this, "sources");
59     this.registerRequiredCSS("sourcesPanel.css");
60     this.registerRequiredCSS("suggestBox.css");
61     new WebInspector.UpgradeFileSystemDropTarget(this.element);
62
63     WebInspector.settings.showEditorInDrawer = WebInspector.settings.createSetting("showEditorInDrawer", true);
64
65     this._workspace = workspaceForTest || WebInspector.workspace;
66
67     var helpSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
68     this.debugToolbar = this._createDebugToolbar();
69     this._debugToolbarDrawer = this._createDebugToolbarDrawer();
70     this.threadsToolbar = new WebInspector.ThreadsToolbar();
71
72     const initialDebugSidebarWidth = 225;
73     this._splitView = new WebInspector.SplitView(true, true, "sourcesPanelSplitViewState", initialDebugSidebarWidth);
74     this._splitView.enableShowModeSaving();
75     this._splitView.show(this.element);
76
77     // Create scripts navigator
78     const initialNavigatorWidth = 225;
79     this.editorView = new WebInspector.SplitView(true, false, "sourcesPanelNavigatorSplitViewState", initialNavigatorWidth);
80     this.editorView.enableShowModeSaving();
81     this.editorView.element.id = "scripts-editor-split-view";
82     this.editorView.element.tabIndex = 0;
83     this.editorView.show(this._splitView.mainElement());
84
85     this._navigator = new WebInspector.SourcesNavigator(this._workspace);
86     this._navigator.view.setMinimumSize(Preferences.minSidebarWidth, 25);
87     this._navigator.view.show(this.editorView.sidebarElement());
88     this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceSelected, this._sourceSelected, this);
89     this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceRenamed, this._sourceRenamed, this);
90
91     this._sourcesView = new WebInspector.SourcesView(this._workspace, this);
92     this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
93     this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
94     this._sourcesView.registerShortcuts(this.registerShortcuts.bind(this));
95
96     if (WebInspector.experimentsSettings.showEditorInDrawer.isEnabled()) {
97         this._drawerEditorView = new WebInspector.SourcesPanel.DrawerEditorView();
98         this._sourcesView.show(this._drawerEditorView.element);
99     } else {
100         this._sourcesView.show(this.editorView.mainElement());
101     }
102
103     this._debugSidebarResizeWidgetElement = document.createElementWithClass("div", "resizer-widget");
104     this._debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget";
105     this._splitView.addEventListener(WebInspector.SplitView.Events.ShowModeChanged, this._updateDebugSidebarResizeWidget, this);
106     this._updateDebugSidebarResizeWidget();
107     this._splitView.installResizer(this._debugSidebarResizeWidgetElement);
108
109     this.sidebarPanes = {};
110     this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
111     this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
112     this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, this._callFrameSelectedInSidebar.bind(this));
113     this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameRestarted, this._callFrameRestartedInSidebar.bind(this));
114     this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));
115
116     this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
117     this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.debuggerModel, WebInspector.breakpointManager, this.showUISourceCode.bind(this));
118     this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this);
119     this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
120     this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
121
122     if (Capabilities.isMainFrontend)
123         this.sidebarPanes.workerList = new WebInspector.WorkersSidebarPane();
124
125     this._extensionSidebarPanes = [];
126
127     this._installDebuggerSidebarController();
128
129     WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
130     WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
131     this._dockSideChanged();
132
133     this._updateDebuggerButtons();
134     this._pauseOnExceptionEnabledChanged();
135     if (WebInspector.debuggerModel.isPaused())
136         this._showDebuggerPausedDetails(WebInspector.debuggerModel.debuggerPausedDetails());
137
138     WebInspector.settings.pauseOnExceptionEnabled.addChangeListener(this._pauseOnExceptionEnabledChanged, this);
139     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
140     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerWasDisabled, this);
141     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
142     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
143     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
144     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
145     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
146     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
147 }
148
149 WebInspector.SourcesPanel.minToolbarWidth = 215;
150
151 WebInspector.SourcesPanel.prototype = {
152     /**
153      * @return {!Element}
154      */
155     defaultFocusedElement: function()
156     {
157         return this._sourcesView.defaultFocusedElement() || this._navigator.view.defaultFocusedElement();
158     },
159
160     get paused()
161     {
162         return this._paused;
163     },
164
165     /**
166      * @return {!WebInspector.SourcesPanel.DrawerEditor}
167      */
168     _drawerEditor: function()
169     {
170         var drawerEditorInstance = WebInspector.moduleManager.instance(WebInspector.DrawerEditor);
171         console.assert(drawerEditorInstance instanceof WebInspector.SourcesPanel.DrawerEditor, "WebInspector.DrawerEditor module instance does not use WebInspector.SourcesPanel.DrawerEditor as an implementation. ");
172         return /** @type {!WebInspector.SourcesPanel.DrawerEditor} */ (drawerEditorInstance);
173     },
174
175     wasShown: function()
176     {
177         if (WebInspector.experimentsSettings.showEditorInDrawer.isEnabled()) {
178             this._drawerEditor()._panelWasShown();
179             this._sourcesView.show(this.editorView.mainElement());
180         }
181         WebInspector.Panel.prototype.wasShown.call(this);
182     },
183
184     willHide: function()
185     {
186         WebInspector.Panel.prototype.willHide.call(this);
187         if (WebInspector.experimentsSettings.showEditorInDrawer.isEnabled()) {
188             this._drawerEditor()._panelWillHide();
189             this._sourcesView.show(this._drawerEditorView.element);
190         }
191     },
192
193     /**
194      * @return {!WebInspector.SearchableView}
195      */
196     searchableView: function()
197     {
198         return this._sourcesView.searchableView();
199     },
200
201     _consoleCommandEvaluatedInSelectedCallFrame: function(event)
202     {
203         this.sidebarPanes.scopechain.update(WebInspector.debuggerModel.selectedCallFrame());
204     },
205
206     /**
207      * @param {!WebInspector.Event} event
208      */
209     _debuggerPaused: function(event)
210     {
211         var details = /** @type {!WebInspector.DebuggerPausedDetails} */ (event.data);
212         WebInspector.inspectorView.setCurrentPanel(this);
213         this._showDebuggerPausedDetails(details);
214     },
215
216     /**
217      * @param {?WebInspector.DebuggerPausedDetails} details
218      */
219     _showDebuggerPausedDetails: function(details)
220     {
221         this._paused = true;
222         this._waitingToPause = false;
223
224         this._updateDebuggerButtons();
225
226         this.sidebarPanes.callstack.update(details);
227
228         /**
229          * @param {!Element} element
230          * @this {WebInspector.SourcesPanel}
231          */
232         function didCreateBreakpointHitStatusMessage(element)
233         {
234             this.sidebarPanes.callstack.setStatus(element);
235         }
236
237         /**
238          * @param {!WebInspector.UILocation} uiLocation
239          * @this {WebInspector.SourcesPanel}
240          */
241         function didGetUILocation(uiLocation)
242         {
243             var breakpoint = WebInspector.breakpointManager.findBreakpointOnLine(uiLocation.uiSourceCode, uiLocation.lineNumber);
244             if (!breakpoint)
245                 return;
246             this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);
247             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
248         }
249
250         if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) {
251             WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData);
252             WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details, didCreateBreakpointHitStatusMessage.bind(this));
253         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) {
254             var eventName = details.auxData.eventName;
255             this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.auxData.eventName);
256             var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName, details.auxData);
257             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
258         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) {
259             this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);
260             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
261         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception)
262             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData.description));
263         else if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert)
264             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));
265         else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation)
266             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"]));
267         else if (details.reason === WebInspector.DebuggerModel.BreakReason.DebugCommand)
268             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a debugged function"));
269         else {
270             if (details.callFrames.length)
271                 details.callFrames[0].createLiveLocation(didGetUILocation.bind(this));
272             else
273                 console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
274         }
275
276         this._splitView.showBoth(true);
277         this._toggleDebuggerSidebarButton.setEnabled(false);
278         window.focus();
279         InspectorFrontendHost.bringToFront();
280     },
281
282     _debuggerResumed: function()
283     {
284         this._paused = false;
285         this._waitingToPause = false;
286
287         this._clearInterface();
288         this._toggleDebuggerSidebarButton.setEnabled(true);
289     },
290
291     _debuggerWasEnabled: function()
292     {
293         this._updateDebuggerButtons();
294     },
295
296     _debuggerWasDisabled: function()
297     {
298         this._debuggerReset();
299     },
300
301     _debuggerReset: function()
302     {
303         this._debuggerResumed();
304         this.sidebarPanes.watchExpressions.reset();
305         delete this._skipExecutionLineRevealing;
306     },
307
308     /**
309      * @return {!WebInspector.View}
310      */
311     get visibleView()
312     {
313         return this._sourcesView.visibleView();
314     },
315
316     /**
317      * @param {!WebInspector.UISourceCode} uiSourceCode
318      * @param {number=} lineNumber
319      * @param {number=} columnNumber
320      * @param {boolean=} forceShowInPanel
321      */
322     showUISourceCode: function(uiSourceCode, lineNumber, columnNumber, forceShowInPanel)
323     {
324         this._showEditor(forceShowInPanel);
325         this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
326     },
327
328     _showEditor: function(forceShowInPanel)
329     {
330         if (this._sourcesView.isShowing())
331             return;
332
333         if (this._shouldShowEditorInDrawer() && !forceShowInPanel)
334             this._drawerEditor()._show();
335         else
336             WebInspector.inspectorView.showPanel("sources");
337     },
338
339     /**
340      * @param {!WebInspector.UILocation} uiLocation
341      * @param {boolean=} forceShowInPanel
342      */
343     showUILocation: function(uiLocation, forceShowInPanel)
344     {
345         this.showUISourceCode(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, forceShowInPanel);
346     },
347
348     /**
349      * @return {boolean}
350      */
351     _shouldShowEditorInDrawer: function()
352     {
353         return WebInspector.experimentsSettings.showEditorInDrawer.isEnabled() && WebInspector.settings.showEditorInDrawer.get() && WebInspector.inspectorView.isDrawerEditorShown();
354     },
355
356     /**
357      * @param {!WebInspector.UISourceCode} uiSourceCode
358      */
359     _revealInNavigator: function(uiSourceCode)
360     {
361         this._navigator.revealUISourceCode(uiSourceCode);
362     },
363
364     _executionLineChanged: function(uiLocation)
365     {
366         this._sourcesView.clearCurrentExecutionLine();
367         this._sourcesView.setExecutionLine(uiLocation);
368         if (this._skipExecutionLineRevealing)
369             return;
370         this._skipExecutionLineRevealing = true;
371         this._sourcesView.showSourceLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, 0, undefined, true);
372     },
373
374     _callFrameSelected: function(event)
375     {
376         var callFrame = event.data;
377
378         if (!callFrame)
379             return;
380
381         this.sidebarPanes.scopechain.update(callFrame);
382         this.sidebarPanes.watchExpressions.refreshExpressions();
383         this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
384         callFrame.createLiveLocation(this._executionLineChanged.bind(this));
385     },
386
387     /**
388      * @param {!WebInspector.Event} event
389      */
390     _sourceSelected: function(event)
391     {
392         var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
393         this._sourcesView.showSourceLocation(uiSourceCode, undefined, undefined, !event.data.focusSource)
394     },
395
396     /**
397      * @param {!WebInspector.Event} event
398      */
399     _sourceRenamed: function(event)
400     {
401         var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
402         this._sourcesView.sourceRenamed(uiSourceCode);
403     },
404
405     _pauseOnExceptionEnabledChanged: function()
406     {
407         var enabled = WebInspector.settings.pauseOnExceptionEnabled.get();
408         this._pauseOnExceptionButton.toggled = enabled;
409         this._pauseOnExceptionButton.title = WebInspector.UIString(enabled ? "Don't pause on exceptions." : "Pause on exceptions.");
410         this._debugToolbarDrawer.classList.toggle("expanded", enabled);
411     },
412
413     _updateDebuggerButtons: function()
414     {
415         if (this._paused) {
416             this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Resume script execution (%s)."))
417             this._pauseButton.state = true;
418             this._pauseButton.setLongClickOptionsEnabled((function() { return [ this._longResumeButton ] }).bind(this));
419
420             this._pauseButton.setEnabled(true);
421             this._stepOverButton.setEnabled(true);
422             this._stepIntoButton.setEnabled(true);
423             this._stepOutButton.setEnabled(true);
424         } else {
425             this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Pause script execution (%s)."))
426             this._pauseButton.state = false;
427             this._pauseButton.setLongClickOptionsEnabled(null);
428
429             this._pauseButton.setEnabled(!this._waitingToPause);
430             this._stepOverButton.setEnabled(false);
431             this._stepIntoButton.setEnabled(false);
432             this._stepOutButton.setEnabled(false);
433         }
434     },
435
436     _clearInterface: function()
437     {
438         this.sidebarPanes.callstack.update(null);
439         this.sidebarPanes.scopechain.update(null);
440         this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
441         WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight();
442         this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
443         this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
444
445         this._sourcesView.clearCurrentExecutionLine();
446         this._updateDebuggerButtons();
447     },
448
449     _togglePauseOnExceptions: function()
450     {
451         WebInspector.settings.pauseOnExceptionEnabled.set(!this._pauseOnExceptionButton.toggled);
452     },
453
454     /**
455      * @return {boolean}
456      */
457     _runSnippet: function()
458     {
459         var uiSourceCode = this._sourcesView.currentUISourceCode();
460         if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
461             return false;
462
463         var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
464         if (!currentExecutionContext)
465             return false;
466
467         WebInspector.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, uiSourceCode);
468         return true;
469     },
470
471     /**
472      * @param {!WebInspector.Event} event
473      */
474     _editorSelected: function(event)
475     {
476         var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
477         this._editorChanged(uiSourceCode);
478    },
479
480     /**
481      * @param {!WebInspector.Event} event
482      */
483     _editorClosed: function(event)
484     {
485         var wasSelected = /** @type {boolean} */ (event.data.wasSelected);
486         if (wasSelected)
487             this._editorChanged(null);
488     },
489
490     /**
491      * @param {?WebInspector.UISourceCode} uiSourceCode
492      */
493     _editorChanged: function(uiSourceCode)
494     {
495         var isSnippet = uiSourceCode && uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
496         this._runSnippetButton.element.classList.toggle("hidden", !isSnippet);
497     },
498
499     /**
500      * @return {boolean}
501      */
502     togglePause: function()
503     {
504         if (this._paused) {
505             delete this._skipExecutionLineRevealing;
506             this._paused = false;
507             this._waitingToPause = false;
508             WebInspector.debuggerModel.resume();
509         } else {
510             this._waitingToPause = true;
511             // Make sure pauses didn't stick skipped.
512             WebInspector.debuggerModel.skipAllPauses(false);
513             DebuggerAgent.pause();
514         }
515
516         this._clearInterface();
517         return true;
518     },
519
520     /**
521      * @return {boolean}
522      */
523     _longResume: function()
524     {
525         if (!this._paused)
526             return true;
527
528         this._paused = false;
529         this._waitingToPause = false;
530         WebInspector.debuggerModel.skipAllPausesUntilReloadOrTimeout(500);
531         WebInspector.debuggerModel.resume();
532
533         this._clearInterface();
534         return true;
535     },
536
537     /**
538      * @return {boolean}
539      */
540     _stepOverClicked: function()
541     {
542         if (!this._paused)
543             return true;
544
545         delete this._skipExecutionLineRevealing;
546         this._paused = false;
547
548         this._clearInterface();
549
550         WebInspector.debuggerModel.stepOver();
551         return true;
552     },
553
554     /**
555      * @return {boolean}
556      */
557     _stepIntoClicked: function()
558     {
559         if (!this._paused)
560             return true;
561
562         delete this._skipExecutionLineRevealing;
563         this._paused = false;
564
565         this._clearInterface();
566
567         WebInspector.debuggerModel.stepInto();
568         return true;
569     },
570
571     /**
572      * @return {boolean}
573      */
574     _stepOutClicked: function()
575     {
576         if (!this._paused)
577             return true;
578
579         delete this._skipExecutionLineRevealing;
580         this._paused = false;
581
582         this._clearInterface();
583
584         WebInspector.debuggerModel.stepOut();
585         return true;
586     },
587
588     /**
589      * @param {!WebInspector.Event} event
590      */
591     _callFrameSelectedInSidebar: function(event)
592     {
593         var callFrame = /** @type {!WebInspector.DebuggerModel.CallFrame} */ (event.data);
594         delete this._skipExecutionLineRevealing;
595         WebInspector.debuggerModel.setSelectedCallFrame(callFrame);
596     },
597
598     _callFrameRestartedInSidebar: function()
599     {
600         delete this._skipExecutionLineRevealing;
601     },
602
603     /**
604      * @param {!WebInspector.DebuggerModel.Location} rawLocation
605      */
606     continueToLocation: function(rawLocation)
607     {
608         if (!this._paused)
609             return;
610
611         delete this._skipExecutionLineRevealing;
612         this._paused = false;
613         this._clearInterface();
614         rawLocation.continueToLocation();
615     },
616
617     _toggleBreakpointsClicked: function(event)
618     {
619         WebInspector.debuggerModel.setBreakpointsActive(!WebInspector.debuggerModel.breakpointsActive());
620     },
621
622     _breakpointsActiveStateChanged: function(event)
623     {
624         var active = event.data;
625         this._toggleBreakpointsButton.toggled = !active;
626         this.sidebarPanes.jsBreakpoints.listElement.classList.toggle("breakpoints-list-deactivated", !active);
627         this._sourcesView.toggleBreakpointsActiveState(active);
628         if (active)
629             this._toggleBreakpointsButton.title = WebInspector.UIString("Deactivate breakpoints.");
630         else
631             this._toggleBreakpointsButton.title = WebInspector.UIString("Activate breakpoints.");
632     },
633
634     _createDebugToolbar: function()
635     {
636         var debugToolbar = document.createElement("div");
637         debugToolbar.className = "scripts-debug-toolbar";
638
639         var title, handler;
640         var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
641
642         // Run snippet.
643         title = WebInspector.UIString("Run snippet (%s).");
644         handler = this._runSnippet.bind(this);
645         this._runSnippetButton = this._createButtonAndRegisterShortcuts("scripts-run-snippet", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.RunSnippet);
646         debugToolbar.appendChild(this._runSnippetButton.element);
647         this._runSnippetButton.element.classList.add("hidden");
648
649         // Continue.
650         handler = this.togglePause.bind(this);
651         this._pauseButton = this._createButtonAndRegisterShortcuts("scripts-pause", "", handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PauseContinue);
652         debugToolbar.appendChild(this._pauseButton.element);
653
654         // Long resume.
655         title = WebInspector.UIString("Resume with all pauses blocked for 500 ms");
656         this._longResumeButton = new WebInspector.StatusBarButton(title, "scripts-long-resume");
657         this._longResumeButton.addEventListener("click", this._longResume.bind(this), this);
658
659         // Step over.
660         title = WebInspector.UIString("Step over next function call (%s).");
661         handler = this._stepOverClicked.bind(this);
662         this._stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOver);
663         debugToolbar.appendChild(this._stepOverButton.element);
664
665         // Step into.
666         title = WebInspector.UIString("Step into next function call (%s).");
667         handler = this._stepIntoClicked.bind(this);
668         this._stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepInto);
669         debugToolbar.appendChild(this._stepIntoButton.element);
670
671         // Step out.
672         title = WebInspector.UIString("Step out of current function (%s).");
673         handler = this._stepOutClicked.bind(this);
674         this._stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOut);
675         debugToolbar.appendChild(this._stepOutButton.element);
676
677         // Toggle Breakpoints
678         this._toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate breakpoints."), "scripts-toggle-breakpoints");
679         this._toggleBreakpointsButton.toggled = false;
680         this._toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this);
681         debugToolbar.appendChild(this._toggleBreakpointsButton.element);
682
683         // Pause on Exception
684         this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item");
685         this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this);
686         debugToolbar.appendChild(this._pauseOnExceptionButton.element);
687
688         return debugToolbar;
689     },
690
691     _createDebugToolbarDrawer: function()
692     {
693         var debugToolbarDrawer = document.createElement("div");
694         debugToolbarDrawer.className = "scripts-debug-toolbar-drawer";
695
696         var label = WebInspector.UIString("Pause On Caught Exceptions");
697         var setting = WebInspector.settings.pauseOnCaughtException;
698         debugToolbarDrawer.appendChild(WebInspector.SettingsUI.createSettingCheckbox(label, setting, true));
699
700         return debugToolbarDrawer;
701     },
702
703     /**
704      * @param {!WebInspector.StatusBarButton} button
705      * @param {string} buttonTitle
706      */
707     _updateButtonTitle: function(button, buttonTitle)
708     {
709         var hasShortcuts = button.shortcuts && button.shortcuts.length;
710         if (hasShortcuts)
711             button.title = String.vsprintf(buttonTitle, [button.shortcuts[0].name]);
712         else
713             button.title = buttonTitle;
714     },
715
716     /**
717      * @param {string} buttonId
718      * @param {string} buttonTitle
719      * @param {function(?Event=):boolean} handler
720      * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
721      * @return {!WebInspector.StatusBarButton}
722      */
723     _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts)
724     {
725         var button = new WebInspector.StatusBarButton(buttonTitle, buttonId);
726         button.element.addEventListener("click", handler, false);
727         button.shortcuts = shortcuts;
728         this._updateButtonTitle(button, buttonTitle);
729         this.registerShortcuts(shortcuts, handler);
730         return button;
731     },
732
733     addToWatch: function(expression)
734     {
735         this.sidebarPanes.watchExpressions.addExpression(expression);
736     },
737
738     _installDebuggerSidebarController: function()
739     {
740         this._toggleNavigatorSidebarButton = this.editorView.createShowHideSidebarButton("navigator", "scripts-navigator-show-hide-button");
741         this.editorView.mainElement().appendChild(this._toggleNavigatorSidebarButton.element);
742
743         this._toggleDebuggerSidebarButton = this._splitView.createShowHideSidebarButton("debugger", "scripts-debugger-show-hide-button");
744
745         this._splitView.mainElement().appendChild(this._toggleDebuggerSidebarButton.element);
746         this._splitView.mainElement().appendChild(this._debugSidebarResizeWidgetElement);
747     },
748
749     _updateDebugSidebarResizeWidget: function()
750     {
751         this._debugSidebarResizeWidgetElement.classList.toggle("hidden", this._splitView.showMode() !== WebInspector.SplitView.ShowMode.Both);
752     },
753
754     /**
755      * @param {!WebInspector.UISourceCode} uiSourceCode
756      */
757     _showLocalHistory: function(uiSourceCode)
758     {
759         WebInspector.RevisionHistoryView.showHistory(uiSourceCode);
760     },
761
762     /**
763      * @param {!WebInspector.ContextMenu} contextMenu
764      * @param {!Object} target
765      */
766     appendApplicableItems: function(event, contextMenu, target)
767     {
768         this._appendUISourceCodeItems(event, contextMenu, target);
769         this._appendRemoteObjectItems(contextMenu, target);
770     },
771
772     _suggestReload: function()
773     {
774         if (window.confirm(WebInspector.UIString("It is recommended to restart inspector after making these changes. Would you like to restart it?")))
775             WebInspector.reload();
776     },
777
778     /**
779      * @param {!WebInspector.UISourceCode} uiSourceCode
780      */
781     _mapFileSystemToNetwork: function(uiSourceCode)
782     {
783         WebInspector.SelectUISourceCodeForProjectTypesDialog.show(uiSourceCode.name(), [WebInspector.projectTypes.Network, WebInspector.projectTypes.ContentScripts], mapFileSystemToNetwork.bind(this), this.editorView.mainElement())
784
785         /**
786          * @param {!WebInspector.UISourceCode} networkUISourceCode
787          * @this {WebInspector.SourcesPanel}
788          */
789         function mapFileSystemToNetwork(networkUISourceCode)
790         {
791             this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceBinding);
792             this._suggestReload();
793         }
794     },
795
796     /**
797      * @param {!WebInspector.UISourceCode} uiSourceCode
798      */
799     _removeNetworkMapping: function(uiSourceCode)
800     {
801         if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?"))) {
802             this._workspace.removeMapping(uiSourceCode);
803             this._suggestReload();
804         }
805     },
806
807     /**
808      * @param {!WebInspector.UISourceCode} networkUISourceCode
809      */
810     _mapNetworkToFileSystem: function(networkUISourceCode)
811     {
812         WebInspector.SelectUISourceCodeForProjectTypesDialog.show(networkUISourceCode.name(), [WebInspector.projectTypes.FileSystem], mapNetworkToFileSystem.bind(this), this.editorView.mainElement())
813
814         /**
815          * @param {!WebInspector.UISourceCode} uiSourceCode
816          * @this {WebInspector.SourcesPanel}
817          */
818         function mapNetworkToFileSystem(uiSourceCode)
819         {
820             this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceBinding);
821             this._suggestReload();
822         }
823     },
824
825     /**
826      * @param {!WebInspector.ContextMenu} contextMenu
827      * @param {!WebInspector.UISourceCode} uiSourceCode
828      */
829     _appendUISourceCodeMappingItems: function(contextMenu, uiSourceCode)
830     {
831         if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
832             var hasMappings = !!uiSourceCode.url;
833             if (!hasMappings)
834                 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this._mapFileSystemToNetwork.bind(this, uiSourceCode));
835             else
836                 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode));
837         }
838
839         /**
840          * @param {!WebInspector.Project} project
841          */
842         function filterProject(project)
843         {
844             return project.type() === WebInspector.projectTypes.FileSystem;
845         }
846
847         if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) {
848             if (!this._workspace.projects().filter(filterProject).length)
849                 return;
850             if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode)
851                 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this._mapNetworkToFileSystem.bind(this, uiSourceCode));
852         }
853     },
854
855     /**
856      * @param {!Event} event
857      * @param {!WebInspector.ContextMenu} contextMenu
858      * @param {!Object} target
859      */
860     _appendUISourceCodeItems: function(event, contextMenu, target)
861     {
862         if (!(target instanceof WebInspector.UISourceCode))
863             return;
864
865         var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (target);
866         contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Local modifications\u2026" : "Local Modifications\u2026"), this._showLocalHistory.bind(this, uiSourceCode));
867         this._appendUISourceCodeMappingItems(contextMenu, uiSourceCode);
868
869         if (!event.target.isSelfOrDescendant(this.editorView.sidebarElement())) {
870             contextMenu.appendSeparator();
871             contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in navigator" : "Reveal in Navigator"), this._handleContextMenuReveal.bind(this, uiSourceCode));
872         }
873     },
874
875     /**
876      * @param {!WebInspector.UISourceCode} uiSourceCode
877      */
878     _handleContextMenuReveal: function(uiSourceCode)
879     {
880         this.editorView.showBoth();
881         this._revealInNavigator(uiSourceCode);
882     },
883
884     /**
885      * @param {!WebInspector.ContextMenu} contextMenu
886      * @param {!Object} target
887      */
888     _appendRemoteObjectItems: function(contextMenu, target)
889     {
890         if (!(target instanceof WebInspector.RemoteObject))
891             return;
892         var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target);
893         contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Store as global variable" : "Store as Global Variable"), this._saveToTempVariable.bind(this, remoteObject));
894         if (remoteObject.type === "function")
895             contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Show function definition" : "Show Function Definition"), this._showFunctionDefinition.bind(this, remoteObject));
896     },
897
898     /**
899      * @param {!WebInspector.RemoteObject} remoteObject
900      */
901     _saveToTempVariable: function(remoteObject)
902     {
903         var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
904         if (!currentExecutionContext)
905             return;
906
907         currentExecutionContext.evaluate("window", "", false, true, false, false, didGetGlobalObject.bind(null, currentExecutionContext.target()));
908         /**
909          * @param {!WebInspector.Target} target
910          * @param {?WebInspector.RemoteObject} global
911          * @param {boolean=} wasThrown
912          */
913         function didGetGlobalObject(target, global, wasThrown)
914         {
915             /**
916              * @suppressReceiverCheck
917              * @this {Window}
918              */
919             function remoteFunction(value)
920             {
921                 var prefix = "temp";
922                 var index = 1;
923                 while ((prefix + index) in this)
924                     ++index;
925                 var name = prefix + index;
926                 this[name] = value;
927                 return name;
928             }
929
930             if (wasThrown || !global)
931                 failedToSave(target, global);
932             else
933                 global.callFunction(remoteFunction, [WebInspector.RemoteObject.toCallArgument(remoteObject)], didSave.bind(null, global));
934         }
935
936         /**
937          * @param {!WebInspector.RemoteObject} global
938          * @param {?WebInspector.RemoteObject} result
939          * @param {boolean=} wasThrown
940          */
941         function didSave(global, result, wasThrown)
942         {
943             var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
944             global.release();
945             if (!currentExecutionContext || wasThrown || !result || result.type !== "string")
946                 failedToSave(global.target(), result);
947             else
948                 WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext, result.value);
949         }
950
951         /**
952          * @param {!WebInspector.Target} target
953          * @param {?WebInspector.RemoteObject} result
954          */
955         function failedToSave(target, result)
956         {
957             var message = WebInspector.UIString("Failed to save to temp variable.");
958             if (result) {
959                 message += " " + result.description;
960                 result.release();
961             }
962             target.consoleModel.showErrorMessage(message)
963         }
964     },
965
966     /**
967      * @param {!WebInspector.RemoteObject} remoteObject
968      */
969     _showFunctionDefinition: function(remoteObject)
970     {
971         /**
972          * @param {?Protocol.Error} error
973          * @param {!DebuggerAgent.FunctionDetails} response
974          * @this {WebInspector.SourcesPanel}
975          */
976         function didGetFunctionDetails(error, response)
977         {
978             if (error) {
979                 console.error(error);
980                 return;
981             }
982
983             var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(response.location);
984             if (!uiLocation)
985                 return;
986
987             this.showUILocation(uiLocation, true);
988         }
989         DebuggerAgent.getFunctionDetails(remoteObject.objectId, didGetFunctionDetails.bind(this));
990     },
991
992     showGoToSourceDialog: function()
993     {
994         this._sourcesView.showOpenResourceDialog();
995     },
996
997     _dockSideChanged: function()
998     {
999         var vertically = WebInspector.dockController.isVertical() && WebInspector.settings.splitVerticallyWhenDockedToRight.get();
1000         this._splitVertically(vertically);
1001     },
1002
1003     /**
1004      * @param {boolean} vertically
1005      */
1006     _splitVertically: function(vertically)
1007     {
1008         if (this.sidebarPaneView && vertically === !this._splitView.isVertical())
1009             return;
1010
1011         if (this.sidebarPaneView)
1012             this.sidebarPaneView.detach();
1013
1014         this._splitView.setVertical(!vertically);
1015
1016         if (!vertically)
1017             this._splitView.uninstallResizer(this._sourcesView.statusBarContainerElement());
1018         else
1019             this._splitView.installResizer(this._sourcesView.statusBarContainerElement());
1020
1021         // Create vertical box with stack.
1022         var vbox = new WebInspector.VBox();
1023         vbox.element.appendChild(this._debugToolbarDrawer);
1024         vbox.element.appendChild(this.debugToolbar);
1025         vbox.element.appendChild(this.threadsToolbar.element);
1026         vbox.setMinimumAndPreferredSizes(25, 25, WebInspector.SourcesPanel.minToolbarWidth, 100);
1027         var sidebarPaneStack = new WebInspector.SidebarPaneStack();
1028         sidebarPaneStack.element.classList.add("flex-auto");
1029         sidebarPaneStack.show(vbox.element);
1030
1031         if (!vertically) {
1032             // Populate the only stack.
1033             for (var pane in this.sidebarPanes)
1034                 sidebarPaneStack.addPane(this.sidebarPanes[pane]);
1035             this._extensionSidebarPanesContainer = sidebarPaneStack;
1036
1037             this.sidebarPaneView = vbox;
1038         } else {
1039             var splitView = new WebInspector.SplitView(true, true, "sourcesPanelDebuggerSidebarSplitViewState", 0.5);
1040             vbox.show(splitView.mainElement());
1041
1042             // Populate the left stack.
1043             sidebarPaneStack.addPane(this.sidebarPanes.callstack);
1044             sidebarPaneStack.addPane(this.sidebarPanes.jsBreakpoints);
1045             sidebarPaneStack.addPane(this.sidebarPanes.domBreakpoints);
1046             sidebarPaneStack.addPane(this.sidebarPanes.xhrBreakpoints);
1047             sidebarPaneStack.addPane(this.sidebarPanes.eventListenerBreakpoints);
1048             if (this.sidebarPanes.workerList)
1049                 sidebarPaneStack.addPane(this.sidebarPanes.workerList);
1050
1051             var tabbedPane = new WebInspector.SidebarTabbedPane();
1052             tabbedPane.show(splitView.sidebarElement());
1053             tabbedPane.addPane(this.sidebarPanes.scopechain);
1054             tabbedPane.addPane(this.sidebarPanes.watchExpressions);
1055             this._extensionSidebarPanesContainer = tabbedPane;
1056
1057             this.sidebarPaneView = splitView;
1058         }
1059         for (var i = 0; i < this._extensionSidebarPanes.length; ++i)
1060             this._extensionSidebarPanesContainer.addPane(this._extensionSidebarPanes[i]);
1061
1062         this.sidebarPaneView.show(this._splitView.sidebarElement());
1063
1064         this.sidebarPanes.scopechain.expand();
1065         this.sidebarPanes.jsBreakpoints.expand();
1066         this.sidebarPanes.callstack.expand();
1067
1068         if (WebInspector.settings.watchExpressions.get().length > 0)
1069             this.sidebarPanes.watchExpressions.expand();
1070     },
1071
1072     /**
1073      * @param {string} id
1074      * @param {!WebInspector.SidebarPane} pane
1075      */
1076     addExtensionSidebarPane: function(id, pane)
1077     {
1078         this._extensionSidebarPanes.push(pane);
1079         this._extensionSidebarPanesContainer.addPane(pane);
1080         this.setHideOnDetach();
1081     },
1082
1083     /**
1084      * @return {!WebInspector.SourcesView}
1085      */
1086     sourcesView: function()
1087     {
1088         return this._sourcesView;
1089     },
1090
1091     __proto__: WebInspector.Panel.prototype
1092 }
1093
1094 /**
1095  * @constructor
1096  * @param {!Element} element
1097  */
1098 WebInspector.UpgradeFileSystemDropTarget = function(element)
1099 {
1100     element.addEventListener("dragenter", this._onDragEnter.bind(this), true);
1101     element.addEventListener("dragover", this._onDragOver.bind(this), true);
1102     this._element = element;
1103 }
1104
1105 WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType = "Files";
1106
1107 WebInspector.UpgradeFileSystemDropTarget.prototype = {
1108     _onDragEnter: function (event)
1109     {
1110         if (event.dataTransfer.types.indexOf(WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType) === -1)
1111             return;
1112         event.consume(true);
1113     },
1114
1115     _onDragOver: function (event)
1116     {
1117         if (event.dataTransfer.types.indexOf(WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType) === -1)
1118             return;
1119         event.dataTransfer.dropEffect = "copy";
1120         event.consume(true);
1121         if (this._dragMaskElement)
1122             return;
1123         this._dragMaskElement = this._element.createChild("div", "fill drag-mask");
1124         this._dragMaskElement.createChild("div", "fill drag-mask-inner").textContent = WebInspector.UIString("Drop workspace folder here");
1125         this._dragMaskElement.addEventListener("drop", this._onDrop.bind(this), true);
1126         this._dragMaskElement.addEventListener("dragleave", this._onDragLeave.bind(this), true);
1127     },
1128
1129     _onDrop: function (event)
1130     {
1131         event.consume(true);
1132         this._removeMask();
1133         var items = /** @type {!Array.<!DataTransferItem>} */ (event.dataTransfer.items);
1134         if (!items.length)
1135             return;
1136         var entry = items[0].webkitGetAsEntry();
1137         if (!entry.isDirectory)
1138             return;
1139         InspectorFrontendHost.upgradeDraggedFileSystemPermissions(entry.filesystem);
1140     },
1141
1142     _onDragLeave: function (event)
1143     {
1144         event.consume(true);
1145         this._removeMask();
1146     },
1147
1148     _removeMask: function ()
1149     {
1150         this._dragMaskElement.remove();
1151         delete this._dragMaskElement;
1152     }
1153 }
1154
1155 /**
1156  * @constructor
1157  * @implements {WebInspector.DrawerEditor}
1158  */
1159 WebInspector.SourcesPanel.DrawerEditor = function()
1160 {
1161     this._panel = WebInspector.inspectorView.panel("sources");
1162 }
1163
1164 WebInspector.SourcesPanel.DrawerEditor.prototype = {
1165     /**
1166      * @return {!WebInspector.View}
1167      */
1168     view: function()
1169     {
1170         return this._panel._drawerEditorView;
1171     },
1172
1173     installedIntoDrawer: function()
1174     {
1175         if (this._panel.isShowing())
1176             this._panelWasShown();
1177         else
1178             this._panelWillHide();
1179     },
1180
1181     _panelWasShown: function()
1182     {
1183         WebInspector.inspectorView.setDrawerEditorAvailable(false);
1184         WebInspector.inspectorView.hideDrawerEditor();
1185     },
1186
1187     _panelWillHide: function()
1188     {
1189         WebInspector.inspectorView.setDrawerEditorAvailable(true);
1190         if (WebInspector.inspectorView.isDrawerEditorShown())
1191             WebInspector.inspectorView.showDrawerEditor();
1192     },
1193
1194     _show: function()
1195     {
1196         WebInspector.inspectorView.showDrawerEditor();
1197     },
1198 }
1199
1200 /**
1201  * @constructor
1202  * @extends {WebInspector.VBox}
1203  */
1204 WebInspector.SourcesPanel.DrawerEditorView = function()
1205 {
1206     WebInspector.VBox.call(this);
1207     this.element.id = "drawer-editor-view";
1208 }
1209
1210 WebInspector.SourcesPanel.DrawerEditorView.prototype = {
1211     __proto__: WebInspector.VBox.prototype
1212 }
1213
1214
1215 /**
1216  * @constructor
1217  * @implements {WebInspector.ContextMenu.Provider}
1218  */
1219 WebInspector.SourcesPanel.ContextMenuProvider = function()
1220 {
1221 }
1222
1223 WebInspector.SourcesPanel.ContextMenuProvider.prototype = {
1224     /**
1225      * @param {!WebInspector.ContextMenu} contextMenu
1226      * @param {!Object} target
1227      */
1228     appendApplicableItems: function(event, contextMenu, target)
1229     {
1230         WebInspector.inspectorView.panel("sources").appendApplicableItems(event, contextMenu, target);
1231     }
1232 }
1233
1234 /**
1235  * @constructor
1236  * @implements {WebInspector.Revealer}
1237  */
1238 WebInspector.SourcesPanel.UILocationRevealer = function()
1239 {
1240 }
1241
1242 WebInspector.SourcesPanel.UILocationRevealer.prototype = {
1243     /**
1244      * @param {!Object} uiLocation
1245      */
1246     reveal: function(uiLocation)
1247     {
1248         if (uiLocation instanceof WebInspector.UILocation)
1249             /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.panel("sources")).showUILocation(uiLocation);
1250     }
1251 }
1252
1253 /**
1254  * @constructor
1255  * @implements {WebInspector.Revealer}
1256  */
1257 WebInspector.SourcesPanel.UISourceCodeRevealer = function()
1258 {
1259 }
1260
1261 WebInspector.SourcesPanel.UISourceCodeRevealer.prototype = {
1262     /**
1263      * @param {!Object} uiSourceCode
1264      */
1265     reveal: function(uiSourceCode)
1266     {
1267         if (uiSourceCode instanceof WebInspector.UISourceCode)
1268             /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.panel("sources")).showUISourceCode(uiSourceCode);
1269     }
1270 }
1271
1272 /**
1273  * @constructor
1274  * @implements {WebInspector.ActionDelegate}
1275  */
1276 WebInspector.SourcesPanel.ShowGoToSourceDialogActionDelegate = function() {}
1277
1278 WebInspector.SourcesPanel.ShowGoToSourceDialogActionDelegate.prototype = {
1279     /**
1280      * @return {boolean}
1281      */
1282     handleAction: function()
1283     {
1284         /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.showPanel("sources")).showGoToSourceDialog();
1285         return true;
1286     }
1287 }
1288
1289 /**
1290  * @constructor
1291  * @extends {WebInspector.UISettingDelegate}
1292  */
1293 WebInspector.SourcesPanel.SkipStackFramePatternSettingDelegate = function()
1294 {
1295     WebInspector.UISettingDelegate.call(this);
1296 }
1297
1298 WebInspector.SourcesPanel.SkipStackFramePatternSettingDelegate.prototype = {
1299     /**
1300      * @override
1301      * @return {!Element}
1302      */
1303     settingElement: function()
1304     {
1305         return WebInspector.SettingsUI.createSettingInputField(WebInspector.UIString("Pattern"), WebInspector.settings.skipStackFramesPattern, false, 1000, "100px", WebInspector.SettingsUI.regexValidator);
1306     },
1307
1308     __proto__: WebInspector.UISettingDelegate.prototype
1309 }
1310
1311 /**
1312  * @constructor
1313  * @extends {WebInspector.UISettingDelegate}
1314  */
1315 WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate = function()
1316 {
1317     WebInspector.UISettingDelegate.call(this);
1318 }
1319
1320 WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate.prototype = {
1321     /**
1322      * @override
1323      * @return {!Element}
1324      */
1325     settingElement: function()
1326     {
1327         var disableJSElement = WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Disable JavaScript"), WebInspector.settings.javaScriptDisabled);
1328         this._disableJSCheckbox = disableJSElement.getElementsByTagName("input")[0];
1329         WebInspector.settings.javaScriptDisabled.addChangeListener(this._settingChanged, this);
1330         var disableJSInfoParent = this._disableJSCheckbox.parentElement.createChild("span", "monospace");
1331         this._disableJSInfo = disableJSInfoParent.createChild("span", "object-info-state-note hidden");
1332         this._disableJSInfo.title = WebInspector.UIString("JavaScript is blocked on the inspected page (may be disabled in browser settings).");
1333
1334         WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._updateScriptDisabledCheckbox, this);
1335         this._updateScriptDisabledCheckbox();
1336         return disableJSElement;
1337     },
1338
1339     /**
1340      * @param {!WebInspector.Event} event
1341      */
1342     _settingChanged: function(event)
1343     {
1344         PageAgent.setScriptExecutionDisabled(event.data, this._updateScriptDisabledCheckbox.bind(this));
1345     },
1346
1347     _updateScriptDisabledCheckbox: function()
1348     {
1349         PageAgent.getScriptExecutionStatus(executionStatusCallback.bind(this));
1350
1351         /**
1352          * @param {?Protocol.Error} error
1353          * @param {string} status
1354          * @this {WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate}
1355          */
1356         function executionStatusCallback(error, status)
1357         {
1358             if (error || !status)
1359                 return;
1360
1361             var forbidden = (status === "forbidden");
1362             var disabled = forbidden || (status === "disabled");
1363
1364             this._disableJSInfo.classList.toggle("hidden", !forbidden);
1365             this._disableJSCheckbox.checked = disabled;
1366             this._disableJSCheckbox.disabled = forbidden;
1367         }
1368     },
1369
1370     __proto__: WebInspector.UISettingDelegate.prototype
1371 }