Home | History | Annotate | Download | only in front_end
      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("FilePathScoreFunction.js");
     30 importScript("FilteredItemSelectionDialog.js");
     31 importScript("UISourceCodeFrame.js");
     32 importScript("JavaScriptSourceFrame.js");
     33 importScript("NavigatorOverlayController.js");
     34 importScript("NavigatorView.js");
     35 importScript("RevisionHistoryView.js");
     36 importScript("ScopeChainSidebarPane.js");
     37 importScript("ScriptsNavigator.js");
     38 importScript("ScriptsSearchScope.js");
     39 importScript("StyleSheetOutlineDialog.js");
     40 importScript("TabbedEditorContainer.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     this.registerRequiredCSS("textPrompt.css"); // Watch Expressions autocomplete.
     56 
     57     WebInspector.settings.navigatorWasOnceHidden = WebInspector.settings.createSetting("navigatorWasOnceHidden", false);
     58     WebInspector.settings.debuggerSidebarHidden = WebInspector.settings.createSetting("debuggerSidebarHidden", false);
     59 
     60     this._workspace = workspaceForTest || WebInspector.workspace;
     61 
     62     function viewGetter()
     63     {
     64         return this.visibleView;
     65     }
     66     WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
     67 
     68     var helpSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
     69     this.debugToolbar = this._createDebugToolbar();
     70 
     71     const initialDebugSidebarWidth = 225;
     72     const minimumDebugSidebarWidthPercent = 0.5;
     73     this.createSidebarView(this.element, WebInspector.SidebarView.SidebarPosition.End, initialDebugSidebarWidth);
     74     this.splitView.element.id = "scripts-split-view";
     75     this.splitView.setSidebarElementConstraints(Preferences.minScriptsSidebarWidth);
     76     this.splitView.setMainElementConstraints(minimumDebugSidebarWidthPercent);
     77 
     78     // Create scripts navigator
     79     const initialNavigatorWidth = 225;
     80     const minimumViewsContainerWidthPercent = 0.5;
     81     this.editorView = new WebInspector.SidebarView(WebInspector.SidebarView.SidebarPosition.Start, "scriptsPanelNavigatorSidebarWidth", initialNavigatorWidth);
     82     this.editorView.element.tabIndex = 0;
     83 
     84     this.editorView.setSidebarElementConstraints(Preferences.minScriptsSidebarWidth);
     85     this.editorView.setMainElementConstraints(minimumViewsContainerWidthPercent);
     86     this.editorView.show(this.splitView.mainElement);
     87 
     88     this._navigator = new WebInspector.ScriptsNavigator();
     89     this._navigator.view.show(this.editorView.sidebarElement);
     90 
     91     var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIString("Hit Cmd+O to open a file") : WebInspector.UIString("Hit Ctrl+O to open a file");
     92 
     93     this._editorContentsElement = this.editorView.mainElement.createChild("div", "fill");
     94     this._editorFooterElement = this.editorView.mainElement.createChild("div", "inspector-footer status-bar hidden");
     95     this._editorContainer = new WebInspector.TabbedEditorContainer(this, "previouslyViewedFiles", tabbedEditorPlaceholderText);
     96     this._editorContainer.show(this._editorContentsElement);
     97 
     98     this._navigatorController = new WebInspector.NavigatorOverlayController(this.editorView, this._navigator.view, this._editorContainer.view);
     99 
    100     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ScriptSelected, this._scriptSelected, this);
    101     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ItemSearchStarted, this._itemSearchStarted, this);
    102     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ItemCreationRequested, this._itemCreationRequested, this);
    103     this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ItemRenamingRequested, this._itemRenamingRequested, this);
    104 
    105     this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
    106     this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
    107 
    108     this._debugSidebarResizeWidgetElement = this.splitView.mainElement.createChild("div", "resizer-widget");
    109     this._debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget";
    110     this.splitView.installResizer(this._debugSidebarResizeWidgetElement);
    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._showSourceLocation.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 (Capabilities.canInspectWorkers && !WebInspector.WorkerManager.isWorkerFrontend()) {
    122         WorkerAgent.enable();
    123         this.sidebarPanes.workerList = new WebInspector.WorkersSidebarPane(WebInspector.workerManager);
    124     }
    125 
    126     this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));
    127     this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.GoToMember, this._showOutlineDialog.bind(this));
    128     this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
    129 
    130     this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
    131     this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this);
    132 
    133     this._toggleFormatSourceButton = new WebInspector.StatusBarButton(WebInspector.UIString("Pretty print"), "scripts-toggle-pretty-print-status-bar-item");
    134     this._toggleFormatSourceButton.toggled = false;
    135     this._toggleFormatSourceButton.addEventListener("click", this._toggleFormatSource, this);
    136 
    137     this._scriptViewStatusBarItemsContainer = document.createElement("div");
    138     this._scriptViewStatusBarItemsContainer.className = "inline-block";
    139 
    140     this._scriptViewStatusBarTextContainer = document.createElement("div");
    141     this._scriptViewStatusBarTextContainer.className = "inline-block";
    142 
    143     this._installDebuggerSidebarController();
    144 
    145     WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
    146     WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
    147     this._dockSideChanged();
    148 
    149     /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.SourceFrame>} */
    150     this._sourceFramesByUISourceCode = new Map();
    151     this._updateDebuggerButtons();
    152     this._pauseOnExceptionStateChanged();
    153     if (WebInspector.debuggerModel.isPaused())
    154         this._debuggerPaused();
    155 
    156     WebInspector.settings.pauseOnExceptionStateString.addChangeListener(this._pauseOnExceptionStateChanged, this);
    157     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
    158     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerWasDisabled, this);
    159     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
    160     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
    161     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
    162     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
    163     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ExecutionLineChanged, this._executionLineChanged, this);
    164     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
    165 
    166     WebInspector.startBatchUpdate();
    167     this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
    168     WebInspector.endBatchUpdate();
    169 
    170     this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
    171     this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
    172     this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset.bind(this), this);
    173     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
    174 
    175     WebInspector.advancedSearchController.registerSearchScope(new WebInspector.ScriptsSearchScope(this._workspace));
    176 }
    177 
    178 WebInspector.ScriptsPanel.prototype = {
    179     get statusBarItems()
    180     {
    181         return [this._pauseOnExceptionButton.element, this._toggleFormatSourceButton.element, this._scriptViewStatusBarItemsContainer];
    182     },
    183 
    184     /**
    185      * @return {?Element}
    186      */
    187     statusBarText: function()
    188     {
    189         return this._scriptViewStatusBarTextContainer;
    190     },
    191 
    192     defaultFocusedElement: function()
    193     {
    194         return this._editorContainer.view.defaultFocusedElement() || this._navigator.view.defaultFocusedElement();
    195     },
    196 
    197     get paused()
    198     {
    199         return this._paused;
    200     },
    201 
    202     wasShown: function()
    203     {
    204         WebInspector.Panel.prototype.wasShown.call(this);
    205         this._navigatorController.wasShown();
    206     },
    207 
    208     willHide: function()
    209     {
    210         WebInspector.Panel.prototype.willHide.call(this);
    211         WebInspector.closeViewInDrawer();
    212     },
    213 
    214     /**
    215      * @param {WebInspector.Event} event
    216      */
    217     _uiSourceCodeAdded: function(event)
    218     {
    219         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
    220         this._addUISourceCode(uiSourceCode);
    221     },
    222 
    223     /**
    224      * @param {WebInspector.UISourceCode} uiSourceCode
    225      */
    226     _addUISourceCode: function(uiSourceCode)
    227     {
    228         if (this._toggleFormatSourceButton.toggled)
    229             uiSourceCode.setFormatted(true);
    230         if (uiSourceCode.project().isServiceProject())
    231             return;
    232         this._navigator.addUISourceCode(uiSourceCode);
    233         this._editorContainer.addUISourceCode(uiSourceCode);
    234         // Replace debugger script-based uiSourceCode with a network-based one.
    235         var currentUISourceCode = this._currentUISourceCode;
    236         if (currentUISourceCode && currentUISourceCode.project().isServiceProject() && currentUISourceCode !== uiSourceCode && currentUISourceCode.url === uiSourceCode.url) {
    237             this._showFile(uiSourceCode);
    238             this._editorContainer.removeUISourceCode(currentUISourceCode);
    239         }
    240     },
    241 
    242     _uiSourceCodeRemoved: function(event)
    243     {
    244         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
    245         this._removeUISourceCodes([uiSourceCode]);
    246     },
    247 
    248     /**
    249      * @param {Array.<WebInspector.UISourceCode>} uiSourceCodes
    250      */
    251     _removeUISourceCodes: function(uiSourceCodes)
    252     {
    253         for (var i = 0; i < uiSourceCodes.length; ++i) {
    254             this._navigator.removeUISourceCode(uiSourceCodes[i]);
    255             this._removeSourceFrame(uiSourceCodes[i]);
    256         }
    257         this._editorContainer.removeUISourceCodes(uiSourceCodes);
    258     },
    259 
    260     _consoleCommandEvaluatedInSelectedCallFrame: function(event)
    261     {
    262         this.sidebarPanes.scopechain.update(WebInspector.debuggerModel.selectedCallFrame());
    263     },
    264 
    265     _debuggerPaused: function()
    266     {
    267         var details = WebInspector.debuggerModel.debuggerPausedDetails();
    268 
    269         this._paused = true;
    270         this._waitingToPause = false;
    271         this._stepping = false;
    272 
    273         this._updateDebuggerButtons();
    274 
    275         WebInspector.inspectorView.setCurrentPanel(this);
    276         this.sidebarPanes.callstack.update(details.callFrames);
    277 
    278         if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) {
    279             WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData);
    280             function didCreateBreakpointHitStatusMessage(element)
    281             {
    282                 this.sidebarPanes.callstack.setStatus(element);
    283             }
    284             WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details.auxData, didCreateBreakpointHitStatusMessage.bind(this));
    285         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) {
    286             var eventName = details.auxData.eventName;
    287             this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.auxData.eventName);
    288             var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName, details.auxData);
    289             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
    290         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) {
    291             this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);
    292             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
    293         } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception)
    294             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData.description));
    295         else if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert)
    296             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));
    297         else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation)
    298             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"]));
    299         else if (details.reason === WebInspector.DebuggerModel.BreakReason.DebugCommand)
    300             this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a debugged function"));
    301         else {
    302             function didGetUILocation(uiLocation)
    303             {
    304                 var breakpoint = WebInspector.breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber);
    305                 if (!breakpoint)
    306                     return;
    307                 this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);
    308                 this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
    309             }
    310             if (details.callFrames.length)
    311                 details.callFrames[0].createLiveLocation(didGetUILocation.bind(this));
    312             else
    313                 console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
    314         }
    315 
    316         this._enableDebuggerSidebar(true);
    317         this._toggleDebuggerSidebarButton.setEnabled(false);
    318         window.focus();
    319         InspectorFrontendHost.bringToFront();
    320     },
    321 
    322     _debuggerResumed: function()
    323     {
    324         this._paused = false;
    325         this._waitingToPause = false;
    326         this._stepping = false;
    327 
    328         this._clearInterface();
    329         this._toggleDebuggerSidebarButton.setEnabled(true);
    330     },
    331 
    332     _debuggerWasEnabled: function()
    333     {
    334         this._updateDebuggerButtons();
    335     },
    336 
    337     _debuggerWasDisabled: function()
    338     {
    339         this._debuggerReset();
    340     },
    341 
    342     _debuggerReset: function()
    343     {
    344         this._debuggerResumed();
    345         this.sidebarPanes.watchExpressions.reset();
    346     },
    347 
    348     _projectWillReset: function(event)
    349     {
    350         var project = event.data;
    351         var uiSourceCodes = project.uiSourceCodes();
    352         this._removeUISourceCodes(uiSourceCodes);
    353         if (project.type() === WebInspector.projectTypes.Network)
    354             this._editorContainer.reset();
    355     },
    356 
    357     get visibleView()
    358     {
    359         return this._editorContainer.visibleView;
    360     },
    361 
    362     _updateScriptViewStatusBarItems: function()
    363     {
    364         this._scriptViewStatusBarItemsContainer.removeChildren();
    365         this._scriptViewStatusBarTextContainer.removeChildren();
    366 
    367         var sourceFrame = this.visibleView;
    368         if (sourceFrame) {
    369             var statusBarItems = sourceFrame.statusBarItems() || [];
    370             for (var i = 0; i < statusBarItems.length; ++i)
    371                 this._scriptViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
    372             var statusBarText = sourceFrame.statusBarText();
    373             if (statusBarText)
    374                 this._scriptViewStatusBarTextContainer.appendChild(statusBarText);
    375         }
    376     },
    377 
    378     /**
    379      * @param {Element} anchor
    380      */
    381     canShowAnchorLocation: function(anchor)
    382     {
    383         if (WebInspector.debuggerModel.debuggerEnabled() && anchor.uiSourceCode)
    384             return true;
    385         var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(anchor.href);
    386         if (uiSourceCode) {
    387             anchor.uiSourceCode = uiSourceCode;
    388             return true;
    389         }
    390         return false;
    391     },
    392 
    393     /**
    394      * @param {Element} anchor
    395      */
    396     showAnchorLocation: function(anchor)
    397     {
    398         this._showSourceLocation(anchor.uiSourceCode, anchor.lineNumber, anchor.columnNumber);
    399     },
    400 
    401     /**
    402      * @param {WebInspector.UISourceCode} uiSourceCode
    403      * @param {number=} lineNumber
    404      * @param {number=} columnNumber
    405      */
    406     showUISourceCode: function(uiSourceCode, lineNumber, columnNumber)
    407     {
    408         this._showSourceLocation(uiSourceCode, lineNumber, columnNumber);
    409     },
    410 
    411     /**
    412      * @param {WebInspector.UISourceCode} uiSourceCode
    413      * @param {number=} lineNumber
    414      * @param {number=} columnNumber
    415      */
    416     _showSourceLocation: function(uiSourceCode, lineNumber, columnNumber)
    417     {
    418         var sourceFrame = this._showFile(uiSourceCode);
    419         if (typeof lineNumber === "number")
    420             sourceFrame.highlightPosition(lineNumber, columnNumber);
    421         sourceFrame.focus();
    422 
    423         WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
    424             action: WebInspector.UserMetrics.UserActionNames.OpenSourceLink,
    425             url: uiSourceCode.originURL(),
    426             lineNumber: lineNumber
    427         });
    428     },
    429 
    430     /**
    431      * @param {WebInspector.UISourceCode} uiSourceCode
    432      * @return {WebInspector.SourceFrame}
    433      */
    434     _showFile: function(uiSourceCode)
    435     {
    436         var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
    437         if (this._currentUISourceCode === uiSourceCode)
    438             return sourceFrame;
    439         this._currentUISourceCode = uiSourceCode;
    440         if (!uiSourceCode.project().isServiceProject())
    441             this._navigator.revealUISourceCode(uiSourceCode, true);
    442         this._editorContainer.showFile(uiSourceCode);
    443         this._updateScriptViewStatusBarItems();
    444 
    445         if (this._currentUISourceCode.project().type() === WebInspector.projectTypes.Snippets)
    446             this._runSnippetButton.element.removeStyleClass("hidden");
    447         else
    448             this._runSnippetButton.element.addStyleClass("hidden");
    449 
    450         return sourceFrame;
    451     },
    452 
    453     /**
    454      * @param {WebInspector.UISourceCode} uiSourceCode
    455      * @return {WebInspector.SourceFrame}
    456      */
    457     _createSourceFrame: function(uiSourceCode)
    458     {
    459         var sourceFrame;
    460         switch (uiSourceCode.contentType()) {
    461         case WebInspector.resourceTypes.Script:
    462             sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
    463             break;
    464         case WebInspector.resourceTypes.Document:
    465             sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
    466             break;
    467         case WebInspector.resourceTypes.Stylesheet:
    468         default:
    469             sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
    470         break;
    471         }
    472         this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame);
    473         return sourceFrame;
    474     },
    475 
    476     /**
    477      * @param {WebInspector.UISourceCode} uiSourceCode
    478      * @return {WebInspector.SourceFrame}
    479      */
    480     _getOrCreateSourceFrame: function(uiSourceCode)
    481     {
    482         return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._createSourceFrame(uiSourceCode);
    483     },
    484 
    485     /**
    486      * @param {WebInspector.UISourceCode} uiSourceCode
    487      * @return {WebInspector.SourceFrame}
    488      */
    489     viewForFile: function(uiSourceCode)
    490     {
    491         return this._getOrCreateSourceFrame(uiSourceCode);
    492     },
    493 
    494     /**
    495      * @param {WebInspector.UISourceCode} uiSourceCode
    496      */
    497     _removeSourceFrame: function(uiSourceCode)
    498     {
    499         var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
    500         if (!sourceFrame)
    501             return;
    502         this._sourceFramesByUISourceCode.remove(uiSourceCode);
    503         sourceFrame.dispose();
    504     },
    505 
    506     _clearCurrentExecutionLine: function()
    507     {
    508         if (this._executionSourceFrame)
    509             this._executionSourceFrame.clearExecutionLine();
    510         delete this._executionSourceFrame;
    511     },
    512 
    513     _executionLineChanged: function(event)
    514     {
    515         var uiLocation = event.data;
    516 
    517         this._clearCurrentExecutionLine();
    518         if (!uiLocation)
    519             return;
    520         var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode);
    521         sourceFrame.setExecutionLine(uiLocation.lineNumber);
    522         this._executionSourceFrame = sourceFrame;
    523     },
    524 
    525     _revealExecutionLine: function(uiLocation)
    526     {
    527         var uiSourceCode = uiLocation.uiSourceCode;
    528         // Some scripts (anonymous and snippets evaluations) are not added to files select by default.
    529         if (this._currentUISourceCode && this._currentUISourceCode.scriptFile() && this._currentUISourceCode.scriptFile().isDivergingFromVM())
    530             return;
    531         if (this._toggleFormatSourceButton.toggled && !uiSourceCode.formatted())
    532             uiSourceCode.setFormatted(true);
    533         var sourceFrame = this._showFile(uiSourceCode);
    534         sourceFrame.revealLine(uiLocation.lineNumber);
    535         sourceFrame.focus();
    536     },
    537 
    538     _callFrameSelected: function(event)
    539     {
    540         var callFrame = event.data;
    541 
    542         if (!callFrame)
    543             return;
    544 
    545         this.sidebarPanes.scopechain.update(callFrame);
    546         this.sidebarPanes.watchExpressions.refreshExpressions();
    547         this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
    548         callFrame.createLiveLocation(this._revealExecutionLine.bind(this));
    549     },
    550 
    551     _editorClosed: function(event)
    552     {
    553         this._navigatorController.hideNavigatorOverlay();
    554         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
    555 
    556         if (this._currentUISourceCode === uiSourceCode)
    557             delete this._currentUISourceCode;
    558 
    559         // ScriptsNavigator does not need to update on EditorClosed.
    560         this._updateScriptViewStatusBarItems();
    561         WebInspector.searchController.resetSearch();
    562     },
    563 
    564     _editorSelected: function(event)
    565     {
    566         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
    567         var sourceFrame = this._showFile(uiSourceCode);
    568         this._navigatorController.hideNavigatorOverlay();
    569         if (!this._navigatorController.isNavigatorPinned())
    570             sourceFrame.focus();
    571         WebInspector.searchController.resetSearch();
    572     },
    573 
    574     _scriptSelected: function(event)
    575     {
    576         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data.uiSourceCode);
    577         var sourceFrame = this._showFile(uiSourceCode);
    578         this._navigatorController.hideNavigatorOverlay();
    579         if (sourceFrame && (!this._navigatorController.isNavigatorPinned() || event.data.focusSource))
    580             sourceFrame.focus();
    581     },
    582 
    583     _itemSearchStarted: function(event)
    584     {
    585         var searchText = /** @type {string} */ (event.data);
    586         WebInspector.OpenResourceDialog.show(this, this.editorView.mainElement, searchText);
    587     },
    588 
    589     _pauseOnExceptionStateChanged: function()
    590     {
    591         var pauseOnExceptionsState = WebInspector.settings.pauseOnExceptionStateString.get();
    592         switch (pauseOnExceptionsState) {
    593         case WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions:
    594             this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
    595             break;
    596         case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions:
    597             this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
    598             break;
    599         case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions:
    600             this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
    601             break;
    602         }
    603         this._pauseOnExceptionButton.state = pauseOnExceptionsState;
    604     },
    605 
    606     _updateDebuggerButtons: function()
    607     {
    608         if (WebInspector.debuggerModel.debuggerEnabled()) {
    609             this._pauseOnExceptionButton.visible = true;
    610         } else {
    611             this._pauseOnExceptionButton.visible = false;
    612         }
    613 
    614         if (this._paused) {
    615             this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Resume script execution (%s)."))
    616             this._pauseButton.state = true;
    617 
    618             this._pauseButton.setEnabled(true);
    619             this._stepOverButton.setEnabled(true);
    620             this._stepIntoButton.setEnabled(true);
    621             this._stepOutButton.setEnabled(true);
    622 
    623             this.debuggerStatusElement.textContent = WebInspector.UIString("Paused");
    624         } else {
    625             this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Pause script execution (%s)."))
    626             this._pauseButton.state = false;
    627 
    628             this._pauseButton.setEnabled(!this._waitingToPause);
    629             this._stepOverButton.setEnabled(false);
    630             this._stepIntoButton.setEnabled(false);
    631             this._stepOutButton.setEnabled(false);
    632 
    633             if (this._waitingToPause)
    634                 this.debuggerStatusElement.textContent = WebInspector.UIString("Pausing");
    635             else if (this._stepping)
    636                 this.debuggerStatusElement.textContent = WebInspector.UIString("Stepping");
    637             else
    638                 this.debuggerStatusElement.textContent = "";
    639         }
    640     },
    641 
    642     _clearInterface: function()
    643     {
    644         this.sidebarPanes.callstack.update(null);
    645         this.sidebarPanes.scopechain.update(null);
    646         this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
    647         WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight();
    648         this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
    649         this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
    650 
    651         this._clearCurrentExecutionLine();
    652         this._updateDebuggerButtons();
    653     },
    654 
    655     _togglePauseOnExceptions: function()
    656     {
    657         var nextStateMap = {};
    658         var stateEnum = WebInspector.DebuggerModel.PauseOnExceptionsState;
    659         nextStateMap[stateEnum.DontPauseOnExceptions] = stateEnum.PauseOnAllExceptions;
    660         nextStateMap[stateEnum.PauseOnAllExceptions] = stateEnum.PauseOnUncaughtExceptions;
    661         nextStateMap[stateEnum.PauseOnUncaughtExceptions] = stateEnum.DontPauseOnExceptions;
    662         WebInspector.settings.pauseOnExceptionStateString.set(nextStateMap[this._pauseOnExceptionButton.state]);
    663     },
    664 
    665     /**
    666      * @param {Event=} event
    667      * @return {boolean}
    668      */
    669     _runSnippet: function(event)
    670     {
    671         if (this._currentUISourceCode.project().type() !== WebInspector.projectTypes.Snippets)
    672             return false;
    673         WebInspector.scriptSnippetModel.evaluateScriptSnippet(this._currentUISourceCode);
    674         return true;
    675     },
    676 
    677     /**
    678      * @param {Event=} event
    679      * @return {boolean}
    680      */
    681     _togglePause: function(event)
    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         return true;
    695     },
    696 
    697     /**
    698      * @param {Event=} event
    699      * @return {boolean}
    700      */
    701     _stepOverClicked: function(event)
    702     {
    703         if (!this._paused)
    704             return true;
    705 
    706         this._paused = false;
    707         this._stepping = true;
    708 
    709         this._clearInterface();
    710 
    711         DebuggerAgent.stepOver();
    712         return true;
    713     },
    714 
    715     /**
    716      * @param {Event=} event
    717      * @return {boolean}
    718      */
    719     _stepIntoClicked: function(event)
    720     {
    721         if (!this._paused)
    722             return true;
    723 
    724         this._paused = false;
    725         this._stepping = true;
    726 
    727         this._clearInterface();
    728 
    729         DebuggerAgent.stepInto();
    730         return true;
    731     },
    732 
    733     /**
    734      * @param {Event=} event
    735      * @return {boolean}
    736      */
    737     _stepOutClicked: function(event)
    738     {
    739         if (!this._paused)
    740             return true;
    741 
    742         this._paused = false;
    743         this._stepping = true;
    744 
    745         this._clearInterface();
    746 
    747         DebuggerAgent.stepOut();
    748         return true;
    749     },
    750 
    751     _toggleBreakpointsClicked: function(event)
    752     {
    753         WebInspector.debuggerModel.setBreakpointsActive(!WebInspector.debuggerModel.breakpointsActive());
    754     },
    755 
    756     _breakpointsActiveStateChanged: function(event)
    757     {
    758         var active = event.data;
    759         this._toggleBreakpointsButton.toggled = !active;
    760         if (active) {
    761             this._toggleBreakpointsButton.title = WebInspector.UIString("Deactivate breakpoints.");
    762             WebInspector.inspectorView.element.removeStyleClass("breakpoints-deactivated");
    763             this.sidebarPanes.jsBreakpoints.listElement.removeStyleClass("breakpoints-list-deactivated");
    764         } else {
    765             this._toggleBreakpointsButton.title = WebInspector.UIString("Activate breakpoints.");
    766             WebInspector.inspectorView.element.addStyleClass("breakpoints-deactivated");
    767             this.sidebarPanes.jsBreakpoints.listElement.addStyleClass("breakpoints-list-deactivated");
    768         }
    769     },
    770 
    771     _createDebugToolbar: function()
    772     {
    773         var debugToolbar = document.createElement("div");
    774         debugToolbar.className = "status-bar";
    775         debugToolbar.id = "scripts-debug-toolbar";
    776 
    777         var title, handler;
    778         var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
    779 
    780         // Run snippet.
    781         title = WebInspector.UIString("Run snippet (%s).");
    782         handler = this._runSnippet.bind(this);
    783         this._runSnippetButton = this._createButtonAndRegisterShortcuts("scripts-run-snippet", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.RunSnippet);
    784         debugToolbar.appendChild(this._runSnippetButton.element);
    785         this._runSnippetButton.element.addStyleClass("hidden");
    786 
    787         // Continue.
    788         handler = this._togglePause.bind(this);
    789         this._pauseButton = this._createButtonAndRegisterShortcuts("scripts-pause", "", handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.PauseContinue);
    790         debugToolbar.appendChild(this._pauseButton.element);
    791 
    792         // Step over.
    793         title = WebInspector.UIString("Step over next function call (%s).");
    794         handler = this._stepOverClicked.bind(this);
    795         this._stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOver);
    796         debugToolbar.appendChild(this._stepOverButton.element);
    797 
    798         // Step into.
    799         title = WebInspector.UIString("Step into next function call (%s).");
    800         handler = this._stepIntoClicked.bind(this);
    801         this._stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepInto);
    802         debugToolbar.appendChild(this._stepIntoButton.element);
    803 
    804         // Step out.
    805         title = WebInspector.UIString("Step out of current function (%s).");
    806         handler = this._stepOutClicked.bind(this);
    807         this._stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOut);
    808         debugToolbar.appendChild(this._stepOutButton.element);
    809 
    810         this._toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate breakpoints."), "scripts-toggle-breakpoints");
    811         this._toggleBreakpointsButton.toggled = false;
    812         this._toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this);
    813         debugToolbar.appendChild(this._toggleBreakpointsButton.element);
    814 
    815         this.debuggerStatusElement = document.createElement("div");
    816         this.debuggerStatusElement.id = "scripts-debugger-status";
    817         debugToolbar.appendChild(this.debuggerStatusElement);
    818 
    819         return debugToolbar;
    820     },
    821 
    822     /**
    823      * @param {WebInspector.StatusBarButton} button
    824      * @param {string} buttonTitle
    825      */
    826     _updateButtonTitle: function(button, buttonTitle)
    827     {
    828         var hasShortcuts = button.shortcuts && button.shortcuts.length;
    829         if (hasShortcuts)
    830             button.title = String.vsprintf(buttonTitle, [button.shortcuts[0].name]);
    831         else
    832             button.title = buttonTitle;
    833     },
    834 
    835     /**
    836      * @param {string} buttonId
    837      * @param {string} buttonTitle
    838      * @param {function(Event=):boolean} handler
    839      * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
    840      * @return {WebInspector.StatusBarButton}
    841      */
    842     _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts)
    843     {
    844         var button = new WebInspector.StatusBarButton(buttonTitle, buttonId);
    845         button.element.addEventListener("click", handler, false);
    846         button.shortcuts = shortcuts;
    847         this._updateButtonTitle(button, buttonTitle);
    848         this.registerShortcuts(shortcuts, handler);
    849         return button;
    850     },
    851 
    852     searchCanceled: function()
    853     {
    854         if (this._searchView)
    855             this._searchView.searchCanceled();
    856 
    857         delete this._searchView;
    858         delete this._searchQuery;
    859     },
    860 
    861     /**
    862      * @param {string} query
    863      * @param {boolean} shouldJump
    864      */
    865     performSearch: function(query, shouldJump)
    866     {
    867         WebInspector.searchController.updateSearchMatchesCount(0, this);
    868 
    869         if (!this.visibleView)
    870             return;
    871 
    872         this._searchView = this.visibleView;
    873         this._searchQuery = query;
    874 
    875         function finishedCallback(view, searchMatches)
    876         {
    877             if (!searchMatches)
    878                 return;
    879 
    880             WebInspector.searchController.updateSearchMatchesCount(searchMatches, this);
    881         }
    882 
    883         function currentMatchChanged(currentMatchIndex)
    884         {
    885             WebInspector.searchController.updateCurrentMatchIndex(currentMatchIndex, this);
    886         }
    887 
    888         this._searchView.performSearch(query, shouldJump, finishedCallback.bind(this), currentMatchChanged.bind(this));
    889     },
    890 
    891     /**
    892      * @return {number}
    893      */
    894     minimalSearchQuerySize: function()
    895     {
    896         return 0;
    897     },
    898 
    899     jumpToNextSearchResult: function()
    900     {
    901         if (!this._searchView)
    902             return;
    903 
    904         if (this._searchView !== this.visibleView) {
    905             this.performSearch(this._searchQuery, true);
    906             return;
    907         }
    908 
    909         this._searchView.jumpToNextSearchResult();
    910         return true;
    911     },
    912 
    913     jumpToPreviousSearchResult: function()
    914     {
    915         if (!this._searchView)
    916             return;
    917 
    918         if (this._searchView !== this.visibleView) {
    919             this.performSearch(this._searchQuery, true);
    920             if (this._searchView)
    921                 this._searchView.jumpToLastSearchResult();
    922             return;
    923         }
    924 
    925         this._searchView.jumpToPreviousSearchResult();
    926     },
    927 
    928     /**
    929      * @return {boolean}
    930      */
    931     canSearchAndReplace: function()
    932     {
    933         var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
    934         return !!view && view.canEditSource();
    935     },
    936 
    937     /**
    938      * @param {string} text
    939      */
    940     replaceSelectionWith: function(text)
    941     {
    942         var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
    943         view.replaceSearchMatchWith(text);
    944     },
    945 
    946     /**
    947      * @param {string} query
    948      * @param {string} text
    949      */
    950     replaceAllWith: function(query, text)
    951     {
    952         var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
    953         view.replaceAllWith(query, text);
    954     },
    955 
    956     _toggleFormatSource: function()
    957     {
    958         this._toggleFormatSourceButton.toggled = !this._toggleFormatSourceButton.toggled;
    959         var uiSourceCodes = this._workspace.uiSourceCodes();
    960         for (var i = 0; i < uiSourceCodes.length; ++i)
    961             uiSourceCodes[i].setFormatted(this._toggleFormatSourceButton.toggled);
    962 
    963         var currentFile = this._editorContainer.currentFile();
    964 
    965         WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
    966             action: WebInspector.UserMetrics.UserActionNames.TogglePrettyPrint,
    967             enabled: this._toggleFormatSourceButton.toggled,
    968             url: currentFile ? currentFile.originURL() : null
    969         });
    970     },
    971 
    972     addToWatch: function(expression)
    973     {
    974         this.sidebarPanes.watchExpressions.addExpression(expression);
    975     },
    976 
    977     /**
    978      * @return {boolean}
    979      */
    980     _toggleBreakpoint: function()
    981     {
    982         var sourceFrame = this.visibleView;
    983         if (!sourceFrame)
    984             return false;
    985 
    986         if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
    987             var javaScriptSourceFrame = /** @type {WebInspector.JavaScriptSourceFrame} */ (sourceFrame);
    988             javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
    989             return true;
    990         }
    991         return false;
    992     },
    993 
    994     /**
    995      * @param {Event=} event
    996      * @return {boolean}
    997      */
    998     _showOutlineDialog: function(event)
    999     {
   1000         var uiSourceCode = this._editorContainer.currentFile();
   1001         if (!uiSourceCode)
   1002             return false;
   1003 
   1004         switch (uiSourceCode.contentType()) {
   1005         case WebInspector.resourceTypes.Document:
   1006         case WebInspector.resourceTypes.Script:
   1007             WebInspector.JavaScriptOutlineDialog.show(this.visibleView, uiSourceCode);
   1008             return true;
   1009         case WebInspector.resourceTypes.Stylesheet:
   1010             WebInspector.StyleSheetOutlineDialog.show(this.visibleView, uiSourceCode);
   1011             return true;
   1012         }
   1013         return false;
   1014     },
   1015 
   1016     _installDebuggerSidebarController: function()
   1017     {
   1018         this._toggleDebuggerSidebarButton = new WebInspector.StatusBarButton("", "right-sidebar-show-hide-button scripts-debugger-show-hide-button", 3);
   1019         this._toggleDebuggerSidebarButton.addEventListener("click", clickHandler, this);
   1020         this.editorView.element.appendChild(this._toggleDebuggerSidebarButton.element);
   1021         this._enableDebuggerSidebar(!WebInspector.settings.debuggerSidebarHidden.get());
   1022 
   1023         function clickHandler()
   1024         {
   1025             this._enableDebuggerSidebar(this._toggleDebuggerSidebarButton.state === "left");
   1026         }
   1027     },
   1028 
   1029     /**
   1030      * @param {boolean} show
   1031      */
   1032     _enableDebuggerSidebar: function(show)
   1033     {
   1034         this._toggleDebuggerSidebarButton.state = show ? "right" : "left";
   1035         this._toggleDebuggerSidebarButton.title = show ? WebInspector.UIString("Hide debugger") : WebInspector.UIString("Show debugger");
   1036         if (show)
   1037             this.splitView.showSidebarElement();
   1038         else
   1039             this.splitView.hideSidebarElement();
   1040         this._debugSidebarResizeWidgetElement.enableStyleClass("hidden", !show);
   1041         WebInspector.settings.debuggerSidebarHidden.set(!show);
   1042     },
   1043 
   1044     /**
   1045      * @param {WebInspector.Event} event
   1046      */
   1047     _itemCreationRequested: function(event)
   1048     {
   1049         var project = event.data.project;
   1050         var path = event.data.path;
   1051         var filePath;
   1052         var shouldHideNavigator;
   1053         var uiSourceCode;
   1054         project.createFile(path, null, fileCreated.bind(this));
   1055 
   1056         /**
   1057          * @param {?string} path
   1058          */
   1059         function fileCreated(path)
   1060         {
   1061             if (!path)
   1062                 return;
   1063             filePath = path;
   1064             uiSourceCode = project.uiSourceCode(filePath);
   1065             this._showSourceLocation(uiSourceCode);
   1066 
   1067             shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
   1068             if (this._navigatorController.isNavigatorHidden())
   1069                 this._navigatorController.showNavigatorOverlay();
   1070             this._navigator.rename(uiSourceCode, callback.bind(this));
   1071         }
   1072 
   1073         /**
   1074          * @param {boolean} committed
   1075          */
   1076         function callback(committed)
   1077         {
   1078             if (shouldHideNavigator)
   1079                 this._navigatorController.hideNavigatorOverlay();
   1080 
   1081             if (!committed) {
   1082                 project.deleteFile(uiSourceCode);
   1083                 return;
   1084             }
   1085 
   1086             this._showSourceLocation(uiSourceCode);
   1087         }
   1088     },
   1089 
   1090     /**
   1091      * @param {WebInspector.Event} event
   1092      */
   1093     _itemRenamingRequested: function(event)
   1094     {
   1095         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
   1096 
   1097         var shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
   1098         if (this._navigatorController.isNavigatorHidden())
   1099             this._navigatorController.showNavigatorOverlay();
   1100         this._navigator.rename(uiSourceCode, callback.bind(this));
   1101 
   1102         /**
   1103          * @param {boolean} committed
   1104          */
   1105         function callback(committed)
   1106         {
   1107             if (shouldHideNavigator && committed) {
   1108                 this._navigatorController.hideNavigatorOverlay();
   1109                 this._showSourceLocation(uiSourceCode);
   1110             }
   1111         }
   1112     },
   1113 
   1114     /**
   1115      * @param {WebInspector.UISourceCode} uiSourceCode
   1116      */
   1117     _showLocalHistory: function(uiSourceCode)
   1118     {
   1119         WebInspector.RevisionHistoryView.showHistory(uiSourceCode);
   1120     },
   1121 
   1122     /**
   1123      * @param {WebInspector.ContextMenu} contextMenu
   1124      * @param {Object} target
   1125      */
   1126     appendApplicableItems: function(event, contextMenu, target)
   1127     {
   1128         this._appendUISourceCodeItems(contextMenu, target);
   1129         this._appendFunctionItems(contextMenu, target);
   1130     },
   1131 
   1132     /**
   1133      * @param {WebInspector.UISourceCode} uiSourceCode
   1134      */
   1135     _mapFileSystemToNetwork: function(uiSourceCode)
   1136     {
   1137         WebInspector.SelectUISourceCodeForProjectTypeDialog.show(uiSourceCode.name(), WebInspector.projectTypes.Network, mapFileSystemToNetwork.bind(this), this.editorView.mainElement)
   1138 
   1139         /**
   1140          * @param {WebInspector.UISourceCode} networkUISourceCode
   1141          */
   1142         function mapFileSystemToNetwork(networkUISourceCode)
   1143         {
   1144             this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceProvider);
   1145         }
   1146     },
   1147 
   1148     /**
   1149      * @param {WebInspector.UISourceCode} uiSourceCode
   1150      */
   1151     _removeNetworkMapping: function(uiSourceCode)
   1152     {
   1153         if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?")))
   1154             this._workspace.removeMapping(uiSourceCode);
   1155     },
   1156 
   1157     /**
   1158      * @param {WebInspector.UISourceCode} networkUISourceCode
   1159      */
   1160     _mapNetworkToFileSystem: function(networkUISourceCode)
   1161     {
   1162         WebInspector.SelectUISourceCodeForProjectTypeDialog.show(networkUISourceCode.name(), WebInspector.projectTypes.FileSystem, mapNetworkToFileSystem.bind(this), this.editorView.mainElement)
   1163 
   1164         /**
   1165          * @param {WebInspector.UISourceCode} uiSourceCode
   1166          */
   1167         function mapNetworkToFileSystem(uiSourceCode)
   1168         {
   1169             this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceProvider);
   1170         }
   1171     },
   1172 
   1173     /**
   1174      * @param {WebInspector.ContextMenu} contextMenu
   1175      * @param {WebInspector.UISourceCode} uiSourceCode
   1176      */
   1177     _appendUISourceCodeMappingItems: function(contextMenu, uiSourceCode)
   1178     {
   1179         if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
   1180             var hasMappings = !!uiSourceCode.url;
   1181             if (!hasMappings)
   1182                 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this._mapFileSystemToNetwork.bind(this, uiSourceCode));
   1183             else
   1184                 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode));
   1185         }
   1186 
   1187         if (uiSourceCode.project().type() === WebInspector.projectTypes.Network) {
   1188             /**
   1189              * @param {WebInspector.Project} project
   1190              */
   1191             function filterProject(project)
   1192             {
   1193                 return project.type() === WebInspector.projectTypes.FileSystem;
   1194             }
   1195 
   1196             if (!this._workspace.projects().filter(filterProject).length)
   1197                 return;
   1198             if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode)
   1199                 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this._mapNetworkToFileSystem.bind(this, uiSourceCode));
   1200         }
   1201     },
   1202 
   1203     /**
   1204      * @param {WebInspector.ContextMenu} contextMenu
   1205      * @param {Object} target
   1206      */
   1207     _appendUISourceCodeItems: function(contextMenu, target)
   1208     {
   1209         if (!(target instanceof WebInspector.UISourceCode))
   1210             return;
   1211 
   1212         var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (target);
   1213         contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Local modifications\u2026" : "Local Modifications\u2026"), this._showLocalHistory.bind(this, uiSourceCode));
   1214 
   1215         if (WebInspector.isolatedFileSystemManager.supportsFileSystems())
   1216             this._appendUISourceCodeMappingItems(contextMenu, uiSourceCode);
   1217 
   1218         var resource = WebInspector.resourceForURL(uiSourceCode.url);
   1219         if (resource && resource.request)
   1220             contextMenu.appendApplicableItems(resource.request);
   1221     },
   1222 
   1223     /**
   1224      * @param {WebInspector.ContextMenu} contextMenu
   1225      * @param {Object} target
   1226      */
   1227     _appendFunctionItems: function(contextMenu, target)
   1228     {
   1229         if (!(target instanceof WebInspector.RemoteObject))
   1230             return;
   1231         var remoteObject = /** @type {WebInspector.RemoteObject} */ (target);
   1232         if (remoteObject.type !== "function")
   1233             return;
   1234 
   1235         function didGetDetails(error, response)
   1236         {
   1237             if (error) {
   1238                 console.error(error);
   1239                 return;
   1240             }
   1241 
   1242             WebInspector.inspectorView.setCurrentPanel(this);
   1243             var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(response.location);
   1244             this._showSourceLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
   1245         }
   1246 
   1247         function revealFunction()
   1248         {
   1249             DebuggerAgent.getFunctionDetails(remoteObject.objectId, didGetDetails.bind(this));
   1250         }
   1251 
   1252         contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Show function definition" : "Show Function Definition"), revealFunction.bind(this));
   1253     },
   1254 
   1255     showGoToSourceDialog: function()
   1256     {
   1257         var uiSourceCodes = this._editorContainer.historyUISourceCodes();
   1258         /** @type {!Map.<WebInspector.UISourceCode, number>} */
   1259         var defaultScores = new Map();
   1260         for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element
   1261             defaultScores.put(uiSourceCodes[i], uiSourceCodes.length - i);
   1262         WebInspector.OpenResourceDialog.show(this, this.editorView.mainElement, undefined, defaultScores);
   1263     },
   1264 
   1265     _dockSideChanged: function()
   1266     {
   1267         var dockSide = WebInspector.dockController.dockSide();
   1268         var vertically = dockSide === WebInspector.DockController.State.DockedToRight && WebInspector.settings.splitVerticallyWhenDockedToRight.get();
   1269         this._splitVertically(vertically);
   1270     },
   1271 
   1272     /**
   1273      * @param {boolean} vertically
   1274      */
   1275     _splitVertically: function(vertically)
   1276     {
   1277         if (this.sidebarPaneView && vertically === !this.splitView.isVertical())
   1278             return;
   1279 
   1280         if (this.sidebarPaneView)
   1281             this.sidebarPaneView.detach();
   1282 
   1283         this.splitView.setVertical(!vertically);
   1284 
   1285         if (!vertically) {
   1286             this.sidebarPaneView = new WebInspector.SidebarPaneStack();
   1287             for (var pane in this.sidebarPanes)
   1288                 this.sidebarPaneView.addPane(this.sidebarPanes[pane]);
   1289 
   1290             this.sidebarElement.appendChild(this.debugToolbar);
   1291         } else {
   1292             this._enableDebuggerSidebar(true);
   1293 
   1294             this.sidebarPaneView = new WebInspector.SplitView(true, this.name + "PanelSplitSidebarRatio", 0.5);
   1295 
   1296             var group1 = new WebInspector.SidebarPaneStack();
   1297             group1.show(this.sidebarPaneView.firstElement());
   1298             group1.element.id = "scripts-sidebar-stack-pane";
   1299             group1.addPane(this.sidebarPanes.callstack);
   1300             group1.addPane(this.sidebarPanes.jsBreakpoints);
   1301             group1.addPane(this.sidebarPanes.domBreakpoints);
   1302             group1.addPane(this.sidebarPanes.xhrBreakpoints);
   1303             group1.addPane(this.sidebarPanes.eventListenerBreakpoints);
   1304             if (this.sidebarPanes.workerList)
   1305                 group1.addPane(this.sidebarPanes.workerList);
   1306 
   1307             var group2 = new WebInspector.SidebarTabbedPane();
   1308             group2.show(this.sidebarPaneView.secondElement());
   1309             group2.addPane(this.sidebarPanes.scopechain);
   1310             group2.addPane(this.sidebarPanes.watchExpressions);
   1311 
   1312             this.sidebarPaneView.firstElement().appendChild(this.debugToolbar);
   1313         }
   1314 
   1315         this.sidebarPaneView.element.id = "scripts-debug-sidebar-contents";
   1316         this.sidebarPaneView.show(this.splitView.sidebarElement);
   1317 
   1318         this.sidebarPanes.scopechain.expand();
   1319         this.sidebarPanes.jsBreakpoints.expand();
   1320         this.sidebarPanes.callstack.expand();
   1321 
   1322         if (WebInspector.settings.watchExpressions.get().length > 0)
   1323             this.sidebarPanes.watchExpressions.expand();
   1324     },
   1325 
   1326     /**
   1327      * @return {boolean}
   1328      */
   1329     canSetFooterElement: function()
   1330     {
   1331         return true;
   1332     },
   1333 
   1334     /**
   1335      * @param {Element?} element
   1336      */
   1337     setFooterElement: function(element)
   1338     {
   1339         if (element) {
   1340             this._editorFooterElement.removeStyleClass("hidden");
   1341             this._editorFooterElement.appendChild(element);
   1342             this._editorContentsElement.style.bottom = this._editorFooterElement.offsetHeight + "px";
   1343         } else {
   1344             this._editorFooterElement.addStyleClass("hidden");
   1345             this._editorFooterElement.removeChildren();
   1346             this._editorContentsElement.style.bottom = 0;
   1347         }
   1348         this.doResize();
   1349     },
   1350 
   1351     __proto__: WebInspector.Panel.prototype
   1352 }
   1353