OLD | NEW |
| (Empty) |
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); | |
29 | |
30 this.element.addStyleClass("scripts"); | |
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 reso
urce."); | |
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 resou
rce."); | |
50 this.forwardButton.disabled = true; | |
51 this.forwardButton.appendChild(document.createElement("img")); | |
52 this.forwardButton.addEventListener("click", this._goForward.bind(this), fal
se); | |
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._changeVisibleFile.b
ind(this), false); | |
59 this.filesSelectElement.handleKeyEvent = this.handleKeyEvent.bind(this); | |
60 this.topStatusBar.appendChild(this.filesSelectElement); | |
61 | |
62 this.functionsSelectElement = document.createElement("select"); | |
63 this.functionsSelectElement.className = "status-bar-item"; | |
64 this.functionsSelectElement.id = "scripts-functions"; | |
65 | |
66 // FIXME: append the functions select element to the top status bar when it
is implemented. | |
67 // this.topStatusBar.appendChild(this.functionsSelectElement); | |
68 | |
69 this.sidebarButtonsElement = document.createElement("div"); | |
70 this.sidebarButtonsElement.id = "scripts-sidebar-buttons"; | |
71 this.topStatusBar.appendChild(this.sidebarButtonsElement); | |
72 | |
73 this.pauseButton = document.createElement("button"); | |
74 this.pauseButton.className = "status-bar-item"; | |
75 this.pauseButton.id = "scripts-pause"; | |
76 this.pauseButton.title = WebInspector.UIString("Pause script execution."); | |
77 this.pauseButton.disabled = true; | |
78 this.pauseButton.appendChild(document.createElement("img")); | |
79 this.pauseButton.addEventListener("click", this._togglePause.bind(this), fal
se); | |
80 this.sidebarButtonsElement.appendChild(this.pauseButton); | |
81 | |
82 this.stepOverButton = document.createElement("button"); | |
83 this.stepOverButton.className = "status-bar-item"; | |
84 this.stepOverButton.id = "scripts-step-over"; | |
85 this.stepOverButton.title = WebInspector.UIString("Step over next function c
all."); | |
86 this.stepOverButton.disabled = true; | |
87 this.stepOverButton.addEventListener("click", this._stepOverClicked.bind(thi
s), false); | |
88 this.stepOverButton.appendChild(document.createElement("img")); | |
89 this.sidebarButtonsElement.appendChild(this.stepOverButton); | |
90 | |
91 this.stepIntoButton = document.createElement("button"); | |
92 this.stepIntoButton.className = "status-bar-item"; | |
93 this.stepIntoButton.id = "scripts-step-into"; | |
94 this.stepIntoButton.title = WebInspector.UIString("Step into next function c
all."); | |
95 this.stepIntoButton.disabled = true; | |
96 this.stepIntoButton.addEventListener("click", this._stepIntoClicked.bind(thi
s), false); | |
97 this.stepIntoButton.appendChild(document.createElement("img")); | |
98 this.sidebarButtonsElement.appendChild(this.stepIntoButton); | |
99 | |
100 this.stepOutButton = document.createElement("button"); | |
101 this.stepOutButton.className = "status-bar-item"; | |
102 this.stepOutButton.id = "scripts-step-out"; | |
103 this.stepOutButton.title = WebInspector.UIString("Step out of current functi
on."); | |
104 this.stepOutButton.disabled = true; | |
105 this.stepOutButton.addEventListener("click", this._stepOutClicked.bind(this)
, false); | |
106 this.stepOutButton.appendChild(document.createElement("img")); | |
107 this.sidebarButtonsElement.appendChild(this.stepOutButton); | |
108 | |
109 this.debuggerStatusElement = document.createElement("div"); | |
110 this.debuggerStatusElement.id = "scripts-debugger-status"; | |
111 this.sidebarButtonsElement.appendChild(this.debuggerStatusElement); | |
112 | |
113 this.viewsContainerElement = document.createElement("div"); | |
114 this.viewsContainerElement.id = "script-resource-views"; | |
115 | |
116 this.sidebarElement = document.createElement("div"); | |
117 this.sidebarElement.id = "scripts-sidebar"; | |
118 | |
119 this.sidebarResizeElement = document.createElement("div"); | |
120 this.sidebarResizeElement.className = "sidebar-resizer-vertical"; | |
121 this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarRe
sizeDrag.bind(this), false); | |
122 | |
123 this.sidebarResizeWidgetElement = document.createElement("div"); | |
124 this.sidebarResizeWidgetElement.id = "scripts-sidebar-resizer-widget"; | |
125 this.sidebarResizeWidgetElement.addEventListener("mousedown", this._startSid
ebarResizeDrag.bind(this), false); | |
126 this.topStatusBar.appendChild(this.sidebarResizeWidgetElement); | |
127 | |
128 this.sidebarPanes = {}; | |
129 this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSideba
rPane(); | |
130 this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(); | |
131 this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane(); | |
132 this.sidebarPanes.breakpoints = new WebInspector.BreakpointsSidebarPane(); | |
133 | |
134 for (var pane in this.sidebarPanes) | |
135 this.sidebarElement.appendChild(this.sidebarPanes[pane].element); | |
136 | |
137 this.sidebarPanes.callstack.expanded = true; | |
138 this.sidebarPanes.callstack.addEventListener("call frame selected", this._ca
llFrameSelected, this); | |
139 | |
140 this.sidebarPanes.scopechain.expanded = true; | |
141 this.sidebarPanes.breakpoints.expanded = true; | |
142 | |
143 var panelEnablerHeading = WebInspector.UIString("You need to enable debuggin
g before you can use the Scripts panel."); | |
144 var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will
make scripts run slower."); | |
145 var panelEnablerButton = WebInspector.UIString("Enable Debugging"); | |
146 | |
147 this.panelEnablerView = new WebInspector.PanelEnablerView("scripts", panelEn
ablerHeading, panelEnablerDisclaimer, panelEnablerButton); | |
148 this.panelEnablerView.addEventListener("enable clicked", this._enableDebuggi
ng, this); | |
149 | |
150 this.element.appendChild(this.panelEnablerView.element); | |
151 this.element.appendChild(this.viewsContainerElement); | |
152 this.element.appendChild(this.sidebarElement); | |
153 this.element.appendChild(this.sidebarResizeElement); | |
154 | |
155 this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggl
e-status-bar-item"); | |
156 this.enableToggleButton.addEventListener("click", this._toggleDebugging.bind
(this), false); | |
157 | |
158 this.pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-
pause-on-exceptions-status-bar-item"); | |
159 this.pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExc
eptions.bind(this), false); | |
160 | |
161 this._breakpointsURLMap = {}; | |
162 | |
163 this._shortcuts = {}; | |
164 | |
165 var isMac = InspectorController.platform().indexOf("mac-") === 0; | |
166 var platformSpecificModifier = isMac ? WebInspector.KeyboardShortcut.Modifie
rs.Meta : WebInspector.KeyboardShortcut.Modifiers.Ctrl; | |
167 | |
168 // Continue. | |
169 var handler = this.pauseButton.click.bind(this.pauseButton); | |
170 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.F8); | |
171 this._shortcuts[shortcut] = handler; | |
172 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.Slash, platformSpecificModifier); | |
173 this._shortcuts[shortcut] = handler; | |
174 | |
175 // Step over. | |
176 var handler = this.stepOverButton.click.bind(this.stepOverButton); | |
177 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.F10); | |
178 this._shortcuts[shortcut] = handler; | |
179 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.SingleQuote, platformSpecificModifier); | |
180 this._shortcuts[shortcut] = handler; | |
181 | |
182 // Step into. | |
183 var handler = this.stepIntoButton.click.bind(this.stepIntoButton); | |
184 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.F11); | |
185 this._shortcuts[shortcut] = handler; | |
186 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.Semicolon, platformSpecificModifier); | |
187 this._shortcuts[shortcut] = handler; | |
188 | |
189 // Step out. | |
190 var handler = this.stepOutButton.click.bind(this.stepOutButton); | |
191 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.F11, WebInspector.KeyboardShortcut.Modifiers.Shift); | |
192 this._shortcuts[shortcut] = handler; | |
193 var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardSh
ortcut.KeyCodes.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift, platfo
rmSpecificModifier); | |
194 this._shortcuts[shortcut] = handler; | |
195 | |
196 this.reset(); | |
197 } | |
198 | |
199 WebInspector.ScriptsPanel.prototype = { | |
200 toolbarItemClass: "scripts", | |
201 | |
202 get toolbarItemLabel() | |
203 { | |
204 return WebInspector.UIString("Scripts"); | |
205 }, | |
206 | |
207 get statusBarItems() | |
208 { | |
209 return [this.enableToggleButton.element, this.pauseOnExceptionButton.ele
ment]; | |
210 }, | |
211 | |
212 get paused() | |
213 { | |
214 return this._paused; | |
215 }, | |
216 | |
217 show: function() | |
218 { | |
219 WebInspector.Panel.prototype.show.call(this); | |
220 this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth
- 3) + "px"; | |
221 | |
222 if (this.visibleView) { | |
223 if (this.visibleView instanceof WebInspector.ResourceView) | |
224 this.visibleView.headersVisible = false; | |
225 this.visibleView.show(this.viewsContainerElement); | |
226 } | |
227 | |
228 // Hide any views that are visible that are not this panel's current vis
ible view. | |
229 // This can happen when a ResourceView is visible in the Resources panel
then switched | |
230 // to the this panel. | |
231 for (var sourceID in this._sourceIDMap) { | |
232 var scriptOrResource = this._sourceIDMap[sourceID]; | |
233 var view = this._sourceViewForScriptOrResource(scriptOrResource); | |
234 if (!view || view === this.visibleView) | |
235 continue; | |
236 view.visible = false; | |
237 } | |
238 if (this._attachDebuggerWhenShown) { | |
239 InspectorController.enableDebugger(false); | |
240 delete this._attachDebuggerWhenShown; | |
241 } | |
242 }, | |
243 | |
244 get searchableViews() | |
245 { | |
246 var views = []; | |
247 | |
248 const visibleView = this.visibleView; | |
249 if (visibleView && visibleView.performSearch) { | |
250 visibleView.alreadySearching = true; | |
251 views.push(visibleView); | |
252 } | |
253 | |
254 for (var sourceID in this._sourceIDMap) { | |
255 var scriptOrResource = this._sourceIDMap[sourceID]; | |
256 var view = this._sourceViewForScriptOrResource(scriptOrResource); | |
257 if (!view || !view.performSearch || view.alreadySearching) | |
258 continue; | |
259 | |
260 view.alreadySearching = true; | |
261 views.push(view); | |
262 } | |
263 | |
264 for (var i = 0; i < views.length; ++i) | |
265 delete views[i].alreadySearching; | |
266 | |
267 return views; | |
268 }, | |
269 | |
270 addScript: function(sourceID, sourceURL, source, startingLine, errorLine, er
rorMessage) | |
271 { | |
272 var script = new WebInspector.Script(sourceID, sourceURL, source, starti
ngLine, errorLine, errorMessage); | |
273 | |
274 if (sourceURL in WebInspector.resourceURLMap) { | |
275 var resource = WebInspector.resourceURLMap[sourceURL]; | |
276 resource.addScript(script); | |
277 } | |
278 | |
279 if (sourceURL in this._breakpointsURLMap && sourceID) { | |
280 var breakpoints = this._breakpointsURLMap[sourceURL]; | |
281 var breakpointsLength = breakpoints.length; | |
282 for (var i = 0; i < breakpointsLength; ++i) { | |
283 var breakpoint = breakpoints[i]; | |
284 if (startingLine <= breakpoint.line) { | |
285 breakpoint.sourceID = sourceID; | |
286 if (breakpoint.enabled) | |
287 InspectorController.addBreakpoint(breakpoint.sourceID, b
reakpoint.line, breakpoint.condition); | |
288 } | |
289 } | |
290 } | |
291 | |
292 if (sourceID) | |
293 this._sourceIDMap[sourceID] = (resource || script); | |
294 | |
295 this._addScriptToFilesMenu(script); | |
296 }, | |
297 | |
298 scriptOrResourceForID: function(id) | |
299 { | |
300 return this._sourceIDMap[id]; | |
301 }, | |
302 | |
303 addBreakpoint: function(breakpoint) | |
304 { | |
305 this.sidebarPanes.breakpoints.addBreakpoint(breakpoint); | |
306 | |
307 var sourceFrame; | |
308 if (breakpoint.url) { | |
309 if (!(breakpoint.url in this._breakpointsURLMap)) | |
310 this._breakpointsURLMap[breakpoint.url] = []; | |
311 this._breakpointsURLMap[breakpoint.url].unshift(breakpoint); | |
312 | |
313 if (breakpoint.url in WebInspector.resourceURLMap) { | |
314 var resource = WebInspector.resourceURLMap[breakpoint.url]; | |
315 sourceFrame = this._sourceFrameForScriptOrResource(resource); | |
316 } | |
317 } | |
318 | |
319 if (breakpoint.sourceID && !sourceFrame) { | |
320 var object = this._sourceIDMap[breakpoint.sourceID] | |
321 sourceFrame = this._sourceFrameForScriptOrResource(object); | |
322 } | |
323 | |
324 if (sourceFrame) | |
325 sourceFrame.addBreakpoint(breakpoint); | |
326 }, | |
327 | |
328 removeBreakpoint: function(breakpoint) | |
329 { | |
330 this.sidebarPanes.breakpoints.removeBreakpoint(breakpoint); | |
331 | |
332 var sourceFrame; | |
333 if (breakpoint.url && breakpoint.url in this._breakpointsURLMap) { | |
334 var breakpoints = this._breakpointsURLMap[breakpoint.url]; | |
335 breakpoints.remove(breakpoint); | |
336 if (!breakpoints.length) | |
337 delete this._breakpointsURLMap[breakpoint.url]; | |
338 | |
339 if (breakpoint.url in WebInspector.resourceURLMap) { | |
340 var resource = WebInspector.resourceURLMap[breakpoint.url]; | |
341 sourceFrame = this._sourceFrameForScriptOrResource(resource); | |
342 } | |
343 } | |
344 | |
345 if (breakpoint.sourceID && !sourceFrame) { | |
346 var object = this._sourceIDMap[breakpoint.sourceID] | |
347 sourceFrame = this._sourceFrameForScriptOrResource(object); | |
348 } | |
349 | |
350 if (sourceFrame) | |
351 sourceFrame.removeBreakpoint(breakpoint); | |
352 }, | |
353 | |
354 selectedCallFrameId: function() | |
355 { | |
356 var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame; | |
357 if (!selectedCallFrame) | |
358 return null; | |
359 return selectedCallFrame.id; | |
360 }, | |
361 | |
362 evaluateInSelectedCallFrame: function(code, updateInterface, objectGroup, ca
llback) | |
363 { | |
364 var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame; | |
365 if (!this._paused || !selectedCallFrame) | |
366 return; | |
367 | |
368 if (typeof updateInterface === "undefined") | |
369 updateInterface = true; | |
370 | |
371 var self = this; | |
372 function updatingCallbackWrapper(result, exception) | |
373 { | |
374 callback(result, exception); | |
375 if (updateInterface) | |
376 self.sidebarPanes.scopechain.update(selectedCallFrame); | |
377 } | |
378 this.doEvalInCallFrame(selectedCallFrame, code, objectGroup, updatingCal
lbackWrapper); | |
379 }, | |
380 | |
381 doEvalInCallFrame: function(callFrame, code, objectGroup, callback) | |
382 { | |
383 function evalCallback(result) | |
384 { | |
385 if (result) | |
386 callback(result.value, result.isException); | |
387 } | |
388 InjectedScriptAccess.evaluateInCallFrame(callFrame.id, code, objectGroup
, evalCallback); | |
389 }, | |
390 | |
391 debuggerPaused: function(callFrames) | |
392 { | |
393 this._paused = true; | |
394 this._waitingToPause = false; | |
395 this._stepping = false; | |
396 | |
397 this._updateDebuggerButtons(); | |
398 | |
399 this.sidebarPanes.callstack.update(callFrames, this._sourceIDMap); | |
400 this.sidebarPanes.callstack.selectedCallFrame = callFrames[0]; | |
401 | |
402 WebInspector.currentPanel = this; | |
403 window.focus(); | |
404 }, | |
405 | |
406 debuggerResumed: function() | |
407 { | |
408 this._paused = false; | |
409 this._waitingToPause = false; | |
410 this._stepping = false; | |
411 | |
412 this._clearInterface(); | |
413 }, | |
414 | |
415 attachDebuggerWhenShown: function() | |
416 { | |
417 if (this.element.parentElement) { | |
418 InspectorController.enableDebugger(false); | |
419 } else { | |
420 this._attachDebuggerWhenShown = true; | |
421 } | |
422 }, | |
423 | |
424 debuggerWasEnabled: function() | |
425 { | |
426 this.reset(); | |
427 }, | |
428 | |
429 debuggerWasDisabled: function() | |
430 { | |
431 this.reset(); | |
432 }, | |
433 | |
434 reset: function() | |
435 { | |
436 this.visibleView = null; | |
437 | |
438 delete this.currentQuery; | |
439 this.searchCanceled(); | |
440 | |
441 if (!InspectorController.debuggerEnabled()) { | |
442 this._paused = false; | |
443 this._waitingToPause = false; | |
444 this._stepping = false; | |
445 } | |
446 | |
447 this._clearInterface(); | |
448 | |
449 this._backForwardList = []; | |
450 this._currentBackForwardIndex = -1; | |
451 this._updateBackAndForwardButtons(); | |
452 | |
453 this._scriptsForURLsInFilesSelect = {}; | |
454 this.filesSelectElement.removeChildren(); | |
455 this.functionsSelectElement.removeChildren(); | |
456 this.viewsContainerElement.removeChildren(); | |
457 | |
458 if (this._sourceIDMap) { | |
459 for (var sourceID in this._sourceIDMap) { | |
460 var object = this._sourceIDMap[sourceID]; | |
461 if (object instanceof WebInspector.Resource) | |
462 object.removeAllScripts(); | |
463 } | |
464 } | |
465 | |
466 this._sourceIDMap = {}; | |
467 | |
468 this.sidebarPanes.watchExpressions.refreshExpressions(); | |
469 }, | |
470 | |
471 get visibleView() | |
472 { | |
473 return this._visibleView; | |
474 }, | |
475 | |
476 set visibleView(x) | |
477 { | |
478 if (this._visibleView === x) | |
479 return; | |
480 | |
481 if (this._visibleView) | |
482 this._visibleView.hide(); | |
483 | |
484 this._visibleView = x; | |
485 | |
486 if (x) | |
487 x.show(this.viewsContainerElement); | |
488 }, | |
489 | |
490 canShowResource: function(resource) | |
491 { | |
492 return resource && resource.scripts.length && InspectorController.debugg
erEnabled(); | |
493 }, | |
494 | |
495 showScript: function(script, line) | |
496 { | |
497 this._showScriptOrResource(script, line, true); | |
498 }, | |
499 | |
500 showResource: function(resource, line) | |
501 { | |
502 this._showScriptOrResource(resource, line, true); | |
503 }, | |
504 | |
505 showView: function(view) | |
506 { | |
507 if (!view) | |
508 return; | |
509 this._showScriptOrResource((view.resource || view.script)); | |
510 }, | |
511 | |
512 handleKeyEvent: function(event) | |
513 { | |
514 var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); | |
515 var handler = this._shortcuts[shortcut]; | |
516 if (handler) { | |
517 handler(event); | |
518 event.preventDefault(); | |
519 event.handled = true; | |
520 } else { | |
521 this.sidebarPanes.callstack.handleKeyEvent(event); | |
522 } | |
523 }, | |
524 | |
525 scriptViewForScript: function(script) | |
526 { | |
527 if (!script) | |
528 return null; | |
529 if (!script._scriptView) | |
530 script._scriptView = new WebInspector.ScriptView(script); | |
531 return script._scriptView; | |
532 }, | |
533 | |
534 sourceFrameForScript: function(script) | |
535 { | |
536 var view = this.scriptViewForScript(script); | |
537 if (!view) | |
538 return null; | |
539 | |
540 // Setting up the source frame requires that we be attached. | |
541 if (!this.element.parentNode) | |
542 this.attach(); | |
543 | |
544 view.setupSourceFrameIfNeeded(); | |
545 return view.sourceFrame; | |
546 }, | |
547 | |
548 _sourceViewForScriptOrResource: function(scriptOrResource) | |
549 { | |
550 if (scriptOrResource instanceof WebInspector.Resource) { | |
551 if (!WebInspector.panels.resources) | |
552 return null; | |
553 return WebInspector.panels.resources.resourceViewForResource(scriptO
rResource); | |
554 } | |
555 if (scriptOrResource instanceof WebInspector.Script) | |
556 return this.scriptViewForScript(scriptOrResource); | |
557 }, | |
558 | |
559 _sourceFrameForScriptOrResource: function(scriptOrResource) | |
560 { | |
561 if (scriptOrResource instanceof WebInspector.Resource) { | |
562 if (!WebInspector.panels.resources) | |
563 return null; | |
564 return WebInspector.panels.resources.sourceFrameForResource(scriptOr
Resource); | |
565 } | |
566 if (scriptOrResource instanceof WebInspector.Script) | |
567 return this.sourceFrameForScript(scriptOrResource); | |
568 }, | |
569 | |
570 _showScriptOrResource: function(scriptOrResource, line, shouldHighlightLine,
fromBackForwardAction) | |
571 { | |
572 if (!scriptOrResource) | |
573 return; | |
574 | |
575 var view; | |
576 if (scriptOrResource instanceof WebInspector.Resource) { | |
577 if (!WebInspector.panels.resources) | |
578 return null; | |
579 view = WebInspector.panels.resources.resourceViewForResource(scriptO
rResource); | |
580 view.headersVisible = false; | |
581 | |
582 if (scriptOrResource.url in this._breakpointsURLMap) { | |
583 var sourceFrame = this._sourceFrameForScriptOrResource(scriptOrR
esource); | |
584 if (sourceFrame && !sourceFrame.breakpoints.length) { | |
585 var breakpoints = this._breakpointsURLMap[scriptOrResource.u
rl]; | |
586 var breakpointsLength = breakpoints.length; | |
587 for (var i = 0; i < breakpointsLength; ++i) | |
588 sourceFrame.addBreakpoint(breakpoints[i]); | |
589 } | |
590 } | |
591 } else if (scriptOrResource instanceof WebInspector.Script) | |
592 view = this.scriptViewForScript(scriptOrResource); | |
593 | |
594 if (!view) | |
595 return; | |
596 | |
597 if (!fromBackForwardAction) { | |
598 var oldIndex = this._currentBackForwardIndex; | |
599 if (oldIndex >= 0) | |
600 this._backForwardList.splice(oldIndex + 1, this._backForwardList
.length - oldIndex); | |
601 | |
602 // Check for a previous entry of the same object in _backForwardList
. | |
603 // If one is found, remove it and update _currentBackForwardIndex to
match. | |
604 var previousEntryIndex = this._backForwardList.indexOf(scriptOrResou
rce); | |
605 if (previousEntryIndex !== -1) { | |
606 this._backForwardList.splice(previousEntryIndex, 1); | |
607 --this._currentBackForwardIndex; | |
608 } | |
609 | |
610 this._backForwardList.push(scriptOrResource); | |
611 ++this._currentBackForwardIndex; | |
612 | |
613 this._updateBackAndForwardButtons(); | |
614 } | |
615 | |
616 this.visibleView = view; | |
617 | |
618 if (line) { | |
619 if (view.revealLine) | |
620 view.revealLine(line); | |
621 if (view.highlightLine && shouldHighlightLine) | |
622 view.highlightLine(line); | |
623 } | |
624 | |
625 var option; | |
626 if (scriptOrResource instanceof WebInspector.Script) { | |
627 option = scriptOrResource.filesSelectOption; | |
628 console.assert(option); | |
629 } else { | |
630 var url = scriptOrResource.url; | |
631 var script = this._scriptsForURLsInFilesSelect[url]; | |
632 if (script) | |
633 option = script.filesSelectOption; | |
634 } | |
635 | |
636 if (option) | |
637 this.filesSelectElement.selectedIndex = option.index; | |
638 }, | |
639 | |
640 _addScriptToFilesMenu: function(script) | |
641 { | |
642 if (script.resource && this._scriptsForURLsInFilesSelect[script.sourceUR
L]) | |
643 return; | |
644 | |
645 this._scriptsForURLsInFilesSelect[script.sourceURL] = script; | |
646 | |
647 var select = this.filesSelectElement; | |
648 | |
649 var option = document.createElement("option"); | |
650 option.representedObject = (script.resource || script); | |
651 option.text = (script.sourceURL ? WebInspector.displayNameForURL(script.
sourceURL) : WebInspector.UIString("(program)")); | |
652 | |
653 function optionCompare(a, b) | |
654 { | |
655 var aTitle = a.text.toLowerCase(); | |
656 var bTitle = b.text.toLowerCase(); | |
657 if (aTitle < bTitle) | |
658 return -1; | |
659 else if (aTitle > bTitle) | |
660 return 1; | |
661 | |
662 var aSourceID = a.representedObject.sourceID; | |
663 var bSourceID = b.representedObject.sourceID; | |
664 if (aSourceID < bSourceID) | |
665 return -1; | |
666 else if (aSourceID > bSourceID) | |
667 return 1; | |
668 return 0; | |
669 } | |
670 | |
671 var insertionIndex = insertionIndexForObjectInListSortedByFunction(optio
n, select.childNodes, optionCompare); | |
672 if (insertionIndex < 0) | |
673 select.appendChild(option); | |
674 else | |
675 select.insertBefore(option, select.childNodes.item(insertionIndex)); | |
676 | |
677 script.filesSelectOption = option; | |
678 | |
679 // Call _showScriptOrResource if the option we just appended ended up be
ing selected. | |
680 // This will happen for the first item added to the menu. | |
681 if (select.options[select.selectedIndex] === option) | |
682 this._showScriptOrResource(option.representedObject); | |
683 }, | |
684 | |
685 _clearCurrentExecutionLine: function() | |
686 { | |
687 if (this._executionSourceFrame) | |
688 this._executionSourceFrame.executionLine = 0; | |
689 delete this._executionSourceFrame; | |
690 }, | |
691 | |
692 _callFrameSelected: function() | |
693 { | |
694 this._clearCurrentExecutionLine(); | |
695 | |
696 var callStackPane = this.sidebarPanes.callstack; | |
697 var currentFrame = callStackPane.selectedCallFrame; | |
698 if (!currentFrame) | |
699 return; | |
700 | |
701 this.sidebarPanes.scopechain.update(currentFrame); | |
702 this.sidebarPanes.watchExpressions.refreshExpressions(); | |
703 | |
704 var scriptOrResource = this._sourceIDMap[currentFrame.sourceID]; | |
705 this._showScriptOrResource(scriptOrResource, currentFrame.line); | |
706 | |
707 this._executionSourceFrame = this._sourceFrameForScriptOrResource(script
OrResource); | |
708 if (this._executionSourceFrame) | |
709 this._executionSourceFrame.executionLine = currentFrame.line; | |
710 }, | |
711 | |
712 _changeVisibleFile: function(event) | |
713 { | |
714 var select = this.filesSelectElement; | |
715 this._showScriptOrResource(select.options[select.selectedIndex].represen
tedObject); | |
716 }, | |
717 | |
718 _startSidebarResizeDrag: function(event) | |
719 { | |
720 WebInspector.elementDragStart(this.sidebarElement, this._sidebarResizeDr
ag.bind(this), this._endSidebarResizeDrag.bind(this), event, "col-resize"); | |
721 | |
722 if (event.target === this.sidebarResizeWidgetElement) | |
723 this._dragOffset = (event.target.offsetWidth - (event.pageX - event.
target.totalOffsetLeft)); | |
724 else | |
725 this._dragOffset = 0; | |
726 }, | |
727 | |
728 _endSidebarResizeDrag: function(event) | |
729 { | |
730 WebInspector.elementDragEnd(event); | |
731 | |
732 delete this._dragOffset; | |
733 }, | |
734 | |
735 _sidebarResizeDrag: function(event) | |
736 { | |
737 var x = event.pageX + this._dragOffset; | |
738 var newWidth = Number.constrain(window.innerWidth - x, Preferences.minSc
riptsSidebarWidth, window.innerWidth * 0.66); | |
739 | |
740 this.sidebarElement.style.width = newWidth + "px"; | |
741 this.sidebarButtonsElement.style.width = newWidth + "px"; | |
742 this.viewsContainerElement.style.right = newWidth + "px"; | |
743 this.sidebarResizeWidgetElement.style.right = newWidth + "px"; | |
744 this.sidebarResizeElement.style.right = (newWidth - 3) + "px"; | |
745 | |
746 event.preventDefault(); | |
747 }, | |
748 | |
749 _updatePauseOnExceptionsButton: function() | |
750 { | |
751 if (InspectorController.pauseOnExceptions()) { | |
752 this.pauseOnExceptionButton.title = WebInspector.UIString("Don't pau
se on exceptions."); | |
753 this.pauseOnExceptionButton.toggled = true; | |
754 } else { | |
755 this.pauseOnExceptionButton.title = WebInspector.UIString("Pause on
exceptions."); | |
756 this.pauseOnExceptionButton.toggled = false; | |
757 } | |
758 }, | |
759 | |
760 _updateDebuggerButtons: function() | |
761 { | |
762 if (InspectorController.debuggerEnabled()) { | |
763 this.enableToggleButton.title = WebInspector.UIString("Debugging ena
bled. Click to disable."); | |
764 this.enableToggleButton.toggled = true; | |
765 this.pauseOnExceptionButton.visible = true; | |
766 this.panelEnablerView.visible = false; | |
767 } else { | |
768 this.enableToggleButton.title = WebInspector.UIString("Debugging dis
abled. Click to enable."); | |
769 this.enableToggleButton.toggled = false; | |
770 this.pauseOnExceptionButton.visible = false; | |
771 this.panelEnablerView.visible = true; | |
772 } | |
773 | |
774 this._updatePauseOnExceptionsButton(); | |
775 | |
776 if (this._paused) { | |
777 this.pauseButton.addStyleClass("paused"); | |
778 | |
779 this.pauseButton.disabled = false; | |
780 this.stepOverButton.disabled = false; | |
781 this.stepIntoButton.disabled = false; | |
782 this.stepOutButton.disabled = false; | |
783 | |
784 this.debuggerStatusElement.textContent = WebInspector.UIString("Paus
ed"); | |
785 } else { | |
786 this.pauseButton.removeStyleClass("paused"); | |
787 | |
788 this.pauseButton.disabled = this._waitingToPause; | |
789 this.stepOverButton.disabled = true; | |
790 this.stepIntoButton.disabled = true; | |
791 this.stepOutButton.disabled = true; | |
792 | |
793 if (this._waitingToPause) | |
794 this.debuggerStatusElement.textContent = WebInspector.UIString("
Pausing"); | |
795 else if (this._stepping) | |
796 this.debuggerStatusElement.textContent = WebInspector.UIString("
Stepping"); | |
797 else | |
798 this.debuggerStatusElement.textContent = ""; | |
799 } | |
800 }, | |
801 | |
802 _updateBackAndForwardButtons: function() | |
803 { | |
804 this.backButton.disabled = this._currentBackForwardIndex <= 0; | |
805 this.forwardButton.disabled = this._currentBackForwardIndex >= (this._ba
ckForwardList.length - 1); | |
806 }, | |
807 | |
808 _clearInterface: function() | |
809 { | |
810 this.sidebarPanes.callstack.update(null); | |
811 this.sidebarPanes.scopechain.update(null); | |
812 | |
813 this._clearCurrentExecutionLine(); | |
814 this._updateDebuggerButtons(); | |
815 }, | |
816 | |
817 _goBack: function() | |
818 { | |
819 if (this._currentBackForwardIndex <= 0) { | |
820 console.error("Can't go back from index " + this._currentBackForward
Index); | |
821 return; | |
822 } | |
823 | |
824 this._showScriptOrResource(this._backForwardList[--this._currentBackForw
ardIndex], null, false, true); | |
825 this._updateBackAndForwardButtons(); | |
826 }, | |
827 | |
828 _goForward: function() | |
829 { | |
830 if (this._currentBackForwardIndex >= this._backForwardList.length - 1) { | |
831 console.error("Can't go forward from index " + this._currentBackForw
ardIndex); | |
832 return; | |
833 } | |
834 | |
835 this._showScriptOrResource(this._backForwardList[++this._currentBackForw
ardIndex], null, false, true); | |
836 this._updateBackAndForwardButtons(); | |
837 }, | |
838 | |
839 _enableDebugging: function() | |
840 { | |
841 if (InspectorController.debuggerEnabled()) | |
842 return; | |
843 this._toggleDebugging(this.panelEnablerView.alwaysEnabled); | |
844 }, | |
845 | |
846 _toggleDebugging: function(optionalAlways) | |
847 { | |
848 this._paused = false; | |
849 this._waitingToPause = false; | |
850 this._stepping = false; | |
851 | |
852 if (InspectorController.debuggerEnabled()) | |
853 InspectorController.disableDebugger(true); | |
854 else | |
855 InspectorController.enableDebugger(!!optionalAlways); | |
856 }, | |
857 | |
858 _togglePauseOnExceptions: function() | |
859 { | |
860 InspectorController.setPauseOnExceptions(!InspectorController.pauseOnExc
eptions()); | |
861 this._updatePauseOnExceptionsButton(); | |
862 }, | |
863 | |
864 _togglePause: function() | |
865 { | |
866 if (this._paused) { | |
867 this._paused = false; | |
868 this._waitingToPause = false; | |
869 InspectorController.resumeDebugger(); | |
870 } else { | |
871 this._stepping = false; | |
872 this._waitingToPause = true; | |
873 InspectorController.pauseInDebugger(); | |
874 } | |
875 | |
876 this._clearInterface(); | |
877 }, | |
878 | |
879 _stepOverClicked: function() | |
880 { | |
881 this._paused = false; | |
882 this._stepping = true; | |
883 | |
884 this._clearInterface(); | |
885 | |
886 InspectorController.stepOverStatementInDebugger(); | |
887 }, | |
888 | |
889 _stepIntoClicked: function() | |
890 { | |
891 this._paused = false; | |
892 this._stepping = true; | |
893 | |
894 this._clearInterface(); | |
895 | |
896 InspectorController.stepIntoStatementInDebugger(); | |
897 }, | |
898 | |
899 _stepOutClicked: function() | |
900 { | |
901 this._paused = false; | |
902 this._stepping = true; | |
903 | |
904 this._clearInterface(); | |
905 | |
906 InspectorController.stepOutOfFunctionInDebugger(); | |
907 } | |
908 } | |
909 | |
910 WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype; | |
OLD | NEW |