Home | History | Annotate | Download | only in front-end
      1 /*
      2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 WebInspector.ScriptsPanel = function()
     27 {
     28     WebInspector.Panel.call(this, "scripts");
     29 
     30     this._presentationModel = new WebInspector.DebuggerPresentationModel();
     31 
     32     this.topStatusBar = document.createElement("div");
     33     this.topStatusBar.className = "status-bar";
     34     this.topStatusBar.id = "scripts-status-bar";
     35     this.element.appendChild(this.topStatusBar);
     36 
     37     this.backButton = document.createElement("button");
     38     this.backButton.className = "status-bar-item";
     39     this.backButton.id = "scripts-back";
     40     this.backButton.title = WebInspector.UIString("Show the previous script resource.");
     41     this.backButton.disabled = true;
     42     this.backButton.appendChild(document.createElement("img"));
     43     this.backButton.addEventListener("click", this._goBack.bind(this), false);
     44     this.topStatusBar.appendChild(this.backButton);
     45 
     46     this.forwardButton = document.createElement("button");
     47     this.forwardButton.className = "status-bar-item";
     48     this.forwardButton.id = "scripts-forward";
     49     this.forwardButton.title = WebInspector.UIString("Show the next script resource.");
     50     this.forwardButton.disabled = true;
     51     this.forwardButton.appendChild(document.createElement("img"));
     52     this.forwardButton.addEventListener("click", this._goForward.bind(this), false);
     53     this.topStatusBar.appendChild(this.forwardButton);
     54 
     55     this._filesSelectElement = document.createElement("select");
     56     this._filesSelectElement.className = "status-bar-item";
     57     this._filesSelectElement.id = "scripts-files";
     58     this._filesSelectElement.addEventListener("change", this._filesSelectChanged.bind(this), false);
     59     this.topStatusBar.appendChild(this._filesSelectElement);
     60 
     61     this.functionsSelectElement = document.createElement("select");
     62     this.functionsSelectElement.className = "status-bar-item";
     63     this.functionsSelectElement.id = "scripts-functions";
     64 
     65     // FIXME: append the functions select element to the top status bar when it is implemented.
     66     // this.topStatusBar.appendChild(this.functionsSelectElement);
     67 
     68     this.sidebarButtonsElement = document.createElement("div");
     69     this.sidebarButtonsElement.id = "scripts-sidebar-buttons";
     70     this.topStatusBar.appendChild(this.sidebarButtonsElement);
     71 
     72     this.pauseButton = document.createElement("button");
     73     this.pauseButton.className = "status-bar-item";
     74     this.pauseButton.id = "scripts-pause";
     75     this.pauseButton.title = WebInspector.UIString("Pause script execution.");
     76     this.pauseButton.disabled = true;
     77     this.pauseButton.appendChild(document.createElement("img"));
     78     this.pauseButton.addEventListener("click", this._togglePause.bind(this), false);
     79     this.sidebarButtonsElement.appendChild(this.pauseButton);
     80 
     81     this.stepOverButton = document.createElement("button");
     82     this.stepOverButton.className = "status-bar-item";
     83     this.stepOverButton.id = "scripts-step-over";
     84     this.stepOverButton.title = WebInspector.UIString("Step over next function call.");
     85     this.stepOverButton.disabled = true;
     86     this.stepOverButton.addEventListener("click", this._stepOverClicked.bind(this), false);
     87     this.stepOverButton.appendChild(document.createElement("img"));
     88     this.sidebarButtonsElement.appendChild(this.stepOverButton);
     89 
     90     this.stepIntoButton = document.createElement("button");
     91     this.stepIntoButton.className = "status-bar-item";
     92     this.stepIntoButton.id = "scripts-step-into";
     93     this.stepIntoButton.title = WebInspector.UIString("Step into next function call.");
     94     this.stepIntoButton.disabled = true;
     95     this.stepIntoButton.addEventListener("click", this._stepIntoClicked.bind(this), false);
     96     this.stepIntoButton.appendChild(document.createElement("img"));
     97     this.sidebarButtonsElement.appendChild(this.stepIntoButton);
     98 
     99     this.stepOutButton = document.createElement("button");
    100     this.stepOutButton.className = "status-bar-item";
    101     this.stepOutButton.id = "scripts-step-out";
    102     this.stepOutButton.title = WebInspector.UIString("Step out of current function.");
    103     this.stepOutButton.disabled = true;
    104     this.stepOutButton.addEventListener("click", this._stepOutClicked.bind(this), false);
    105     this.stepOutButton.appendChild(document.createElement("img"));
    106     this.sidebarButtonsElement.appendChild(this.stepOutButton);
    107 
    108     this.toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate all breakpoints."), "toggle-breakpoints");
    109     this.toggleBreakpointsButton.toggled = true;
    110     this.toggleBreakpointsButton.addEventListener("click", this.toggleBreakpointsClicked.bind(this), false);
    111     this.sidebarButtonsElement.appendChild(this.toggleBreakpointsButton.element);
    112 
    113     this.debuggerStatusElement = document.createElement("div");
    114     this.debuggerStatusElement.id = "scripts-debugger-status";
    115     this.sidebarButtonsElement.appendChild(this.debuggerStatusElement);
    116 
    117     this.viewsContainerElement = document.createElement("div");
    118     this.viewsContainerElement.id = "script-resource-views";
    119 
    120     this.sidebarElement = document.createElement("div");
    121     this.sidebarElement.id = "scripts-sidebar";
    122 
    123     this.sidebarResizeElement = document.createElement("div");
    124     this.sidebarResizeElement.className = "sidebar-resizer-vertical";
    125     this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarResizeDrag.bind(this), false);
    126 
    127     this.sidebarResizeWidgetElement = document.createElement("div");
    128     this.sidebarResizeWidgetElement.id = "scripts-sidebar-resizer-widget";
    129     this.sidebarResizeWidgetElement.addEventListener("mousedown", this._startSidebarResizeDrag.bind(this), false);
    130     this.topStatusBar.appendChild(this.sidebarResizeWidgetElement);
    131 
    132     this.sidebarPanes = {};
    133     this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
    134     this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(this._presentationModel);
    135     this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
    136     this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(this._presentationModel, this._showSourceLine.bind(this));
    137     if (Preferences.nativeInstrumentationEnabled) {
    138         this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane;
    139         this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
    140         this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
    141     }
    142 
    143     this.sidebarPanes.workers = new WebInspector.WorkersSidebarPane();
    144 
    145     for (var pane in this.sidebarPanes)
    146         this.sidebarElement.appendChild(this.sidebarPanes[pane].element);
    147 
    148     this.sidebarPanes.callstack.expanded = true;
    149 
    150     this.sidebarPanes.scopechain.expanded = true;
    151     this.sidebarPanes.jsBreakpoints.expanded = true;
    152 
    153     var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel.");
    154     var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower.");
    155     var panelEnablerButton = WebInspector.UIString("Enable Debugging");
    156 
    157     this.panelEnablerView = new WebInspector.PanelEnablerView("scripts", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton);
    158     this.panelEnablerView.addEventListener("enable clicked", this._enableDebugging, this);
    159 
    160     this.element.appendChild(this.panelEnablerView.element);
    161     this.element.appendChild(this.viewsContainerElement);
    162     this.element.appendChild(this.sidebarElement);
    163     this.element.appendChild(this.sidebarResizeElement);
    164 
    165     this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item");
    166     this.enableToggleButton.addEventListener("click", this._toggleDebugging.bind(this), false);
    167     if (Preferences.debuggerAlwaysEnabled)
    168         this.enableToggleButton.element.addStyleClass("hidden");
    169 
    170     this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
    171     this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions.bind(this), false);
    172 
    173     this._registerShortcuts();
    174 
    175     this._debuggerEnabled = Preferences.debuggerAlwaysEnabled;
    176 
    177     this.reset();
    178 
    179     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
    180     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerWasDisabled, this);
    181 
    182     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.SourceFileAdded, this._sourceFileAdded, this)
    183     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.SourceFileChanged, this._sourceFileChanged, this);
    184     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.ConsoleMessageAdded, this._consoleMessageAdded, this);
    185     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, this._breakpointAdded, this);
    186     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
    187     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerPaused, this._debuggerPaused, this);
    188     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerResumed, this._debuggerResumed, this);
    189     this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, this._callFrameSelected, this);
    190 
    191     var enableDebugger = Preferences.debuggerAlwaysEnabled || WebInspector.settings.debuggerEnabled;
    192     if (enableDebugger || InspectorFrontendHost.loadSessionSetting("debugger-enabled") === "true")
    193         WebInspector.debuggerModel.enableDebugger();
    194 }
    195 
    196 // Keep these in sync with WebCore::ScriptDebugServer
    197 WebInspector.ScriptsPanel.PauseOnExceptionsState = {
    198     DontPauseOnExceptions : "none",
    199     PauseOnAllExceptions : "all",
    200     PauseOnUncaughtExceptions: "uncaught"
    201 };
    202 
    203 WebInspector.ScriptsPanel.BrowserBreakpointTypes = {
    204     DOM: "DOM",
    205     EventListener: "EventListener",
    206     XHR: "XHR"
    207 }
    208 
    209 WebInspector.ScriptsPanel.prototype = {
    210     get toolbarItemLabel()
    211     {
    212         return WebInspector.UIString("Scripts");
    213     },
    214 
    215     get statusBarItems()
    216     {
    217         return [this.enableToggleButton.element, this._pauseOnExceptionButton.element];
    218     },
    219 
    220     get defaultFocusedElement()
    221     {
    222         return this._filesSelectElement;
    223     },
    224 
    225     get paused()
    226     {
    227         return this._paused;
    228     },
    229 
    230     show: function()
    231     {
    232         WebInspector.Panel.prototype.show.call(this);
    233         this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth - 3) + "px";
    234         if (Preferences.nativeInstrumentationEnabled)
    235             this.sidebarElement.insertBefore(this.sidebarPanes.domBreakpoints.element, this.sidebarPanes.xhrBreakpoints.element);
    236 
    237         if (this.visibleView)
    238             this.visibleView.show(this.viewsContainerElement);
    239     },
    240 
    241     hide: function()
    242     {
    243         if (this.visibleView)
    244             this.visibleView.hide();
    245         WebInspector.Panel.prototype.hide.call(this);
    246     },
    247 
    248     get breakpointsActivated()
    249     {
    250         return this.toggleBreakpointsButton.toggled;
    251     },
    252 
    253     _sourceFileAdded: function(event)
    254     {
    255         var sourceFile = event.data;
    256 
    257         if (!sourceFile.url) {
    258             // Anonymous sources are shown only when stepping.
    259             return;
    260         }
    261 
    262         this._addOptionToFilesSelect(sourceFile.id);
    263 
    264         var lastViewedURL = WebInspector.settings.lastViewedScriptFile;
    265         if (this._filesSelectElement.length === 1) {
    266             // Option we just added is the only option in files select.
    267             // We have to show corresponding source frame immediately.
    268             this._showSourceFrameAndAddToHistory(sourceFile.id);
    269             // Restore original value of lastViewedScriptFile because
    270             // source frame was shown as a result of initial load.
    271             WebInspector.settings.lastViewedScriptFile = lastViewedURL;
    272         } else if (sourceFile.url === lastViewedURL)
    273             this._showSourceFrameAndAddToHistory(sourceFile.id);
    274     },
    275 
    276     _addOptionToFilesSelect: function(sourceFileId)
    277     {
    278         var sourceFile = this._presentationModel.sourceFile(sourceFileId);
    279         var select = this._filesSelectElement;
    280         var option = document.createElement("option");
    281         option.text = sourceFile.url ? WebInspector.displayNameForURL(sourceFile.url) : WebInspector.UIString("(program)");
    282         if (sourceFile.isContentScript)
    283             option.addStyleClass("extension-script");
    284         function optionCompare(a, b)
    285         {
    286             if (a.text === b.text)
    287                 return 0;
    288             return a.text < b.text ? -1 : 1;
    289         }
    290         var insertionIndex = insertionIndexForObjectInListSortedByFunction(option, select.childNodes, optionCompare);
    291         if (insertionIndex < 0)
    292             select.appendChild(option);
    293         else
    294             select.insertBefore(option, select.childNodes.item(insertionIndex));
    295 
    296         option._sourceFileId = sourceFileId;
    297         this._sourceFileIdToFilesSelectOption[sourceFileId] = option;
    298     },
    299 
    300     setScriptSourceIsBeingEdited: function(sourceFileId, inEditMode)
    301     {
    302         var option = this._sourceFileIdToFilesSelectOption[sourceFileId];
    303         if (!option)
    304             return;
    305         if (inEditMode)
    306             option.text = option.text.replace(/[^*]$/, "$&*");
    307         else
    308             option.text = option.text.replace(/[*]$/, "");
    309     },
    310 
    311     addConsoleMessage: function(message)
    312     {
    313         if (message.isErrorOrWarning() && message.message)
    314             this._presentationModel.addConsoleMessage(message);
    315     },
    316 
    317     clearConsoleMessages: function()
    318     {
    319         this._presentationModel.clearConsoleMessages();
    320         for (var sourceFileId in this._sourceFileIdToSourceFrame)
    321             this._sourceFileIdToSourceFrame[sourceFileId].clearMessages();
    322     },
    323 
    324     _consoleMessageAdded: function(event)
    325     {
    326         var message = event.data;
    327 
    328         var sourceFrame = this._sourceFileIdToSourceFrame[message.sourceFileId];
    329         if (sourceFrame && sourceFrame.loaded)
    330             sourceFrame.addMessageToSource(message.lineNumber, message.originalMessage);
    331     },
    332 
    333     _breakpointAdded: function(event)
    334     {
    335         var breakpoint = event.data;
    336 
    337         var sourceFrame = this._sourceFileIdToSourceFrame[breakpoint.sourceFileId];
    338         if (sourceFrame && sourceFrame.loaded)
    339             sourceFrame.addBreakpoint(breakpoint.lineNumber, breakpoint.resolved, breakpoint.condition, breakpoint.enabled);
    340 
    341         this.sidebarPanes.jsBreakpoints.addBreakpoint(breakpoint);
    342     },
    343 
    344     _breakpointRemoved: function(event)
    345     {
    346         var breakpoint = event.data;
    347 
    348         var sourceFrame = this._sourceFileIdToSourceFrame[breakpoint.sourceFileId];
    349         if (sourceFrame && sourceFrame.loaded)
    350             sourceFrame.removeBreakpoint(breakpoint.lineNumber);
    351 
    352         this.sidebarPanes.jsBreakpoints.removeBreakpoint(breakpoint.sourceFileId, breakpoint.lineNumber);
    353     },
    354 
    355     evaluateInSelectedCallFrame: function(code, objectGroup, includeCommandLineAPI, callback)
    356     {
    357         var selectedCallFrame = this._presentationModel.selectedCallFrame;
    358         selectedCallFrame.evaluate(code, objectGroup, includeCommandLineAPI, callback);
    359     },
    360 
    361     getSelectedCallFrameVariables: function(callback)
    362     {
    363         var result = { this: true };
    364 
    365         var selectedCallFrame = this._presentationModel.selectedCallFrame;
    366         if (!selectedCallFrame)
    367             callback(result);
    368 
    369         var pendingRequests = 0;
    370 
    371         function propertiesCollected(properties)
    372         {
    373             for (var i = 0; properties && i < properties.length; ++i)
    374                 result[properties[i].name] = true;
    375             if (--pendingRequests == 0)
    376                 callback(result);
    377         }
    378 
    379         for (var i = 0; i < selectedCallFrame.scopeChain.length; ++i) {
    380             var scope = selectedCallFrame.scopeChain[i];
    381             var object = WebInspector.RemoteObject.fromPayload(scope.object);
    382             pendingRequests++;
    383             object.getAllProperties(propertiesCollected);
    384         }
    385     },
    386 
    387     _debuggerPaused: function(event)
    388     {
    389         var callFrames = event.data.callFrames;
    390         var details = event.data.details;
    391 
    392         this._paused = true;
    393         this._waitingToPause = false;
    394         this._stepping = false;
    395 
    396         this._updateDebuggerButtons();
    397 
    398         WebInspector.currentPanel = this;
    399 
    400         this.sidebarPanes.callstack.update(callFrames, details);
    401         this.sidebarPanes.callstack.selectedCallFrame = this._presentationModel.selectedCallFrame;
    402 
    403         if (details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) {
    404             if (details.eventData.breakpointType === WebInspector.ScriptsPanel.BrowserBreakpointTypes.DOM) {
    405                 this.sidebarPanes.domBreakpoints.highlightBreakpoint(details.eventData);
    406                 function didCreateBreakpointHitStatusMessage(element)
    407                 {
    408                     this.sidebarPanes.callstack.setStatus(element);
    409                 }
    410                 this.sidebarPanes.domBreakpoints.createBreakpointHitStatusMessage(details.eventData, didCreateBreakpointHitStatusMessage.bind(this));
    411             } else if (details.eventData.breakpointType === WebInspector.ScriptsPanel.BrowserBreakpointTypes.EventListener) {
    412                 var eventName = details.eventData.eventName;
    413                 this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.eventData.eventName);
    414                 var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);
    415                 this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
    416             } else if (details.eventData.breakpointType === WebInspector.ScriptsPanel.BrowserBreakpointTypes.XHR) {
    417                 this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.eventData.breakpointURL);
    418                 this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
    419             }
    420         } else {
    421             function didGetSourceLocation(sourceFileId, lineNumber)
    422             {
    423                 if (!sourceFileId || !this._presentationModel.findBreakpoint(sourceFileId, lineNumber))
    424                     return;
    425                 this.sidebarPanes.jsBreakpoints.highlightBreakpoint(sourceFileId, lineNumber);
    426                 this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
    427             }
    428             callFrames[0].sourceLine(didGetSourceLocation.bind(this));
    429         }
    430 
    431         window.focus();
    432         InspectorFrontendHost.bringToFront();
    433     },
    434 
    435     _debuggerResumed: function()
    436     {
    437         this._paused = false;
    438         this._waitingToPause = false;
    439         this._stepping = false;
    440 
    441         this._clearInterface();
    442     },
    443 
    444     _debuggerWasEnabled: function()
    445     {
    446         this._setPauseOnExceptions(WebInspector.settings.pauseOnExceptionStateString);
    447 
    448         if (this._debuggerEnabled)
    449             return;
    450 
    451         InspectorFrontendHost.saveSessionSetting("debugger-enabled", "true");
    452         this._debuggerEnabled = true;
    453         this.reset(true);
    454     },
    455 
    456     _debuggerWasDisabled: function()
    457     {
    458         if (!this._debuggerEnabled)
    459             return;
    460 
    461         InspectorFrontendHost.saveSessionSetting("debugger-enabled", "false");
    462         this._debuggerEnabled = false;
    463         this.reset(true);
    464     },
    465 
    466     reset: function(preserveItems)
    467     {
    468         this.visibleView = null;
    469 
    470         delete this.currentQuery;
    471         this.searchCanceled();
    472 
    473         this._debuggerResumed();
    474 
    475         this._backForwardList = [];
    476         this._currentBackForwardIndex = -1;
    477         this._updateBackAndForwardButtons();
    478 
    479         this._sourceFileIdToSourceFrame = {};
    480         this._sourceFileIdToFilesSelectOption = {};
    481         this._filesSelectElement.removeChildren();
    482         this.functionsSelectElement.removeChildren();
    483         this.viewsContainerElement.removeChildren();
    484 
    485         this.sidebarPanes.jsBreakpoints.reset();
    486         this.sidebarPanes.watchExpressions.refreshExpressions();
    487         if (!preserveItems)
    488             this.sidebarPanes.workers.reset();
    489     },
    490 
    491     get visibleView()
    492     {
    493         return this._visibleView;
    494     },
    495 
    496     set visibleView(x)
    497     {
    498         if (this._visibleView === x)
    499             return;
    500 
    501         if (this._visibleView)
    502             this._visibleView.hide();
    503 
    504         this._visibleView = x;
    505 
    506         if (x)
    507             x.show(this.viewsContainerElement);
    508     },
    509 
    510     canShowAnchorLocation: function(anchor)
    511     {
    512         return this._debuggerEnabled && this._presentationModel.sourceFileForScriptURL(anchor.href);
    513     },
    514 
    515     showAnchorLocation: function(anchor)
    516     {
    517         function didRequestSourceMapping(mapping)
    518         {
    519             var lineNumber = mapping.scriptLocationToSourceLine({lineNumber:anchor.getAttribute("line_number") - 1, columnNumber:0});
    520             this._showSourceLine(sourceFile.id, lineNumber);
    521         }
    522         var sourceFile = this._presentationModel.sourceFileForScriptURL(anchor.href);
    523         sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
    524     },
    525 
    526     _showSourceLine: function(sourceFileId, lineNumber)
    527     {
    528         var sourceFrame = this._showSourceFrameAndAddToHistory(sourceFileId);
    529         sourceFrame.highlightLine(lineNumber);
    530     },
    531 
    532     handleShortcut: function(event)
    533     {
    534         var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
    535         var handler = this._shortcuts[shortcut];
    536         if (handler) {
    537             handler(event);
    538             event.handled = true;
    539         } else
    540             this.sidebarPanes.callstack.handleShortcut(event);
    541     },
    542 
    543     _showSourceFrameAndAddToHistory: function(sourceFileId)
    544     {
    545         var sourceFrame = this._showSourceFrame(sourceFileId);
    546 
    547         var oldIndex = this._currentBackForwardIndex;
    548         if (oldIndex >= 0)
    549             this._backForwardList.splice(oldIndex + 1, this._backForwardList.length - oldIndex);
    550 
    551         // Check for a previous entry of the same object in _backForwardList.
    552         // If one is found, remove it.
    553         var previousEntryIndex = this._backForwardList.indexOf(sourceFileId);
    554         if (previousEntryIndex !== -1)
    555             this._backForwardList.splice(previousEntryIndex, 1);
    556 
    557         this._backForwardList.push(sourceFileId);
    558         this._currentBackForwardIndex = this._backForwardList.length - 1;
    559 
    560         this._updateBackAndForwardButtons();
    561 
    562         return sourceFrame;
    563     },
    564 
    565     _showSourceFrame: function(sourceFileId)
    566     {
    567         var index = this._sourceFileIdToFilesSelectOption[sourceFileId].index;
    568         this._filesSelectElement.selectedIndex = index;
    569 
    570         var sourceFrame = this._sourceFrameForSourceFileId(sourceFileId);
    571         this.visibleView = sourceFrame;
    572 
    573         var sourceFile = this._presentationModel.sourceFile(sourceFileId);
    574         if (sourceFile.url)
    575             WebInspector.settings.lastViewedScriptFile = sourceFile.url;
    576 
    577         return sourceFrame;
    578     },
    579 
    580     _sourceFrameForSourceFileId: function(sourceFileId)
    581     {
    582         var sourceFrame = this._sourceFileIdToSourceFrame[sourceFileId];
    583         return sourceFrame || this._createSourceFrame(sourceFileId);
    584     },
    585 
    586     _createSourceFrame: function(sourceFileId)
    587     {
    588         var sourceFile = this._presentationModel.sourceFile(sourceFileId);
    589         var delegate = new WebInspector.SourceFrameDelegateForScriptsPanel(this._presentationModel, sourceFileId);
    590         var sourceFrame = new WebInspector.SourceFrame(delegate, sourceFile.url);
    591         sourceFrame._sourceFileId = sourceFileId;
    592         sourceFrame.addEventListener(WebInspector.SourceFrame.Events.Loaded, this._sourceFrameLoaded, this);
    593         this._sourceFileIdToSourceFrame[sourceFileId] = sourceFrame;
    594         return sourceFrame;
    595     },
    596 
    597     _sourceFileChanged: function(event)
    598     {
    599         var sourceFileId = event.data.id;
    600 
    601         var oldSourceFrame = this._sourceFileIdToSourceFrame[sourceFileId];
    602         if (!oldSourceFrame)
    603             return;
    604         oldSourceFrame.removeEventListener(WebInspector.SourceFrame.Events.Loaded, this._sourceFrameLoaded, this);
    605         delete this._sourceFileIdToSourceFrame[sourceFileId];
    606         if (this.visibleView !== oldSourceFrame)
    607             return;
    608 
    609         var newSourceFrame = this._createSourceFrame(sourceFileId)
    610         newSourceFrame.scrollTop = oldSourceFrame.scrollTop;
    611         this.visibleView = newSourceFrame;
    612     },
    613 
    614     _sourceFrameLoaded: function(event)
    615     {
    616         var sourceFrame = event.target;
    617         var sourceFileId = sourceFrame._sourceFileId;
    618         var sourceFile = this._presentationModel.sourceFile(sourceFileId);
    619 
    620         var messages = sourceFile.messages;
    621         for (var i = 0; i < messages.length; ++i) {
    622             var message = messages[i];
    623             sourceFrame.addMessageToSource(message.lineNumber, message.originalMessage);
    624         }
    625 
    626         var breakpoints = this._presentationModel.breakpointsForSourceFileId(sourceFileId);
    627         for (var i = 0; i < breakpoints.length; ++i) {
    628             var breakpoint = breakpoints[i];
    629             sourceFrame.addBreakpoint(breakpoint.lineNumber, breakpoint.resolved, breakpoint.condition, breakpoint.enabled);
    630         }
    631     },
    632 
    633     _clearCurrentExecutionLine: function()
    634     {
    635         if (this._executionSourceFrame)
    636             this._executionSourceFrame.clearExecutionLine();
    637         delete this._executionSourceFrame;
    638     },
    639 
    640     _callFrameSelected: function(event)
    641     {
    642         var callFrame = event.data;
    643 
    644         this._clearCurrentExecutionLine();
    645 
    646         if (!callFrame)
    647             return;
    648 
    649         this.sidebarPanes.scopechain.update(callFrame);
    650         this.sidebarPanes.watchExpressions.refreshExpressions();
    651         this.sidebarPanes.callstack.selectedCallFrame = this._presentationModel.selectedCallFrame;
    652 
    653         function didGetSourceLocation(sourceFileId, lineNumber)
    654         {
    655             if (!sourceFileId)
    656                 return;
    657 
    658             if (!(sourceFileId in this._sourceFileIdToFilesSelectOption)) {
    659                 // Anonymous scripts are not added to files select by default.
    660                 this._addOptionToFilesSelect(sourceFileId);
    661             }
    662             var sourceFrame = this._showSourceFrameAndAddToHistory(sourceFileId);
    663             sourceFrame.setExecutionLine(lineNumber);
    664             this._executionSourceFrame = sourceFrame;
    665         }
    666         callFrame.sourceLine(didGetSourceLocation.bind(this));
    667     },
    668 
    669     _filesSelectChanged: function()
    670     {
    671         var sourceFileId = this._filesSelectElement[this._filesSelectElement.selectedIndex]._sourceFileId;
    672         this._showSourceFrameAndAddToHistory(sourceFileId);
    673     },
    674 
    675     _startSidebarResizeDrag: function(event)
    676     {
    677         WebInspector.elementDragStart(this.sidebarElement, this._sidebarResizeDrag.bind(this), this._endSidebarResizeDrag.bind(this), event, "col-resize");
    678 
    679         if (event.target === this.sidebarResizeWidgetElement)
    680             this._dragOffset = (event.target.offsetWidth - (event.pageX - event.target.totalOffsetLeft));
    681         else
    682             this._dragOffset = 0;
    683     },
    684 
    685     _endSidebarResizeDrag: function(event)
    686     {
    687         WebInspector.elementDragEnd(event);
    688         delete this._dragOffset;
    689         this.saveSidebarWidth();
    690     },
    691 
    692     _sidebarResizeDrag: function(event)
    693     {
    694         var x = event.pageX + this._dragOffset;
    695         var newWidth = Number.constrain(window.innerWidth - x, Preferences.minScriptsSidebarWidth, window.innerWidth * 0.66);
    696         this.setSidebarWidth(newWidth);
    697         event.preventDefault();
    698     },
    699 
    700     setSidebarWidth: function(newWidth)
    701     {
    702         this.sidebarElement.style.width = newWidth + "px";
    703         this.sidebarButtonsElement.style.width = newWidth + "px";
    704         this.viewsContainerElement.style.right = newWidth + "px";
    705         this.sidebarResizeWidgetElement.style.right = newWidth + "px";
    706         this.sidebarResizeElement.style.right = (newWidth - 3) + "px";
    707 
    708         this.resize();
    709     },
    710 
    711     _setPauseOnExceptions: function(pauseOnExceptionsState)
    712     {
    713         pauseOnExceptionsState = pauseOnExceptionsState || WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions;
    714         function callback(error)
    715         {
    716             if (error)
    717                 return;
    718             if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions)
    719                 this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
    720             else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnAllExceptions)
    721                 this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
    722             else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions)
    723                 this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
    724 
    725             this._pauseOnExceptionButton.state = pauseOnExceptionsState;
    726             WebInspector.settings.pauseOnExceptionStateString = pauseOnExceptionsState;
    727         }
    728         DebuggerAgent.setPauseOnExceptions(pauseOnExceptionsState, callback.bind(this));
    729     },
    730 
    731     _updateDebuggerButtons: function()
    732     {
    733         if (this._debuggerEnabled) {
    734             this.enableToggleButton.title = WebInspector.UIString("Debugging enabled. Click to disable.");
    735             this.enableToggleButton.toggled = true;
    736             this._pauseOnExceptionButton.visible = true;
    737             this.panelEnablerView.visible = false;
    738         } else {
    739             this.enableToggleButton.title = WebInspector.UIString("Debugging disabled. Click to enable.");
    740             this.enableToggleButton.toggled = false;
    741             this._pauseOnExceptionButton.visible = false;
    742             this.panelEnablerView.visible = true;
    743         }
    744 
    745         if (this._paused) {
    746             this.pauseButton.addStyleClass("paused");
    747 
    748             this.pauseButton.disabled = false;
    749             this.stepOverButton.disabled = false;
    750             this.stepIntoButton.disabled = false;
    751             this.stepOutButton.disabled = false;
    752 
    753             this.debuggerStatusElement.textContent = WebInspector.UIString("Paused");
    754         } else {
    755             this.pauseButton.removeStyleClass("paused");
    756 
    757             this.pauseButton.disabled = this._waitingToPause;
    758             this.stepOverButton.disabled = true;
    759             this.stepIntoButton.disabled = true;
    760             this.stepOutButton.disabled = true;
    761 
    762             if (this._waitingToPause)
    763                 this.debuggerStatusElement.textContent = WebInspector.UIString("Pausing");
    764             else if (this._stepping)
    765                 this.debuggerStatusElement.textContent = WebInspector.UIString("Stepping");
    766             else
    767                 this.debuggerStatusElement.textContent = "";
    768         }
    769     },
    770 
    771     _updateBackAndForwardButtons: function()
    772     {
    773         this.backButton.disabled = this._currentBackForwardIndex <= 0;
    774         this.forwardButton.disabled = this._currentBackForwardIndex >= (this._backForwardList.length - 1);
    775     },
    776 
    777     _clearInterface: function()
    778     {
    779         this.sidebarPanes.callstack.update(null);
    780         this.sidebarPanes.scopechain.update(null);
    781         this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
    782         if (Preferences.nativeInstrumentationEnabled) {
    783             this.sidebarPanes.domBreakpoints.clearBreakpointHighlight();
    784             this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
    785             this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
    786         }
    787 
    788         this._clearCurrentExecutionLine();
    789         this._updateDebuggerButtons();
    790     },
    791 
    792     _goBack: function()
    793     {
    794         if (this._currentBackForwardIndex <= 0) {
    795             console.error("Can't go back from index " + this._currentBackForwardIndex);
    796             return;
    797         }
    798 
    799         this._showSourceFrame(this._backForwardList[--this._currentBackForwardIndex]);
    800         this._updateBackAndForwardButtons();
    801     },
    802 
    803     _goForward: function()
    804     {
    805         if (this._currentBackForwardIndex >= this._backForwardList.length - 1) {
    806             console.error("Can't go forward from index " + this._currentBackForwardIndex);
    807             return;
    808         }
    809 
    810         this._showSourceFrame(this._backForwardList[++this._currentBackForwardIndex]);
    811         this._updateBackAndForwardButtons();
    812     },
    813 
    814     _enableDebugging: function()
    815     {
    816         if (this._debuggerEnabled)
    817             return;
    818         this._toggleDebugging(this.panelEnablerView.alwaysEnabled);
    819     },
    820 
    821     _toggleDebugging: function(optionalAlways)
    822     {
    823         this._paused = false;
    824         this._waitingToPause = false;
    825         this._stepping = false;
    826 
    827         if (this._debuggerEnabled) {
    828             WebInspector.settings.debuggerEnabled = false;
    829             WebInspector.debuggerModel.disableDebugger();
    830         } else {
    831             WebInspector.settings.debuggerEnabled = !!optionalAlways;
    832             WebInspector.debuggerModel.enableDebugger();
    833         }
    834     },
    835 
    836     _togglePauseOnExceptions: function()
    837     {
    838         var nextStateMap = {};
    839         var stateEnum = WebInspector.ScriptsPanel.PauseOnExceptionsState;
    840         nextStateMap[stateEnum.DontPauseOnExceptions] = stateEnum.PauseOnAllExceptions;
    841         nextStateMap[stateEnum.PauseOnAllExceptions] = stateEnum.PauseOnUncaughtExceptions;
    842         nextStateMap[stateEnum.PauseOnUncaughtExceptions] = stateEnum.DontPauseOnExceptions;
    843         this._setPauseOnExceptions(nextStateMap[this._pauseOnExceptionButton.state]);
    844     },
    845 
    846     _togglePause: function()
    847     {
    848         if (this._paused) {
    849             this._paused = false;
    850             this._waitingToPause = false;
    851             DebuggerAgent.resume();
    852         } else {
    853             this._stepping = false;
    854             this._waitingToPause = true;
    855             DebuggerAgent.pause();
    856         }
    857 
    858         this._clearInterface();
    859     },
    860 
    861     _stepOverClicked: function()
    862     {
    863         this._paused = false;
    864         this._stepping = true;
    865 
    866         this._clearInterface();
    867 
    868         DebuggerAgent.stepOver();
    869     },
    870 
    871     _stepIntoClicked: function()
    872     {
    873         this._paused = false;
    874         this._stepping = true;
    875 
    876         this._clearInterface();
    877 
    878         DebuggerAgent.stepInto();
    879     },
    880 
    881     _stepOutClicked: function()
    882     {
    883         this._paused = false;
    884         this._stepping = true;
    885 
    886         this._clearInterface();
    887 
    888         DebuggerAgent.stepOut();
    889     },
    890 
    891     toggleBreakpointsClicked: function()
    892     {
    893         this.toggleBreakpointsButton.toggled = !this.toggleBreakpointsButton.toggled;
    894         if (this.toggleBreakpointsButton.toggled) {
    895             DebuggerAgent.setBreakpointsActive(true);
    896             this.toggleBreakpointsButton.title = WebInspector.UIString("Deactivate all breakpoints.");
    897             document.getElementById("main-panels").removeStyleClass("breakpoints-deactivated");
    898         } else {
    899             DebuggerAgent.setBreakpointsActive(false);
    900             this.toggleBreakpointsButton.title = WebInspector.UIString("Activate all breakpoints.");
    901             document.getElementById("main-panels").addStyleClass("breakpoints-deactivated");
    902         }
    903     },
    904 
    905     elementsToRestoreScrollPositionsFor: function()
    906     {
    907         return [ this.sidebarElement ];
    908     },
    909 
    910     _registerShortcuts: function()
    911     {
    912         var section = WebInspector.shortcutsHelp.section(WebInspector.UIString("Scripts Panel"));
    913         var handler, shortcut1, shortcut2;
    914         var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
    915 
    916         this._shortcuts = {};
    917 
    918         // Continue.
    919         handler = this.pauseButton.click.bind(this.pauseButton);
    920         shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F8);
    921         this._shortcuts[shortcut1.key] = handler;
    922         shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash, platformSpecificModifier);
    923         this._shortcuts[shortcut2.key] = handler;
    924         section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Continue"));
    925 
    926         // Step over.
    927         handler = this.stepOverButton.click.bind(this.stepOverButton);
    928         shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F10);
    929         this._shortcuts[shortcut1.key] = handler;
    930         shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.SingleQuote, platformSpecificModifier);
    931         this._shortcuts[shortcut2.key] = handler;
    932         section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step over"));
    933 
    934         // Step into.
    935         handler = this.stepIntoButton.click.bind(this.stepIntoButton);
    936         shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11);
    937         this._shortcuts[shortcut1.key] = handler;
    938         shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, platformSpecificModifier);
    939         this._shortcuts[shortcut2.key] = handler;
    940         section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step into"));
    941 
    942         // Step out.
    943         handler = this.stepOutButton.click.bind(this.stepOutButton);
    944         shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.Shift);
    945         this._shortcuts[shortcut1.key] = handler;
    946         shortcut2 = WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift, platformSpecificModifier);
    947         this._shortcuts[shortcut2.key] = handler;
    948         section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step out"));
    949 
    950         var isMac = WebInspector.isMac();
    951         if (isMac)
    952             shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Meta);
    953         else
    954             shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
    955         this._shortcuts[shortcut1.key] = this.showGoToLineDialog.bind(this);
    956         section.addAlternateKeys([ shortcut1.name ], WebInspector.UIString("Go to Line"));
    957         this.sidebarPanes.callstack.registerShortcuts(section);
    958     },
    959 
    960     searchCanceled: function()
    961     {
    962         if (this._searchView)
    963             this._searchView.searchCanceled();
    964 
    965         delete this._searchView;
    966         delete this._searchQuery;
    967     },
    968 
    969     performSearch: function(query)
    970     {
    971         WebInspector.searchController.updateSearchMatchesCount(0, this);
    972 
    973         if (!this.visibleView)
    974             return;
    975 
    976         // Call searchCanceled since it will reset everything we need before doing a new search.
    977         this.searchCanceled();
    978 
    979         this._searchView = this.visibleView;
    980         this._searchQuery = query;
    981 
    982         function finishedCallback(view, searchMatches)
    983         {
    984             if (!searchMatches)
    985                 return;
    986 
    987             WebInspector.searchController.updateSearchMatchesCount(searchMatches, this);
    988             view.jumpToFirstSearchResult();
    989         }
    990 
    991         this._searchView.performSearch(query, finishedCallback.bind(this));
    992     },
    993 
    994     jumpToNextSearchResult: function()
    995     {
    996         if (!this._searchView)
    997             return;
    998 
    999         if (this._searchView !== this.visibleView) {
   1000             this.performSearch(this._searchQuery);
   1001             return;
   1002         }
   1003 
   1004         if (this._searchView.showingLastSearchResult())
   1005             this._searchView.jumpToFirstSearchResult();
   1006         else
   1007             this._searchView.jumpToNextSearchResult();
   1008     },
   1009 
   1010     jumpToPreviousSearchResult: function()
   1011     {
   1012         if (!this._searchView)
   1013             return;
   1014 
   1015         if (this._searchView !== this.visibleView) {
   1016             this.performSearch(this._searchQuery);
   1017             if (this._searchView)
   1018                 this._searchView.jumpToLastSearchResult();
   1019             return;
   1020         }
   1021 
   1022         if (this._searchView.showingFirstSearchResult())
   1023             this._searchView.jumpToLastSearchResult();
   1024         else
   1025             this._searchView.jumpToPreviousSearchResult();
   1026     },
   1027 
   1028     showGoToLineDialog: function(e)
   1029     {
   1030          var view = this.visibleView;
   1031          if (view)
   1032              WebInspector.GoToLineDialog.show(view);
   1033     }
   1034 }
   1035 
   1036 WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype;
   1037 
   1038 
   1039 WebInspector.SourceFrameDelegateForScriptsPanel = function(model, sourceFileId)
   1040 {
   1041     WebInspector.SourceFrameDelegate.call(this);
   1042     this._model = model;
   1043     this._sourceFileId = sourceFileId;
   1044     this._popoverObjectGroup = "popover";
   1045 }
   1046 
   1047 WebInspector.SourceFrameDelegateForScriptsPanel.prototype = {
   1048     requestContent: function(callback)
   1049     {
   1050         this._model.requestSourceFileContent(this._sourceFileId, callback);
   1051     },
   1052 
   1053     debuggingSupported: function()
   1054     {
   1055         return true;
   1056     },
   1057 
   1058     setBreakpoint: function(lineNumber, condition, enabled)
   1059     {
   1060         this._model.setBreakpoint(this._sourceFileId, lineNumber, condition, enabled);
   1061 
   1062         if (!WebInspector.panels.scripts.breakpointsActivated)
   1063             WebInspector.panels.scripts.toggleBreakpointsClicked();
   1064     },
   1065 
   1066     updateBreakpoint: function(lineNumber, condition, enabled)
   1067     {
   1068         this._model.updateBreakpoint(this._sourceFileId, lineNumber, condition, enabled);
   1069     },
   1070 
   1071     removeBreakpoint: function(lineNumber)
   1072     {
   1073         this._model.removeBreakpoint(this._sourceFileId, lineNumber);
   1074     },
   1075 
   1076     findBreakpoint: function(lineNumber)
   1077     {
   1078         return this._model.findBreakpoint(this._sourceFileId, lineNumber);
   1079     },
   1080 
   1081     continueToLine: function(lineNumber)
   1082     {
   1083         this._model.continueToLine(this._sourceFileId, lineNumber);
   1084     },
   1085 
   1086     canEditScriptSource: function()
   1087     {
   1088         return this._model.canEditScriptSource(this._sourceFileId);
   1089     },
   1090 
   1091     editScriptSource: function(text, callback)
   1092     {
   1093         this._model.editScriptSource(this._sourceFileId, text, callback);
   1094     },
   1095 
   1096     setScriptSourceIsBeingEdited: function(inEditMode)
   1097     {
   1098         WebInspector.panels.scripts.setScriptSourceIsBeingEdited(this._sourceFileId, inEditMode);
   1099     },
   1100 
   1101     debuggerPaused: function()
   1102     {
   1103         return WebInspector.panels.scripts.paused;
   1104     },
   1105 
   1106     evaluateInSelectedCallFrame: function(string, callback)
   1107     {
   1108         WebInspector.panels.scripts.evaluateInSelectedCallFrame(string, this._popoverObjectGroup, false, callback);
   1109     },
   1110 
   1111     releaseEvaluationResult: function()
   1112     {
   1113         RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
   1114     },
   1115 
   1116     toggleFormatSourceFiles: function()
   1117     {
   1118         WebInspector.panels.scripts.reset();
   1119         this._model.toggleFormatSourceFiles();
   1120     },
   1121 
   1122     formatSourceFilesToggled: function()
   1123     {
   1124         return this._model.formatSourceFilesToggled();
   1125     }
   1126 }
   1127 
   1128 WebInspector.SourceFrameDelegateForScriptsPanel.prototype.__proto__ = WebInspector.SourceFrameDelegate.prototype;
   1129