UNPKG

occaecatidicta

Version:
1,207 lines (996 loc) 68.4 kB
/* * Copyright (C) 2008 Apple Inc. All Rights Reserved. * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @constructor * @implements {WebInspector.EditorContainerDelegate} * @extends {WebInspector.Panel} */ WebInspector.ScriptsPanel = function(presentationModel) { WebInspector.Panel.call(this, "scripts"); this.registerRequiredCSS("scriptsPanel.css"); WebInspector.settings.pauseOnExceptionStateString = WebInspector.settings.createSetting("pauseOnExceptionStateString", WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); WebInspector.settings.navigatorWasOnceHidden = WebInspector.settings.createSetting("navigatorWasOnceHidden", false); this._presentationModel = presentationModel; function viewGetter() { return this.visibleView; } WebInspector.GoToLineDialog.install(this, viewGetter.bind(this)); WebInspector.JavaScriptOutlineDialog.install(this, viewGetter.bind(this)); this.debugToolbar = this._createDebugToolbar(); const initialDebugSidebarWidth = 225; const maximalDebugSidebarWidthPercent = 50; this.createSplitView(this.element, WebInspector.SplitView.SidebarPosition.Right, initialDebugSidebarWidth); this.splitView.element.id = "scripts-split-view"; this.splitView.minimalSidebarWidth = Preferences.minScriptsSidebarWidth; this.splitView.minimalMainWidthPercent = 100 - maximalDebugSidebarWidthPercent; this.sidebarElement.appendChild(this.debugToolbar); this.debugSidebarResizeWidgetElement = document.createElement("div"); this.debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget"; this.splitView.installResizer(this.debugSidebarResizeWidgetElement); WebInspector.settings.useScriptsNavigator = WebInspector.settings.createSetting("useScriptsNavigator", true); if (WebInspector.settings.useScriptsNavigator.get()) { const initialNavigatorWidth = 225; const minimalViewsContainerWidthPercent = 50; this.editorView = new WebInspector.SplitView(WebInspector.SplitView.SidebarPosition.Left, "scriptsPanelNavigatorSidebarWidth", initialNavigatorWidth); this.editorView.element.id = "scripts-editor-view"; this.editorView.element.tabIndex = 0; this.editorView.minimalSidebarWidth = Preferences.minScriptsSidebarWidth; this.editorView.minimalMainWidthPercent = minimalViewsContainerWidthPercent; this.editorView.show(this.splitView.mainElement); this._navigator = new WebInspector.ScriptsNavigator(); this._navigatorView = this._navigator.view; this._fileSelector = this._navigator; this._fileSelector.show(this.editorView.sidebarElement); this._tabbedEditorContainer = new WebInspector.TabbedEditorContainer(this); this._editorContainer = this._tabbedEditorContainer; this._editorContainer.show(this.editorView.mainElement); WebInspector.OpenResourceDialog.install(this, this._presentationModel, this.editorView.mainElement); this._createNavigatorControls(); WebInspector.settings.navigatorHidden = WebInspector.settings.createSetting("navigatorHidden", true); if (WebInspector.settings.navigatorHidden.get()) this._toggleNavigator(); } else { this._fileSelector = new WebInspector.ScriptsPanel.ComboBoxFileSelector(); this._fileSelector.show(this.splitView.mainElement); this._editorContainer = new WebInspector.ScriptsPanel.SingleFileEditorContainer(this); this._editorContainer.show(this.splitView.mainElement); WebInspector.OpenResourceDialog.install(this, this._presentationModel, this.splitView.mainElement); } this._fileSelector.addEventListener(WebInspector.ScriptsPanel.FileSelector.Events.FileSelected, this._fileSelected, this); this._fileSelector.addEventListener(WebInspector.ScriptsPanel.FileSelector.Events.ReleasedFocusAfterSelection, this._fileSelectorReleasedFocus, this); this._editorContainer.addEventListener(WebInspector.EditorContainer.Events.EditorSelected, this._editorSelected, this); this._editorContainer.addEventListener(WebInspector.EditorContainer.Events.EditorClosed, this._editorClosed, this); this.splitView.mainElement.appendChild(this.debugSidebarResizeWidgetElement); this.sidebarPanes = {}; this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane(); this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(this._presentationModel); this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane(); this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(this._presentationModel, this._showSourceLine.bind(this)); if (Capabilities.nativeInstrumentationEnabled) { this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane; this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane(); this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane(); } if (Preferences.exposeWorkersInspection && !WebInspector.WorkerManager.isWorkerFrontend()) { WorkerAgent.setWorkerInspectionEnabled(true); this.sidebarPanes.workerList = new WebInspector.WorkerListSidebarPane(WebInspector.workerManager); } else this.sidebarPanes.workers = new WebInspector.WorkersSidebarPane(); this._debugSidebarContentsElement = document.createElement("div"); this._debugSidebarContentsElement.id = "scripts-debug-sidebar-contents"; this.sidebarElement.appendChild(this._debugSidebarContentsElement); for (var pane in this.sidebarPanes) this._debugSidebarContentsElement.appendChild(this.sidebarPanes[pane].element); this.sidebarPanes.callstack.expanded = true; this.sidebarPanes.scopechain.expanded = true; this.sidebarPanes.jsBreakpoints.expanded = true; var helpSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Scripts Panel")); this.sidebarPanes.callstack.registerShortcuts(helpSection, this.registerShortcut.bind(this)); var evaluateInConsoleShortcut = WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl); helpSection.addKey(evaluateInConsoleShortcut.name, WebInspector.UIString("Evaluate selection in console")); this.registerShortcut(evaluateInConsoleShortcut.key, this._evaluateSelectionInConsole.bind(this)); var openResourceShortcut = WebInspector.OpenResourceDialog.createShortcut(); helpSection.addKey(openResourceShortcut.name, WebInspector.UIString("Open script")); var scriptOutlineShortcut = WebInspector.JavaScriptOutlineDialog.createShortcut(); helpSection.addKey(scriptOutlineShortcut.name, WebInspector.UIString("Go to function")); var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel."); var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower."); var panelEnablerButton = WebInspector.UIString("Enable Debugging"); this.panelEnablerView = new WebInspector.PanelEnablerView("scripts", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton); this.panelEnablerView.addEventListener("enable clicked", this.enableDebugging, this); this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item"); this.enableToggleButton.addEventListener("click", this.toggleDebugging, this); if (!Capabilities.debuggerCausesRecompilation) this.enableToggleButton.element.addStyleClass("hidden"); this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3); this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this); this._toggleFormatSourceButton = new WebInspector.StatusBarButton(WebInspector.UIString("Pretty print"), "scripts-toggle-pretty-print-status-bar-item"); this._toggleFormatSourceButton.toggled = false; this._toggleFormatSourceButton.addEventListener("click", this._toggleFormatSource, this); this._scriptViewStatusBarItemsContainer = document.createElement("div"); this._scriptViewStatusBarItemsContainer.style.display = "inline-block"; this._debuggerEnabled = !Capabilities.debuggerCausesRecompilation; this._reset(false); WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this); WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerWasDisabled, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this) this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.UISourceCodeReplaced, this._uiSourceCodeReplaced, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.ConsoleMessageAdded, this._consoleMessageAdded, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.ConsoleMessagesCleared, this._consoleMessagesCleared, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerPaused, this._debuggerPaused, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerResumed, this._debuggerResumed, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, this._callFrameSelected, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.ExecutionLineChanged, this._executionLineChanged, this); this._presentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerReset, this._reset.bind(this, false)); var enableDebugger = !Capabilities.debuggerCausesRecompilation || WebInspector.settings.debuggerEnabled.get(); if (enableDebugger) WebInspector.debuggerModel.enableDebugger(); WebInspector.advancedSearchController.registerSearchScope(new WebInspector.ScriptsSearchScope()); this._sourceFramesByUISourceCode = new Map(); } // Keep these in sync with WebCore::ScriptDebugServer WebInspector.ScriptsPanel.PauseOnExceptionsState = { DontPauseOnExceptions : "none", PauseOnAllExceptions : "all", PauseOnUncaughtExceptions: "uncaught" }; WebInspector.ScriptsPanel.prototype = { get toolbarItemLabel() { return WebInspector.UIString("Scripts"); }, get statusBarItems() { return [this.enableToggleButton.element, this._pauseOnExceptionButton.element, this._toggleFormatSourceButton.element, this._scriptViewStatusBarItemsContainer]; }, get defaultFocusedElement() { return this._fileSelector.defaultFocusedElement; }, get paused() { return this._paused; }, wasShown: function() { WebInspector.Panel.prototype.wasShown.call(this); if (Capabilities.nativeInstrumentationEnabled) this._debugSidebarContentsElement.insertBefore(this.sidebarPanes.domBreakpoints.element, this.sidebarPanes.xhrBreakpoints.element); this.sidebarPanes.watchExpressions.show(); window.setTimeout(this._maybeShowNavigatorOverlay.bind(this), 0); }, breakpointsActivated: function() { return this.toggleBreakpointsButton.toggled; }, activateBreakpoints: function() { if (!this.breakpointsActivated) this._toggleBreakpointsClicked(); }, _didBuildOutlineChunk: function(event) { WebInspector.JavaScriptOutlineDialog.didAddChunk(event.data); if (event.data.total === event.data.index) { if (this._outlineWorker) { this._outlineWorker.terminate(); delete this._outlineWorker; } } }, _uiSourceCodeAdded: function(event) { var uiSourceCode = /** @type {WebInspector.UISourceCode} */ event.data; var breakpoints = uiSourceCode.breakpoints(); for (var lineNumber in breakpoints) this._uiBreakpointAdded({ data: breakpoints[lineNumber] }); this._addBreakpointListeners(uiSourceCode); if (!uiSourceCode.url || uiSourceCode.isSnippetEvaluation) { // Anonymous sources and snippets evaluations are shown only when stepping. return; } this._addUISourceCode(uiSourceCode); }, /** * @param {WebInspector.UISourceCode} uiSourceCode */ _addUISourceCode: function(uiSourceCode) { this._fileSelector.addUISourceCode(uiSourceCode); this._editorContainer.uiSourceCodeAdded(uiSourceCode); }, _uiSourceCodeRemoved: function(event) { var uiSourceCode = /** @type {WebInspector.UISourceCode} */ event.data; this._removeSourceFrame(uiSourceCode); this._removeBreakpointListeners(uiSourceCode); }, /** * @param {WebInspector.UISourceCode} uiSourceCode */ _addBreakpointListeners: function(uiSourceCode) { uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.BreakpointAdded, this._uiBreakpointAdded, this); uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.BreakpointRemoved, this._uiBreakpointRemoved, this); }, /** * @param {WebInspector.UISourceCode} uiSourceCode */ _removeBreakpointListeners: function(uiSourceCode) { uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.BreakpointAdded, this._uiBreakpointAdded, this); uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.BreakpointRemoved, this._uiBreakpointRemoved, this); }, /** * @param {WebInspector.UISourceCode} uiSourceCode * @param {boolean} isDirty */ setScriptSourceIsDirty: function(uiSourceCode, isDirty) { this._fileSelector.setScriptSourceIsDirty(uiSourceCode, isDirty); this._editorContainer.setFileIsDirty(uiSourceCode, isDirty); }, _consoleMessagesCleared: function() { var sourceFrames = this._sourceFramesByUISourceCode.values(); for (var i = 0; i < sourceFrames.length; ++i) sourceFrames[i].clearMessages(); }, _consoleMessageAdded: function(event) { var message = event.data; var sourceFrame = this._sourceFramesByUISourceCode.get(message.uiSourceCode) if (sourceFrame && sourceFrame.loaded) sourceFrame.addMessageToSource(message.lineNumber, message.originalMessage); }, _uiBreakpointAdded: function(event) { var uiBreakpoint = /** @type {WebInspector.UIBreakpoint} */ event.data; var sourceFrame = this._sourceFramesByUISourceCode.get(uiBreakpoint.uiSourceCode) if (sourceFrame && sourceFrame.loaded) sourceFrame.addBreakpoint(uiBreakpoint.lineNumber, uiBreakpoint.resolved, uiBreakpoint.condition, uiBreakpoint.enabled); this.sidebarPanes.jsBreakpoints.addBreakpoint(uiBreakpoint); }, _uiBreakpointRemoved: function(event) { var uiBreakpoint = /** @type {WebInspector.UIBreakpoint} */ event.data; var sourceFrame = this._sourceFramesByUISourceCode.get(uiBreakpoint.uiSourceCode) if (sourceFrame && sourceFrame.loaded) sourceFrame.removeBreakpoint(uiBreakpoint.lineNumber); this.sidebarPanes.jsBreakpoints.removeBreakpoint(uiBreakpoint.uiSourceCode, uiBreakpoint.lineNumber); }, _consoleCommandEvaluatedInSelectedCallFrame: function(event) { this.sidebarPanes.scopechain.update(this._presentationModel.selectedCallFrame); }, _debuggerPaused: function(event) { var callFrames = event.data.callFrames; var details = event.data.details; this._paused = true; this._waitingToPause = false; this._stepping = false; this._updateDebuggerButtons(); WebInspector.inspectorView.setCurrentPanel(this); this.sidebarPanes.callstack.update(callFrames); if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) { this.sidebarPanes.domBreakpoints.highlightBreakpoint(details.auxData); function didCreateBreakpointHitStatusMessage(element) { this.sidebarPanes.callstack.setStatus(element); } this.sidebarPanes.domBreakpoints.createBreakpointHitStatusMessage(details.auxData, didCreateBreakpointHitStatusMessage.bind(this)); } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) { var eventName = details.auxData.eventName; this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.auxData.eventName); var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName); this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI)); } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) { this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]); this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest.")); } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception) { this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData.description)); } else { function didGetUILocation(uiLocation) { if (!this._presentationModel.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber)) return; this.sidebarPanes.jsBreakpoints.highlightBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber); this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint.")); } callFrames[0].uiLocation(didGetUILocation.bind(this)); } window.focus(); InspectorFrontendHost.bringToFront(); }, _debuggerResumed: function() { this._paused = false; this._waitingToPause = false; this._stepping = false; this._clearInterface(); }, _debuggerWasEnabled: function() { this._setPauseOnExceptions(WebInspector.settings.pauseOnExceptionStateString.get()); if (this._debuggerEnabled) return; this._debuggerEnabled = true; this._reset(true); }, _debuggerWasDisabled: function() { if (!this._debuggerEnabled) return; this._debuggerEnabled = false; this._reset(true); }, _reset: function(preserveItems) { delete this.currentQuery; this.searchCanceled(); this._debuggerResumed(); delete this._currentUISourceCode; this._fileSelector.reset(); this._editorContainer.reset(); this._updateScriptViewStatusBarItems(); this.sidebarPanes.jsBreakpoints.reset(); this.sidebarPanes.watchExpressions.reset(); if (!preserveItems && this.sidebarPanes.workers) this.sidebarPanes.workers.reset(); }, get visibleView() { return this._editorContainer.visibleView; }, _updateScriptViewStatusBarItems: function() { this._scriptViewStatusBarItemsContainer.removeChildren(); var sourceFrame = this.visibleView; if (sourceFrame) { var statusBarItems = sourceFrame.statusBarItems || []; for (var i = 0; i < statusBarItems.length; ++i) this._scriptViewStatusBarItemsContainer.appendChild(statusBarItems[i]); } }, canShowAnchorLocation: function(anchor) { return this._debuggerEnabled && anchor.uiSourceCode; }, showAnchorLocation: function(anchor) { this._showSourceLine(anchor.uiSourceCode, anchor.lineNumber); }, showFunctionDefinition: function(functionLocation) { WebInspector.showPanelForAnchorNavigation(this); var uiLocation = this._presentationModel.rawLocationToUILocation(functionLocation); this._showSourceLine(uiLocation.uiSourceCode, uiLocation.lineNumber); }, showUISourceCode: function(uiSourceCode) { this._showSourceLine(uiSourceCode); }, /** * @param {WebInspector.UISourceCode} uiSourceCode * @param {number=} lineNumber */ _showSourceLine: function(uiSourceCode, lineNumber) { var sourceFrame = this._showFile(uiSourceCode); if (typeof lineNumber === "number") sourceFrame.highlightLine(lineNumber); sourceFrame.focus(); }, /** * @param {WebInspector.UISourceCode} uiSourceCode * @return {WebInspector.SourceFrame} */ _showFile: function(uiSourceCode) { if (!this._fileSelector.isScriptSourceAdded(uiSourceCode)) return null; var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode); if (this._currentUISourceCode === uiSourceCode) return sourceFrame; this._currentUISourceCode = uiSourceCode; this._fileSelector.revealUISourceCode(uiSourceCode); this._editorContainer.showFile(uiSourceCode); this._updateScriptViewStatusBarItems(); return sourceFrame; }, requestVisibleScriptOutline: function() { function contentCallback(mimeType, content) { if (this._outlineWorker) this._outlineWorker.terminate(); this._outlineWorker = new Worker("ScriptFormatterWorker.js"); this._outlineWorker.onmessage = this._didBuildOutlineChunk.bind(this); const method = "outline"; this._outlineWorker.postMessage({ method: method, params: { content: content, id: this.visibleView.uiSourceCode.id } }); } if (this.visibleView.uiSourceCode) this.visibleView.uiSourceCode.requestContent(contentCallback.bind(this)); }, /** * @param {WebInspector.UISourceCode} uiSourceCode * @return {WebInspector.SourceFrame} */ _createSourceFrame: function(uiSourceCode) { var sourceFrame = new WebInspector.JavaScriptSourceFrame(this, this._presentationModel, uiSourceCode); sourceFrame._uiSourceCode = uiSourceCode; sourceFrame.addEventListener(WebInspector.SourceFrame.Events.Loaded, this._sourceFrameLoaded, this); this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame); return sourceFrame; }, /** * @param {WebInspector.UISourceCode} uiSourceCode * @return {WebInspector.SourceFrame} */ _getOrCreateSourceFrame: function(uiSourceCode) { return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._createSourceFrame(uiSourceCode); }, /** * @param {WebInspector.UISourceCode} uiSourceCode * @return {WebInspector.SourceFrame} */ viewForFile: function(uiSourceCode) { return this._getOrCreateSourceFrame(uiSourceCode); }, /** * @param {WebInspector.UISourceCode} uiSourceCode */ _removeSourceFrame: function(uiSourceCode) { var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode); if (!sourceFrame) return; this._sourceFramesByUISourceCode.remove(uiSourceCode); sourceFrame.detach(); sourceFrame.removeEventListener(WebInspector.SourceFrame.Events.Loaded, this._sourceFrameLoaded, this); }, /** * @param {Event} event */ _uiSourceCodeReplaced: function(event) { var oldUISourceCodeList = /** @type {Array.<WebInspector.UISourceCode>} */ event.data.oldUISourceCodeList; var uiSourceCodeList = /** @type {Array.<WebInspector.UISourceCode>} */ event.data.uiSourceCodeList; this._fileSelector.replaceUISourceCodes(oldUISourceCodeList, uiSourceCodeList); this._editorContainer.replaceFiles(oldUISourceCodeList, uiSourceCodeList); for (var i = 0; i < oldUISourceCodeList.length; ++i) this._removeSourceFrame(oldUISourceCodeList[i]); for (var i = 0; i < oldUISourceCodeList.length; ++i) this._removeBreakpointListeners(oldUISourceCodeList[i]); for (var i = 0; i < uiSourceCodeList.length; ++i) { var uiSourceCode = uiSourceCodeList[i]; var breakpoints = uiSourceCode.breakpoints(); for (var lineNumber in breakpoints) this._uiBreakpointAdded({ data: breakpoints[lineNumber] }); this._addBreakpointListeners(uiSourceCode); } }, _sourceFrameLoaded: function(event) { var sourceFrame = /** @type {WebInspector.JavaScriptSourceFrame} */ event.target; var uiSourceCode = sourceFrame._uiSourceCode; var messages = this._presentationModel.messagesForUISourceCode(uiSourceCode); for (var i = 0; i < messages.length; ++i) { var message = messages[i]; sourceFrame.addMessageToSource(message.lineNumber, message.originalMessage); } var breakpoints = this._presentationModel.breakpointsForUISourceCode(uiSourceCode); for (var i = 0; i < breakpoints.length; ++i) { var breakpoint = breakpoints[i]; sourceFrame.addBreakpoint(breakpoint.lineNumber, breakpoint.resolved, breakpoint.condition, breakpoint.enabled); } }, _clearCurrentExecutionLine: function() { if (this._executionSourceFrame) this._executionSourceFrame.clearExecutionLine(); delete this._executionSourceFrame; }, _executionLineChanged: function(event) { var uiLocation = event.data; this._clearCurrentExecutionLine(); if (!uiLocation) return; var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode); sourceFrame.setExecutionLine(uiLocation.lineNumber); this._executionSourceFrame = sourceFrame; }, _revealExecutionLine: function(uiLocation) { // Some scripts (anonymous and snippets evaluations) are not added to files select by default. this._addUISourceCode(uiLocation.uiSourceCode); var sourceFrame = this._showFile(uiLocation.uiSourceCode); sourceFrame.revealLine(uiLocation.lineNumber); }, _callFrameSelected: function(event) { var callFrame = event.data; if (!callFrame) return; this.sidebarPanes.scopechain.update(callFrame); this.sidebarPanes.watchExpressions.refreshExpressions(); this.sidebarPanes.callstack.selectedCallFrame = callFrame; callFrame.uiLocation(this._revealExecutionLine.bind(this)); }, _editorClosed: function(event) { this._hideNavigatorOverlay(); var uiSourceCode = /** @type {WebInspector.UISourceCode} */ event.data; if (this._currentUISourceCode === uiSourceCode) delete this._currentUISourceCode; // We don't need to update file selector here regardless of whether useScriptsNavigator is set or not: // SingleFileEditorContainer never dispatches EditorClosed, so no need to update ComboBoxFileSelector; // ScriptsNavigator does not need to update on EditorClosed. this._updateScriptViewStatusBarItems(); }, _editorSelected: function(event) { var uiSourceCode = /** @type {WebInspector.UISourceCode} */ event.data; this._showFile(uiSourceCode); this._hideNavigatorOverlay(); }, _fileSelected: function(event) { var uiSourceCode = /** @type {WebInspector.UISourceCode} */ event.data; this._showFile(uiSourceCode); this._hideNavigatorOverlay(); }, _fileSelectorReleasedFocus: function(event) { var uiSourceCode = /** @type {WebInspector.UISourceCode} */ event.data; var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode); if (sourceFrame) sourceFrame.focus(); }, _setPauseOnExceptions: function(pauseOnExceptionsState) { pauseOnExceptionsState = pauseOnExceptionsState || WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions; function callback(error) { if (error) return; if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions) this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions."); else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnAllExceptions) this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions."); else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions) this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions."); this._pauseOnExceptionButton.state = pauseOnExceptionsState; WebInspector.settings.pauseOnExceptionStateString.set(pauseOnExceptionsState); } DebuggerAgent.setPauseOnExceptions(pauseOnExceptionsState, callback.bind(this)); }, _updateDebuggerButtons: function() { if (this._debuggerEnabled) { this.enableToggleButton.title = WebInspector.UIString("Debugging enabled. Click to disable."); this.enableToggleButton.toggled = true; this._pauseOnExceptionButton.visible = true; this.panelEnablerView.detach(); } else { this.enableToggleButton.title = WebInspector.UIString("Debugging disabled. Click to enable."); this.enableToggleButton.toggled = false; this._pauseOnExceptionButton.visible = false; this.panelEnablerView.show(this.element); } if (this._paused) { this.pauseButton.addStyleClass("paused"); this.pauseButton.disabled = false; this.stepOverButton.disabled = false; this.stepIntoButton.disabled = false; this.stepOutButton.disabled = false; this.debuggerStatusElement.textContent = WebInspector.UIString("Paused"); } else { this.pauseButton.removeStyleClass("paused"); this.pauseButton.disabled = this._waitingToPause; this.stepOverButton.disabled = true; this.stepIntoButton.disabled = true; this.stepOutButton.disabled = true; if (this._waitingToPause) this.debuggerStatusElement.textContent = WebInspector.UIString("Pausing"); else if (this._stepping) this.debuggerStatusElement.textContent = WebInspector.UIString("Stepping"); else this.debuggerStatusElement.textContent = ""; } }, _clearInterface: function() { this.sidebarPanes.callstack.update(null); this.sidebarPanes.scopechain.update(null); this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight(); if (Capabilities.nativeInstrumentationEnabled) { this.sidebarPanes.domBreakpoints.clearBreakpointHighlight(); this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight(); this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight(); } this._clearCurrentExecutionLine(); this._updateDebuggerButtons(); }, get debuggingEnabled() { return this._debuggerEnabled; }, enableDebugging: function() { if (this._debuggerEnabled) return; this.toggleDebugging(this.panelEnablerView.alwaysEnabled); }, disableDebugging: function() { if (!this._debuggerEnabled) return; this.toggleDebugging(this.panelEnablerView.alwaysEnabled); }, toggleDebugging: function(optionalAlways) { this._paused = false; this._waitingToPause = false; this._stepping = false; if (this._debuggerEnabled) { WebInspector.settings.debuggerEnabled.set(false); WebInspector.debuggerModel.disableDebugger(); } else { WebInspector.settings.debuggerEnabled.set(!!optionalAlways); WebInspector.debuggerModel.enableDebugger(); } }, _togglePauseOnExceptions: function() { var nextStateMap = {}; var stateEnum = WebInspector.ScriptsPanel.PauseOnExceptionsState; nextStateMap[stateEnum.DontPauseOnExceptions] = stateEnum.PauseOnAllExceptions; nextStateMap[stateEnum.PauseOnAllExceptions] = stateEnum.PauseOnUncaughtExceptions; nextStateMap[stateEnum.PauseOnUncaughtExceptions] = stateEnum.DontPauseOnExceptions; this._setPauseOnExceptions(nextStateMap[this._pauseOnExceptionButton.state]); }, _togglePause: function() { if (this._paused) { this._paused = false; this._waitingToPause = false; DebuggerAgent.resume(); } else { this._stepping = false; this._waitingToPause = true; DebuggerAgent.pause(); } this._clearInterface(); }, _stepOverClicked: function() { if (!this._paused) return; this._paused = false; this._stepping = true; this._clearInterface(); DebuggerAgent.stepOver(); }, _stepIntoClicked: function() { if (!this._paused) return; this._paused = false; this._stepping = true; this._clearInterface(); DebuggerAgent.stepInto(); }, _stepOutClicked: function() { if (!this._paused) return; this._paused = false; this._stepping = true; this._clearInterface(); DebuggerAgent.stepOut(); }, _toggleBreakpointsClicked: function() { this.toggleBreakpointsButton.toggled = !this.toggleBreakpointsButton.toggled; if (this.toggleBreakpointsButton.toggled) { DebuggerAgent.setBreakpointsActive(true); this.toggleBreakpointsButton.title = WebInspector.UIString("Deactivate all breakpoints."); WebInspector.inspectorView.element.removeStyleClass("breakpoints-deactivated"); } else { DebuggerAgent.setBreakpointsActive(false); this.toggleBreakpointsButton.title = WebInspector.UIString("Activate all breakpoints."); WebInspector.inspectorView.element.addStyleClass("breakpoints-deactivated"); } }, _evaluateSelectionInConsole: function() { var selection = window.getSelection(); if (selection.type === "Range" && !selection.isCollapsed) WebInspector.evaluateInConsole(selection.toString()); }, _createDebugToolbar: function() { var debugToolbar = document.createElement("div"); debugToolbar.className = "status-bar"; debugToolbar.id = "scripts-debug-toolbar"; var title, handler, shortcuts; var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta; // Continue. title = WebInspector.UIString("Pause script execution (%s)."); handler = this._togglePause.bind(this); shortcuts = []; shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F8)); shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash, platformSpecificModifier)); this.pauseButton = this._createButtonAndRegisterShortcuts("scripts-pause", title, handler, shortcuts, WebInspector.UIString("Pause/Continue")); debugToolbar.appendChild(this.pauseButton); // Step over. title = WebInspector.UIString("Step over next function call (%s)."); handler = this._stepOverClicked.bind(this); shortcuts = []; shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F10)); shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.SingleQuote, platformSpecificModifier)); this.stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, shortcuts, WebInspector.UIString("Step over")); debugToolbar.appendChild(this.stepOverButton); // Step into. title = WebInspector.UIString("Step into next function call (%s)."); handler = this._stepIntoClicked.bind(this); shortcuts = []; shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11)); shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, platformSpecificModifier)); this.stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, shortcuts, WebInspector.UIString("Step into")); debugToolbar.appendChild(this.stepIntoButton); // Step out. title = WebInspector.UIString("Step out of current function (%s)."); handler = this._stepOutClicked.bind(this); shortcuts = []; shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.Shift)); shortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift | platformSpecificModifier)); this.stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, shortcuts, WebInspector.UIString("Step out")); debugToolbar.appendChild(this.stepOutButton); this.toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate all breakpoints."), "toggle-breakpoints"); this.toggleBreakpointsButton.toggled = true; this.toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this); debugToolbar.appendChild(this.toggleBreakpointsButton.element); this.debuggerStatusElement = document.createElement("div"); this.debuggerStatusElement.id = "scripts-debugger-status"; debugToolbar.appendChild(this.debuggerStatusElement); return debugToolbar; }, _createNavigatorControls: function() { this._navigatorSidebarResizeWidgetElement = document.createElement("div"); this._navigatorSidebarResizeWidgetElement.addStyleClass("scripts-navigator-resizer-widget"); this.editorView.installResizer(this._navigatorSidebarResizeWidgetElement); this._navigatorView.element.appendChild(this._navigatorSidebarResizeWidgetElement); this._navigatorShowHideButton = this._createNavigatorControlButton(WebInspector.UIString("Show scripts navigator"), "scripts-navigator-show-hide-button", this._toggleNavigator.bind(this)); this._navigatorShowHideButton.addStyleClass("toggled-on"); this._navigatorShowHideButton.title = WebInspector.UIString("Hide scripts navigator"); this.editorView.element.appendChild(this._navigatorShowHideButton); this._navigatorPinButton = this._createNavigatorControlButton(WebInspector.UIString("Pin scripts navigator"), "scripts-navigator-pin-button", this._pinNavigator.bind(this)); this._navigatorPinButton.addStyleClass("hidden"); this._navigatorView.element.appendChild(this._navigatorPinButton); }, _createNavigatorControlButton: function(title, id, listener) { var button = document.createElement("button"); button.title = title; button.id = id; button.addStyleClass("scripts-navigator-control-button"); button.addEventListener("click", listener, false); button.createChild("div", "glyph"); return button; }, _escDownWhileNavigatorOverlayOpen: function(event) { this._hideNavigatorOverlay(); }, _maybeShowNavigatorOverlay: function() { if (this._navigator && WebInspector.settings.navigatorHidden.get() && !WebInspector.settings.navigatorWasOnceHidden.get()) this._showNavigatorOverlay(); }, _toggleNavigator: function() { if (this._navigatorOverlayShown) this._hideNavigatorOverlay(); else if (this._navigatorHidden) this._showNavigatorOverlay(); else this._hidePinnedNavigator(); }, _hidePinnedNavigator: function() { this._navigatorHidden = true; this._navigatorShowHideButton.removeStyleClass("toggled-on"); this._navigatorShowHideButton.title = WebInspector.UIString("Show scripts navigator"); this._tabbedEditorContainer.element.addStyleClass("navigator-hidden"); this._navigatorSidebarResizeWidgetElement.addStyleClass("hidden"); this._navigatorPinButton.removeStyleClass("hidden"); this.editorView.hideSidebarElement(); this._navigatorView.detach(); WebInspector.settings.navigatorHidden.set(true); }, _pinNavigator: function() { delete this._navigatorHidden; this._hideNavigatorOverlay(); this._navigatorPinButton.addStyleClass("hidden"); this._navigatorShowHideButton.addStyleClass("toggled-on"); this._navigatorShowHideButton.title = WebInspector.UIString("Hide scripts navigator"); this._tabbedEditorContainer.element.removeStyleClass("navigator-hidden"); this._navigatorSidebarResizeWidgetElement.removeStyleClass("hidden"); this.editorView.showSidebarElement(); this._navigator.show(this.editorView.sidebarElement); this._navigator.focus(); WebInspector.settings.navigatorHidden.set(false); }, _showNavigatorOverlay: function() { if (this._navigatorOverlayShown) return; this._navigatorOverlayShown = true; this._sidebarOverlay = new WebInspector.SidebarOverlay(this._navigatorView, "scriptsPanelNavigatorOverlayWidth", Preferences.minScriptsSidebarWidth); this._sidebarOverlay.addEventListener(WebInspector.SidebarOverlay.EventTypes.WasShown, this._navigatorOverlayWasShown, this); this._sidebarOverlay.addEventListener(WebInspector.SidebarOverlay.EventTypes.WillHide, this._navigatorOverlayWillHide, this); var navigatorOverlayResizeWidgetElement = document.createElement("div"); navigatorOverlayResizeWidgetElement.addStyleClass("scripts-navigator-resizer-widget"); this._sidebarOverlay.resizerWidgetElement = navigatorOverlayResizeWidgetElement; this._sidebarOverlay.show(this.editorView.element); }, _hideNavigatorOverlay: function() { if (!this._navigatorOverlayShown) return; this._sidebarOverlay.hide(); if (this.visibleView) this.visibleView.focus(); }, _navigatorOverlayWasShown: function(event) { this._navigatorView.element.appendChild(this._navigatorShowHideButton); this._navigatorShowHideButton.addStyleClass("toggled-on"); this._navigatorShowHideButton.title = WebInspector.UIString("Hide scripts navigator"); this._navigator.focus(); this.registerShortcut(WebInspector.KeyboardShortcut.Keys.Esc.code, this._escDownWhileNavigatorOverlayOpen.bind(this)); }, _navigatorOverlayWillHide: function(event) { delete this._navigatorOverlayShown; WebInspector.settings.navigatorWasOnceHidden.set(true); this.editorView.element.appendChild(this._navigatorShowHideButton); this._navigatorShowHideButton.removeStyleClass("toggled-on"); this._navigatorShowHideButton.title = WebInspector.UIString("Show scripts navigator"); this.unregisterShortcut(WebInspector.KeyboardShortcut.Keys.Esc.code); }, _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts, shortcutDescription) { var button = document.createElement("button"); button.className = "status-bar-item"; button.id = buttonId; button.title = String.vsprintf(buttonTitle, [shortcuts[0].name]); button.disabled = true; button.appendChild(document.createElement("img")); button.addEventListener("click", handler, false); var shortcutNames = []; for (var i = 0; i < shortcuts.length; ++i) { this.registerShortcut(shortcuts[i].key, handler); shortcutNames.push(shortcuts[i].name); } var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Scripts Panel")); section.addAlternateKeys(shortcutNames, shortcutDescription); return button; }, searchCanceled: function() { if (this._searchView) this._searchView.searchCanceled(); delete this._searchView; delete this._searchQuery; }, performSearch: function(query) { WebInspector.searchController.updateSearchMatchesCount(0, this); if (!this.visibleView) return; // Call searchCanceled since it will reset everything we need before doing a new search. this.searchCanceled(); this._searchView = this.visibleView; this._searchQuery = query; function finishedCallback(view, searchMatches) { if (!searchMatches) return; WebInspector.searchController.updateSearchMatchesCount(searchMatches, this); view.jumpToFirstSearchResult(); WebInspector.searchController.updateCurrentMatchIndex(view.currentSearchResultIndex, this); } this._searchView.performSearch(query, finishedCallback.bind(this)); }, jumpToNextSearchResult: function() { if (!this._searchView) return; if (this._searchView !== this.visibleView) { this.performSearch(this._searchQuery); return; } if (this._searchView.showingLastSearchResult()) this._searchView.jumpToFirstSearchResult(); else this._searchView.jumpToNextSearchResult(); WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this); }, jumpToPreviousSearchResult: function() { if (!this._searchView) return; if (this._searchView !== this.visibleView) { this.performSearch(this._searchQuery); if (this._searchView) this._searchView.jumpToLastSearchResult(); return; } if (this._searchView.showingFirstSearchResult()) this._searchView.jumpToLastSearchResult(); else this._searchView.jumpToPreviousSearchResult(); WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this); }, _toggleFormatSource: function() { this._toggleFormatSourceButton.toggled = !this._toggleFormatSourceButton.toggled; this._presentationModel.setFormatSource(this._toggleFormatSourceButton.toggled); }, addToWatch: function(expression) { this.sidebarPanes.watchExpressions.addExpression(expression); } } WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype; /** * @interface */ WebInspector.ScriptsPanel.FileSelector = function() { } WebInspector.ScriptsPanel.FileSelector.Events = { FileSelected: "FileSelected", ReleasedFocusAfterSelection: "ReleasedFocusAfterSelection" } WebInspector.ScriptsPanel.FileSelector.prototype = { /** * @type {Element} */ get defaultFocusedElement() { }, /**