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