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