UNPKG

strong-arc

Version:

A visual suite for the StrongLoop API Platform

1,302 lines (1,136 loc) 51.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 * @extends {WebInspector.Panel} * @implements {WebInspector.ContextMenu.Provider} * @implements {WebInspector.TargetManager.Observer} * @param {!WebInspector.Workspace=} workspaceForTest */ WebInspector.SourcesPanel = function(workspaceForTest) { WebInspector.Panel.call(this, "sources"); this.registerRequiredCSS("sourcesPanel.css"); new WebInspector.UpgradeFileSystemDropTarget(this.element); this._workspace = workspaceForTest || WebInspector.workspace; this.debugToolbar = this._createDebugToolbar(); this._debugToolbarDrawer = this._createDebugToolbarDrawer(); const initialDebugSidebarWidth = 225; this._splitView = new WebInspector.SplitView(true, true, "sourcesPanelSplitViewState", initialDebugSidebarWidth); this._splitView.enableShowModeSaving(); this._splitView.show(this.element); // Create scripts navigator const initialNavigatorWidth = 225; this.editorView = new WebInspector.SplitView(true, false, "sourcesPanelNavigatorSplitViewState", initialNavigatorWidth); this.editorView.enableShowModeSaving(); this.editorView.element.id = "scripts-editor-split-view"; this.editorView.element.tabIndex = 0; this.editorView.show(this._splitView.mainElement()); this._navigator = new WebInspector.SourcesNavigator(this._workspace); this._navigator.view.setMinimumSize(100, 25); this._navigator.view.show(this.editorView.sidebarElement()); this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceSelected, this._sourceSelected, this); this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceRenamed, this._sourceRenamed, this); this._sourcesView = new WebInspector.SourcesView(this._workspace, this); this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this)); this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this)); this._sourcesView.registerShortcuts(this.registerShortcuts.bind(this)); this._sourcesView.show(this.editorView.mainElement()); this._debugSidebarResizeWidgetElement = document.createElementWithClass("div", "resizer-widget"); this._debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget"; this._splitView.addEventListener(WebInspector.SplitView.Events.ShowModeChanged, this._updateDebugSidebarResizeWidget, this); this._updateDebugSidebarResizeWidget(); this._splitView.installResizer(this._debugSidebarResizeWidgetElement); this.sidebarPanes = {}; this.sidebarPanes.threads = new WebInspector.ThreadsSidebarPane(); this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane(); this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(); this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, this._callFrameSelectedInSidebar.bind(this)); this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this)); this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane(); this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.breakpointManager, this.showUISourceCode.bind(this)); this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this); this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane(); this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane(); this._extensionSidebarPanes = []; this._installDebuggerSidebarController(); WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this)); WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this)); this._dockSideChanged(); this._updateDebuggerButtons(); this._pauseOnExceptionEnabledChanged(); WebInspector.settings.pauseOnExceptionEnabled.addChangeListener(this._pauseOnExceptionEnabledChanged, this); this._setTarget(WebInspector.context.flavor(WebInspector.Target)); WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this); WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._onCurrentTargetChanged, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerReset, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); WebInspector.targetManager.observeTargets(this); } WebInspector.SourcesPanel.minToolbarWidth = 215; WebInspector.SourcesPanel.prototype = { /** * @param {?WebInspector.Target} target */ _setTarget: function(target) { if (!target) return; if (target.debuggerModel.isPaused()) { this._showDebuggerPausedDetails(/** @type {!WebInspector.DebuggerPausedDetails} */ (target.debuggerModel.debuggerPausedDetails())); var callFrame = target.debuggerModel.selectedCallFrame(); if (callFrame) this._selectCallFrame(callFrame); } else { this._paused = false; this._clearInterface(); this._toggleDebuggerSidebarButton.setEnabled(true); } }, /** * @param {!WebInspector.Event} event */ _onCurrentTargetChanged: function(event) { var target = /** @type {?WebInspector.Target} */ (event.data); this._setTarget(target); }, /** * @return {!Element} */ defaultFocusedElement: function() { return this._sourcesView.defaultFocusedElement(); }, /** * @return {boolean} */ paused: function() { return this._paused; }, wasShown: function() { WebInspector.context.setFlavor(WebInspector.SourcesPanel, this); WebInspector.Panel.prototype.wasShown.call(this); }, willHide: function() { WebInspector.Panel.prototype.willHide.call(this); WebInspector.context.setFlavor(WebInspector.SourcesPanel, null); }, /** * @return {!WebInspector.SearchableView} */ searchableView: function() { return this._sourcesView.searchableView(); }, _consoleCommandEvaluatedInSelectedCallFrame: function(event) { var target = /** @type {!WebInspector.Target} */ (event.target.target()); if (WebInspector.context.flavor(WebInspector.Target) !== target) return; this.sidebarPanes.scopechain.update(target.debuggerModel.selectedCallFrame()); }, /** * @param {!WebInspector.Event} event */ _debuggerPaused: function(event) { var details = /** @type {!WebInspector.DebuggerPausedDetails} */ (event.data); if (!this._paused) WebInspector.inspectorView.setCurrentPanel(this); if (WebInspector.context.flavor(WebInspector.Target) === details.target()) this._showDebuggerPausedDetails(details); else if (!this._paused) WebInspector.context.setFlavor(WebInspector.Target, details.target()); }, /** * @param {!WebInspector.DebuggerPausedDetails} details */ _showDebuggerPausedDetails: function(details) { this._paused = true; this._updateDebuggerButtons(); this.sidebarPanes.callstack.update(details); /** * @param {!Element} element * @this {WebInspector.SourcesPanel} */ function didCreateBreakpointHitStatusMessage(element) { this.sidebarPanes.callstack.setStatus(element); } /** * @param {!WebInspector.UILocation} uiLocation * @this {WebInspector.SourcesPanel} */ function didGetUILocation(uiLocation) { var breakpoint = WebInspector.breakpointManager.findBreakpointOnLine(uiLocation.uiSourceCode, uiLocation.lineNumber); if (!breakpoint) return; this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint); this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint.")); } if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) { WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData); WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details, didCreateBreakpointHitStatusMessage.bind(this)); } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) { var eventName = details.auxData["eventName"]; var targetName = details.auxData["targetName"]; this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(eventName, targetName); var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName, details.auxData); 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 if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert) this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion.")); else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation) this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"])); else if (details.reason === WebInspector.DebuggerModel.BreakReason.DebugCommand) this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a debugged function")); else { if (details.callFrames.length) WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(details.callFrames[0], didGetUILocation.bind(this)); else console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better } this._splitView.showBoth(true); this._toggleDebuggerSidebarButton.setEnabled(false); window.focus(); InspectorFrontendHost.bringToFront(); }, /** * @param {!WebInspector.Event} event */ _debuggerResumed: function(event) { var target = /** @type {!WebInspector.Target} */ (event.target.target()); if (WebInspector.context.flavor(WebInspector.Target) !== target) return; this._paused = false; this._clearInterface(); this._toggleDebuggerSidebarButton.setEnabled(true); }, /** * @param {!WebInspector.Event} event */ _debuggerWasEnabled: function(event) { var target = /** @type {!WebInspector.Target} */ (event.target.target()); if (WebInspector.context.flavor(WebInspector.Target) !== target) return; this._updateDebuggerButtons(); }, /** * @param {!WebInspector.Event} event */ _debuggerReset: function(event) { this._debuggerResumed(event); }, /** * @return {!WebInspector.View} */ get visibleView() { return this._sourcesView.visibleView(); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode * @param {number=} lineNumber * @param {number=} columnNumber * @param {boolean=} forceShowInPanel */ showUISourceCode: function(uiSourceCode, lineNumber, columnNumber, forceShowInPanel) { this._showEditor(forceShowInPanel); this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber); }, _showEditor: function(forceShowInPanel) { WebInspector.inspectorView.showPanel("sources"); }, /** * @param {!WebInspector.UILocation} uiLocation * @param {boolean=} forceShowInPanel */ showUILocation: function(uiLocation, forceShowInPanel) { this.showUISourceCode(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, forceShowInPanel); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _revealInNavigator: function(uiSourceCode) { this._navigator.revealUISourceCode(uiSourceCode); }, /** * @param {boolean} ignoreExecutionLineEvents */ setIgnoreExecutionLineEvents: function(ignoreExecutionLineEvents) { this._ignoreExecutionLineEvents = ignoreExecutionLineEvents; }, _executionLineChanged: function(uiLocation) { this._sourcesView.clearCurrentExecutionLine(); this._sourcesView.setExecutionLine(uiLocation); if (this._ignoreExecutionLineEvents) return; this._sourcesView.showSourceLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, 0, undefined, true); }, /** * @param {!WebInspector.Event} event */ _callFrameSelected: function(event) { var callFrame = /** @type {?WebInspector.DebuggerModel.CallFrame} */ (event.data); if (!callFrame || callFrame.target() !== WebInspector.context.flavor(WebInspector.Target)) return; this._selectCallFrame(callFrame); }, /** * @param {!WebInspector.DebuggerModel.CallFrame} callFrame */ _selectCallFrame: function(callFrame) { this.sidebarPanes.scopechain.update(callFrame); this.sidebarPanes.watchExpressions.refreshExpressions(); this.sidebarPanes.callstack.setSelectedCallFrame(callFrame); WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(callFrame, this._executionLineChanged.bind(this)); }, /** * @param {!WebInspector.Event} event */ _sourceSelected: function(event) { var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode); this._sourcesView.showSourceLocation(uiSourceCode, undefined, undefined, !event.data.focusSource) }, /** * @param {!WebInspector.Event} event */ _sourceRenamed: function(event) { var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); this._sourcesView.sourceRenamed(uiSourceCode); }, _pauseOnExceptionEnabledChanged: function() { var enabled = WebInspector.settings.pauseOnExceptionEnabled.get(); this._pauseOnExceptionButton.toggled = enabled; this._pauseOnExceptionButton.title = WebInspector.UIString(enabled ? "Don't pause on exceptions." : "Pause on exceptions."); this._debugToolbarDrawer.classList.toggle("expanded", enabled); }, _updateDebuggerButtons: function() { var currentTarget = WebInspector.context.flavor(WebInspector.Target); if (!currentTarget) return; if (this._paused) { this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Resume script execution (%s).")) this._pauseButton.state = true; this._pauseButton.setLongClickOptionsEnabled((function() { return [ this._longResumeButton ] }).bind(this)); this._pauseButton.setEnabled(true); this._stepOverButton.setEnabled(true); this._stepIntoButton.setEnabled(true); this._stepOutButton.setEnabled(true); } else { this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Pause script execution (%s).")) this._pauseButton.state = false; this._pauseButton.setLongClickOptionsEnabled(null); this._pauseButton.setEnabled(!currentTarget.debuggerModel.isPausing()); this._stepOverButton.setEnabled(false); this._stepIntoButton.setEnabled(false); this._stepOutButton.setEnabled(false); } }, _clearInterface: function() { this.sidebarPanes.callstack.update(null); this.sidebarPanes.scopechain.update(null); this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight(); WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight(); this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight(); this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight(); this._sourcesView.clearCurrentExecutionLine(); this._updateDebuggerButtons(); }, _togglePauseOnExceptions: function() { WebInspector.settings.pauseOnExceptionEnabled.set(!this._pauseOnExceptionButton.toggled); }, /** * @return {boolean} */ _runSnippet: function() { var uiSourceCode = this._sourcesView.currentUISourceCode(); if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets) return false; var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext); if (!currentExecutionContext) return false; WebInspector.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, uiSourceCode); return true; }, /** * @param {!WebInspector.Event} event */ _editorSelected: function(event) { var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); this._editorChanged(uiSourceCode); }, /** * @param {!WebInspector.Event} event */ _editorClosed: function(event) { var wasSelected = /** @type {boolean} */ (event.data.wasSelected); if (wasSelected) this._editorChanged(null); }, /** * @param {?WebInspector.UISourceCode} uiSourceCode */ _editorChanged: function(uiSourceCode) { var isSnippet = uiSourceCode && uiSourceCode.project().type() === WebInspector.projectTypes.Snippets; this._runSnippetButton.element.classList.toggle("hidden", !isSnippet); }, /** * @return {boolean} */ togglePause: function() { var target = WebInspector.context.flavor(WebInspector.Target); if (!target) return true; if (this._paused) { this._paused = false; target.debuggerModel.resume(); } else { // Make sure pauses didn't stick skipped. target.debuggerModel.pause(); } this._clearInterface(); return true; }, /** * @return {?WebInspector.DebuggerModel} */ _prepareToResume: function() { if (!this._paused) return null; this._paused = false; this._clearInterface(); var target = WebInspector.context.flavor(WebInspector.Target); return target ? target.debuggerModel : null; }, /** * @return {boolean} */ _longResume: function() { var debuggerModel = this._prepareToResume(); if (!debuggerModel) return true; debuggerModel.skipAllPausesUntilReloadOrTimeout(500); debuggerModel.resume(); return true; }, /** * @return {boolean} */ _stepOverClicked: function() { var debuggerModel = this._prepareToResume(); if (!debuggerModel) return true; debuggerModel.stepOver(); return true; }, /** * @return {boolean} */ _stepIntoClicked: function() { var debuggerModel = this._prepareToResume(); if (!debuggerModel) return true; debuggerModel.stepInto(); return true; }, /** * @return {boolean} */ _stepOutClicked: function() { var debuggerModel = this._prepareToResume(); if (!debuggerModel) return true; debuggerModel.stepOut(); return true; }, /** * @param {!WebInspector.Event} event */ _callFrameSelectedInSidebar: function(event) { var callFrame = /** @type {!WebInspector.DebuggerModel.CallFrame} */ (event.data); callFrame.target().debuggerModel.setSelectedCallFrame(callFrame); }, /** * @param {!WebInspector.DebuggerModel.Location} rawLocation */ continueToLocation: function(rawLocation) { if (!this._prepareToResume()) return; rawLocation.continueToLocation(); }, _toggleBreakpointsClicked: function(event) { WebInspector.breakpointManager.setBreakpointsActive(!WebInspector.breakpointManager.breakpointsActive()); }, _breakpointsActiveStateChanged: function(event) { var active = event.data; this._toggleBreakpointsButton.toggled = !active; this.sidebarPanes.jsBreakpoints.listElement.classList.toggle("breakpoints-list-deactivated", !active); this._sourcesView.toggleBreakpointsActiveState(active); if (active) this._toggleBreakpointsButton.title = WebInspector.UIString("Deactivate breakpoints."); else this._toggleBreakpointsButton.title = WebInspector.UIString("Activate breakpoints."); }, _createDebugToolbar: function() { var debugToolbar = document.createElementWithClass("div", "scripts-debug-toolbar"); var title, handler; var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta; // Run snippet. title = WebInspector.UIString("Run snippet (%s)."); handler = this._runSnippet.bind(this); this._runSnippetButton = this._createButtonAndRegisterShortcuts("scripts-run-snippet", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.RunSnippet); debugToolbar.appendChild(this._runSnippetButton.element); this._runSnippetButton.element.classList.add("hidden"); // Continue. this._pauseButton = this._createButtonAndRegisterShortcutsForAction("scripts-pause", "", "debugger.toggle-pause"); debugToolbar.appendChild(this._pauseButton.element); // Long resume. title = WebInspector.UIString("Resume with all pauses blocked for 500 ms"); this._longResumeButton = new WebInspector.StatusBarButton(title, "scripts-long-resume"); this._longResumeButton.addEventListener("click", this._longResume.bind(this), this); // Step over. title = WebInspector.UIString("Step over next function call (%s)."); handler = this._stepOverClicked.bind(this); this._stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOver); debugToolbar.appendChild(this._stepOverButton.element); // Step into. title = WebInspector.UIString("Step into next function call (%s)."); handler = this._stepIntoClicked.bind(this); this._stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepInto); debugToolbar.appendChild(this._stepIntoButton.element); // Step out. title = WebInspector.UIString("Step out of current function (%s)."); handler = this._stepOutClicked.bind(this); this._stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOut); debugToolbar.appendChild(this._stepOutButton.element); // Toggle Breakpoints this._toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate breakpoints."), "scripts-toggle-breakpoints"); this._toggleBreakpointsButton.toggled = false; this._toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this); debugToolbar.appendChild(this._toggleBreakpointsButton.element); // Pause on Exception this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item"); this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this); debugToolbar.appendChild(this._pauseOnExceptionButton.element); return debugToolbar; }, _createDebugToolbarDrawer: function() { var debugToolbarDrawer = document.createElementWithClass("div", "scripts-debug-toolbar-drawer"); var label = WebInspector.UIString("Pause On Caught Exceptions"); var setting = WebInspector.settings.pauseOnCaughtException; debugToolbarDrawer.appendChild(WebInspector.SettingsUI.createSettingCheckbox(label, setting, true)); return debugToolbarDrawer; }, /** * @param {!WebInspector.StatusBarButton} button * @param {string} buttonTitle */ _updateButtonTitle: function(button, buttonTitle) { var hasShortcuts = button.shortcuts && button.shortcuts.length; if (hasShortcuts) button.title = String.vsprintf(buttonTitle, [button.shortcuts[0].name]); else button.title = buttonTitle; }, /** * @param {string} buttonId * @param {string} buttonTitle * @param {function(!Event=):boolean} handler * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts * @return {!WebInspector.StatusBarButton} */ _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts) { var button = new WebInspector.StatusBarButton(buttonTitle, buttonId); button.element.addEventListener("click", handler, false); button.shortcuts = shortcuts; this._updateButtonTitle(button, buttonTitle); this.registerShortcuts(shortcuts, handler); return button; }, /** * @param {string} buttonId * @param {string} buttonTitle * @param {string} actionId * @return {!WebInspector.StatusBarButton} */ _createButtonAndRegisterShortcutsForAction: function(buttonId, buttonTitle, actionId) { /** * @return {boolean} */ function handler() { return WebInspector.actionRegistry.execute(actionId); } var shortcuts = WebInspector.shortcutRegistry.shortcutDescriptorsForAction(actionId); return this._createButtonAndRegisterShortcuts(buttonId, buttonTitle, handler, shortcuts); }, addToWatch: function(expression) { this.sidebarPanes.watchExpressions.addExpression(expression); }, _installDebuggerSidebarController: function() { this._toggleNavigatorSidebarButton = this.editorView.createShowHideSidebarButton("navigator", "scripts-navigator-show-hide-button"); this.editorView.mainElement().appendChild(this._toggleNavigatorSidebarButton.element); this._toggleDebuggerSidebarButton = this._splitView.createShowHideSidebarButton("debugger", "scripts-debugger-show-hide-button"); this._splitView.mainElement().appendChild(this._toggleDebuggerSidebarButton.element); this._splitView.mainElement().appendChild(this._debugSidebarResizeWidgetElement); }, _updateDebugSidebarResizeWidget: function() { this._debugSidebarResizeWidgetElement.classList.toggle("hidden", this._splitView.showMode() !== WebInspector.SplitView.ShowMode.Both); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _showLocalHistory: function(uiSourceCode) { WebInspector.RevisionHistoryView.showHistory(uiSourceCode); }, /** * @param {!Event} event * @param {!WebInspector.ContextMenu} contextMenu * @param {!Object} target */ appendApplicableItems: function(event, contextMenu, target) { this._appendUISourceCodeItems(event, contextMenu, target); this._appendRemoteObjectItems(contextMenu, target); }, _suggestReload: function() { if (window.confirm(WebInspector.UIString("It is recommended to restart inspector after making these changes. Would you like to restart it?"))) WebInspector.reload(); }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _mapFileSystemToNetwork: function(uiSourceCode) { WebInspector.SelectUISourceCodeForProjectTypesDialog.show(uiSourceCode.name(), [WebInspector.projectTypes.Network, WebInspector.projectTypes.ContentScripts], mapFileSystemToNetwork.bind(this), this.editorView.mainElement()) /** * @param {!WebInspector.UISourceCode} networkUISourceCode * @this {WebInspector.SourcesPanel} */ function mapFileSystemToNetwork(networkUISourceCode) { this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceBinding); this._suggestReload(); } }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _removeNetworkMapping: function(uiSourceCode) { if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?"))) { this._workspace.removeMapping(uiSourceCode); this._suggestReload(); } }, /** * @param {!WebInspector.UISourceCode} networkUISourceCode */ _mapNetworkToFileSystem: function(networkUISourceCode) { WebInspector.SelectUISourceCodeForProjectTypesDialog.show(networkUISourceCode.name(), [WebInspector.projectTypes.FileSystem], mapNetworkToFileSystem.bind(this), this.editorView.mainElement()) /** * @param {!WebInspector.UISourceCode} uiSourceCode * @this {WebInspector.SourcesPanel} */ function mapNetworkToFileSystem(uiSourceCode) { this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceBinding); this._suggestReload(); } }, /** * @param {!WebInspector.ContextMenu} contextMenu * @param {!WebInspector.UISourceCode} uiSourceCode */ _appendUISourceCodeMappingItems: function(contextMenu, uiSourceCode) { if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) { var hasMappings = !!uiSourceCode.url; if (!hasMappings) contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this._mapFileSystemToNetwork.bind(this, uiSourceCode)); else contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode)); } /** * @param {!WebInspector.Project} project */ function filterProject(project) { return project.type() === WebInspector.projectTypes.FileSystem; } if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) { if (!this._workspace.projects().filter(filterProject).length) return; if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode) contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this._mapNetworkToFileSystem.bind(this, uiSourceCode)); } }, /** * @param {!Event} event * @param {!WebInspector.ContextMenu} contextMenu * @param {!Object} target */ _appendUISourceCodeItems: function(event, contextMenu, target) { if (!(target instanceof WebInspector.UISourceCode)) return; var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (target); var project = uiSourceCode.project(); if (project.type() !== WebInspector.projectTypes.FileSystem) contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Local modifications\u2026" : "Local Modifications\u2026"), this._showLocalHistory.bind(this, uiSourceCode)); this._appendUISourceCodeMappingItems(contextMenu, uiSourceCode); if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script && project.type() !== WebInspector.projectTypes.Snippets) this.sidebarPanes.callstack.appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode.url); if (!event.target.isSelfOrDescendant(this.editorView.sidebarElement())) { contextMenu.appendSeparator(); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in navigator" : "Reveal in Navigator"), this._handleContextMenuReveal.bind(this, uiSourceCode)); } }, /** * @param {!WebInspector.UISourceCode} uiSourceCode */ _handleContextMenuReveal: function(uiSourceCode) { this.editorView.showBoth(); this._revealInNavigator(uiSourceCode); }, /** * @param {!WebInspector.ContextMenu} contextMenu * @param {!Object} target */ _appendRemoteObjectItems: function(contextMenu, target) { if (!(target instanceof WebInspector.RemoteObject)) return; var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Store as global variable" : "Store as Global Variable"), this._saveToTempVariable.bind(this, remoteObject)); if (remoteObject.type === "function") contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Show function definition" : "Show Function Definition"), this._showFunctionDefinition.bind(this, remoteObject)); }, /** * @param {!WebInspector.RemoteObject} remoteObject */ _saveToTempVariable: function(remoteObject) { var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext); if (!currentExecutionContext) return; currentExecutionContext.evaluate("this", "", false, true, false, false, didGetGlobalObject.bind(null, currentExecutionContext.target())); /** * @param {!WebInspector.Target} target * @param {?WebInspector.RemoteObject} global * @param {boolean=} wasThrown */ function didGetGlobalObject(target, global, wasThrown) { /** * @suppressReceiverCheck * @this {Window} */ function remoteFunction(value) { var prefix = "temp"; var index = 1; while ((prefix + index) in this) ++index; var name = prefix + index; this[name] = value; return name; } if (wasThrown || !global) failedToSave(target, global); else global.callFunction(remoteFunction, [WebInspector.RemoteObject.toCallArgument(remoteObject)], didSave.bind(null, global)); } /** * @param {!WebInspector.RemoteObject} global * @param {?WebInspector.RemoteObject} result * @param {boolean=} wasThrown */ function didSave(global, result, wasThrown) { var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext); global.release(); if (!currentExecutionContext || wasThrown || !result || result.type !== "string") failedToSave(global.target(), result); else WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext, result.value); } /** * @param {!WebInspector.Target} target * @param {?WebInspector.RemoteObject} result */ function failedToSave(target, result) { var message = WebInspector.UIString("Failed to save to temp variable."); if (result) { message += " " + result.description; result.release(); } WebInspector.console.error(message); } }, /** * @param {!WebInspector.RemoteObject} remoteObject */ _showFunctionDefinition: function(remoteObject) { var debuggerModel = remoteObject.target().debuggerModel; /** * @param {?WebInspector.DebuggerModel.FunctionDetails} response * @this {WebInspector.SourcesPanel} */ function didGetFunctionDetails(response) { if (!response || !response.location) return; var location = response.location; if (!location) return; var uiLocation = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(location); if (uiLocation) this.showUILocation(uiLocation, true); } debuggerModel.functionDetails(remoteObject, didGetFunctionDetails.bind(this)); }, showGoToSourceDialog: function() { this._sourcesView.showOpenResourceDialog(); }, _dockSideChanged: function() { var vertically = WebInspector.dockController.isVertical() && WebInspector.settings.splitVerticallyWhenDockedToRight.get(); this._splitVertically(vertically); }, /** * @param {boolean} vertically */ _splitVertically: function(vertically) { if (this.sidebarPaneView && vertically === !this._splitView.isVertical()) return; if (this.sidebarPaneView) this.sidebarPaneView.detach(); this._splitView.setVertical(!vertically); if (!vertically) this._splitView.uninstallResizer(this._sourcesView.statusBarContainerElement()); else this._splitView.installResizer(this._sourcesView.statusBarContainerElement()); // Create vertical box with stack. var vbox = new WebInspector.VBox(); vbox.element.appendChild(this._debugToolbarDrawer); vbox.element.appendChild(this.debugToolbar); vbox.setMinimumAndPreferredSizes(25, 25, WebInspector.SourcesPanel.minToolbarWidth, 100); var sidebarPaneStack = new WebInspector.SidebarPaneStack(); sidebarPaneStack.element.classList.add("flex-auto"); sidebarPaneStack.show(vbox.element); if (!vertically) { // Populate the only stack. for (var pane in this.sidebarPanes) sidebarPaneStack.addPane(this.sidebarPanes[pane]); this._extensionSidebarPanesContainer = sidebarPaneStack; this.sidebarPaneView = vbox; } else { var splitView = new WebInspector.SplitView(true, true, "sourcesPanelDebuggerSidebarSplitViewState", 0.5); vbox.show(splitView.mainElement()); // Populate the left stack. sidebarPaneStack.addPane(this.sidebarPanes.threads); sidebarPaneStack.addPane(this.sidebarPanes.callstack); sidebarPaneStack.addPane(this.sidebarPanes.jsBreakpoints); sidebarPaneStack.addPane(this.sidebarPanes.domBreakpoints); sidebarPaneStack.addPane(this.sidebarPanes.xhrBreakpoints); sidebarPaneStack.addPane(this.sidebarPanes.eventListenerBreakpoints); var tabbedPane = new WebInspector.SidebarTabbedPane(); tabbedPane.show(splitView.sidebarElement()); tabbedPane.addPane(this.sidebarPanes.scopechain); tabbedPane.addPane(this.sidebarPanes.watchExpressions); this._extensionSidebarPanesContainer = tabbedPane; this.sidebarPaneView = splitView; } for (var i = 0; i < this._extensionSidebarPanes.length; ++i) this._extensionSidebarPanesContainer.addPane(this._extensionSidebarPanes[i]); this.sidebarPaneView.show(this._splitView.sidebarElement()); this.sidebarPanes.threads.expand(); this.sidebarPanes.scopechain.expand(); this.sidebarPanes.jsBreakpoints.expand(); this.sidebarPanes.callstack.expand(); this._sidebarPaneStack = sidebarPaneStack; this._updateTargetsSidebarVisibility(); if (WebInspector.settings.watchExpressions.get().length > 0) this.sidebarPanes.watchExpressions.expand(); }, /** * @param {string} id * @param {!WebInspector.SidebarPane} pane */ addExtensionSidebarPane: function(id, pane) { this._extensionSidebarPanes.push(pane); this._extensionSidebarPanesContainer.addPane(pane); this.setHideOnDetach(); }, /** * @return {!WebInspector.SourcesView} */ sourcesView: function() { return this._sourcesView; }, /** * @param {!WebInspector.Target} target */ targetAdded: function(target) { this._updateTargetsSidebarVisibility(); }, /** * @param {!WebInspector.Target} target */ targetRemoved: function(target) { this._updateTargetsSidebarVisibility(); }, _updateTargetsSidebarVisibility: function() { if (!this._sidebarPaneStack) return; this._sidebarPaneStack.togglePaneHidden(this.sidebarPanes.threads, WebInspector.targetManager.targets().length < 2); }, __proto__: WebInspector.Panel.prototype } /** * @constructor * @param {!Element} element */ WebInspector.UpgradeFileSystemDropTarget = function(element) { element.addEventListener("dragenter", this._onDragEnter.bind(this), true); element.addEventListener("dragover", this._onDragOver.bind(this), true); this._element = element; } WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType = "Files"; WebInspector.UpgradeFileSystemDropTarget.prototype = { _onDragEnter: function (event) { if (event.dataTransfer.types.indexOf(WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType) === -1) return; event.consume(true); }, _onDragOver: function (event) { if (event.dataTransfer.types.indexOf(WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType) === -1) return; event.dataTransfer.dropEffect = "copy"; event.consume(true); if (this._dragMaskElement) return; this._dragMaskElement = this._element.createChild("div", "fill drag-mask"); this._dragMaskElement.createChild("div", "fill drag-mask-inner").textContent = WebInspector.UIString("Drop workspace folder here"); this._dragMaskElement.addEventListener("drop", this._onDrop.bind(this), true); this._dragMaskElement.addEventListener("dragleave", this._onDragLeave.bind(this), true); }, _onDrop: function (event) { event.consume(true); this._removeMask(); var items = /** @type {!Array.<!DataTransferItem>} */ (event.dataTransfer.items); if (!items.length) return; var entry = items[0].webkitGetAsEntry(); if (!entry.isDirectory) return; InspectorFrontendHost.upgradeDraggedFileSystemPermissions(entry.filesystem); }, _onDragLeave: function (event) { event.consume(true); this._removeMask(); }, _removeMask: function () { this._dragMaskElement.remove(); delete this._dragMaskElement; } } /** * @constructor * @implements {WebInspector.ContextMenu.Provider} */ WebInspector.SourcesPanel.ContextMenuProvider = function() { } WebInspector.SourcesPanel.ContextMenuProvider.prototype = { /** * @param {!Event} event * @param {!WebInspector.ContextMenu} contextMenu * @param {!Object} target */ appendApplicableItems: function(event, contextMenu, target) { WebInspector.inspectorView.panel("sources").appendApplicableItems(event, contextMenu, target); } } /** * @constructor * @implements {WebInspector.Revealer} */ WebInspector.SourcesPanel.UILocationRevealer = function() { } WebInspector.SourcesPanel.UILocationRevealer.prototype = { /** * @param {!Object} uiLocation */ reveal: function(uiLocation) { if (uiLocation instanceof WebInspector.UILocation) /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.panel("sources")).showUILocation(uiLocation); } } /** * @constructor * @implements {WebInspector.Revealer} */ WebInspector.SourcesPanel.UISourceCodeRevealer = function() { } WebInspector.SourcesPanel.UISourceCodeRevealer.prototype = { /** * @param {!Object} uiSourceCode */ reveal: function(uiSourceCode) { if (uiSourceCode instanceof WebInspector.UISourceCode) /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.panel("sources")).showUISourceCode(uiSourceCode); } } /** * @constructor * @implements {WebInspector.ActionDelegate} */ WebInspector.SourcesPanel.ShowGoToSourceDialogActionDelegate = function() {} WebInspector.SourcesPanel.ShowGoToSourceDialogActionDelegate.prototype = { /** * @return {boolean} */ handleAction: function() { var panel = /** @type {?WebInspector.SourcesPanel} */ (WebInspector.inspectorView.showPanel("sources")); if (!panel) return false; panel.showGoToSourceDialog(); return true; } } /** * @constructor * @extends {WebInspector.UISettingDelegate} */ WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate = function() { WebInspector.UISettingDelegate.call(this); } WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate.prototype = { /** * @override * @return {!Element} */ settingElement: function() { var disableJSElement = WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Disable JavaScript"), WebInspector.settings.javaScriptDisabled); this._disableJSCheckbox = disableJSElement.getElementsByTagName("input")[0]; WebInspector.settings.javaScriptDisabled.addChangeListener(this._settingChanged, this); var disableJSInfoParent = this._disableJSCheckbox.parentElement.createChild("span", "monospace"); this._disableJSInfo = disableJSInfoParent.createChild("span", "object-info-state-note hidden"); this._disableJSInfo.title = WebInspector.UIString("JavaScript is blocked on the inspected page (may be disabled in browser settings)."); WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated, this._updateScriptDisabledCheckbox, this); this._updateScriptDisabledCheckbox(); return disableJSElement; }, /** * @param {!WebInspector.Event} event */ _settingChanged: function(event) { PageAgent.setScriptExecutionD