ScriptsPanel.js 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
  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. importScript("BreakpointsSidebarPane.js");
  27. importScript("CallStackSidebarPane.js");
  28. importScript("FilteredItemSelectionDialog.js");
  29. importScript("UISourceCodeFrame.js");
  30. importScript("JavaScriptSourceFrame.js");
  31. importScript("NavigatorOverlayController.js");
  32. importScript("NavigatorView.js");
  33. importScript("RevisionHistoryView.js");
  34. importScript("ScopeChainSidebarPane.js");
  35. importScript("ScriptsNavigator.js");
  36. importScript("ScriptsSearchScope.js");
  37. importScript("SnippetJavaScriptSourceFrame.js");
  38. importScript("StyleSheetOutlineDialog.js");
  39. importScript("TabbedEditorContainer.js");
  40. importScript("WatchExpressionsSidebarPane.js");
  41. importScript("WorkersSidebarPane.js");
  42. /**
  43. * @constructor
  44. * @implements {WebInspector.TabbedEditorContainerDelegate}
  45. * @implements {WebInspector.ContextMenu.Provider}
  46. * @extends {WebInspector.Panel}
  47. * @param {WebInspector.Workspace=} workspaceForTest
  48. */
  49. WebInspector.ScriptsPanel = function(workspaceForTest)
  50. {
  51. WebInspector.Panel.call(this, "scripts");
  52. this.registerRequiredCSS("scriptsPanel.css");
  53. WebInspector.settings.navigatorWasOnceHidden = WebInspector.settings.createSetting("navigatorWasOnceHidden", false);
  54. WebInspector.settings.debuggerSidebarHidden = WebInspector.settings.createSetting("debuggerSidebarHidden", false);
  55. this._workspace = workspaceForTest || WebInspector.workspace;
  56. function viewGetter()
  57. {
  58. return this.visibleView;
  59. }
  60. WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
  61. var helpSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
  62. this.debugToolbar = this._createDebugToolbar();
  63. const initialDebugSidebarWidth = 225;
  64. const minimumDebugSidebarWidthPercent = 50;
  65. this.createSidebarView(this.element, WebInspector.SidebarView.SidebarPosition.End, initialDebugSidebarWidth);
  66. this.splitView.element.id = "scripts-split-view";
  67. this.splitView.setMinimumSidebarWidth(Preferences.minScriptsSidebarWidth);
  68. this.splitView.setMinimumMainWidthPercent(minimumDebugSidebarWidthPercent);
  69. this.debugSidebarResizeWidgetElement = document.createElement("div");
  70. this.debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget";
  71. this.splitView.installResizer(this.debugSidebarResizeWidgetElement);
  72. // Create scripts navigator
  73. const initialNavigatorWidth = 225;
  74. const minimumViewsContainerWidthPercent = 50;
  75. this.editorView = new WebInspector.SidebarView(WebInspector.SidebarView.SidebarPosition.Start, "scriptsPanelNavigatorSidebarWidth", initialNavigatorWidth);
  76. this.editorView.element.tabIndex = 0;
  77. this.editorView.setMinimumSidebarWidth(Preferences.minScriptsSidebarWidth);
  78. this.editorView.setMinimumMainWidthPercent(minimumViewsContainerWidthPercent);
  79. this.editorView.show(this.splitView.mainElement);
  80. this._navigator = new WebInspector.ScriptsNavigator();
  81. this._navigator.view.show(this.editorView.sidebarElement);
  82. this._editorContainer = new WebInspector.TabbedEditorContainer(this, "previouslyViewedFiles");
  83. this._editorContainer.show(this.editorView.mainElement);
  84. this._navigatorController = new WebInspector.NavigatorOverlayController(this.editorView, this._navigator.view, this._editorContainer.view);
  85. this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ScriptSelected, this._scriptSelected, this);
  86. this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.SnippetCreationRequested, this._snippetCreationRequested, this);
  87. this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.ItemRenamingRequested, this._itemRenamingRequested, this);
  88. this._navigator.addEventListener(WebInspector.ScriptsNavigator.Events.FileRenamed, this._fileRenamed, this);
  89. this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
  90. this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
  91. this.splitView.mainElement.appendChild(this.debugSidebarResizeWidgetElement);
  92. this.sidebarPanes = {};
  93. this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
  94. this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
  95. this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
  96. this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.breakpointManager, this._showSourceLine.bind(this));
  97. this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this);
  98. this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
  99. this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
  100. if (Capabilities.canInspectWorkers && !WebInspector.WorkerManager.isWorkerFrontend()) {
  101. WorkerAgent.enable();
  102. this.sidebarPanes.workerList = new WebInspector.WorkersSidebarPane(WebInspector.workerManager);
  103. }
  104. this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));
  105. this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.EvaluateSelectionInConsole, this._evaluateSelectionInConsole.bind(this));
  106. this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.GoToMember, this._showOutlineDialog.bind(this));
  107. this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
  108. var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel.");
  109. var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower.");
  110. var panelEnablerButton = WebInspector.UIString("Enable Debugging");
  111. this.panelEnablerView = new WebInspector.PanelEnablerView("scripts", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton);
  112. this.panelEnablerView.addEventListener("enable clicked", this._enableDebugging, this);
  113. this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item");
  114. this.enableToggleButton.addEventListener("click", this._toggleDebugging, this);
  115. if (!Capabilities.debuggerCausesRecompilation)
  116. this.enableToggleButton.element.addStyleClass("hidden");
  117. this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
  118. this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this);
  119. this._toggleFormatSourceButton = new WebInspector.StatusBarButton(WebInspector.UIString("Pretty print"), "scripts-toggle-pretty-print-status-bar-item");
  120. this._toggleFormatSourceButton.toggled = false;
  121. this._toggleFormatSourceButton.addEventListener("click", this._toggleFormatSource, this);
  122. this._scriptViewStatusBarItemsContainer = document.createElement("div");
  123. this._scriptViewStatusBarItemsContainer.className = "inline-block";
  124. this._scriptViewStatusBarTextContainer = document.createElement("div");
  125. this._scriptViewStatusBarTextContainer.className = "inline-block";
  126. this._installDebuggerSidebarController();
  127. WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
  128. WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
  129. this._dockSideChanged();
  130. this._sourceFramesByUISourceCode = new Map();
  131. this._updateDebuggerButtons();
  132. this._pauseOnExceptionStateChanged();
  133. if (WebInspector.debuggerModel.isPaused())
  134. this._debuggerPaused();
  135. WebInspector.settings.pauseOnExceptionStateString.addChangeListener(this._pauseOnExceptionStateChanged, this);
  136. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
  137. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerWasDisabled, this);
  138. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
  139. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
  140. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
  141. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
  142. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ExecutionLineChanged, this._executionLineChanged, this);
  143. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
  144. WebInspector.startBatchUpdate();
  145. var uiSourceCodes = this._workspace.uiSourceCodes();
  146. for (var i = 0; i < uiSourceCodes.length; ++i)
  147. this._addUISourceCode(uiSourceCodes[i]);
  148. WebInspector.endBatchUpdate();
  149. this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
  150. this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
  151. this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset.bind(this), this);
  152. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
  153. WebInspector.advancedSearchController.registerSearchScope(new WebInspector.ScriptsSearchScope(this._workspace));
  154. }
  155. WebInspector.ScriptsPanel.prototype = {
  156. statusBarItems: function()
  157. {
  158. return [this.enableToggleButton.element, this._pauseOnExceptionButton.element, this._toggleFormatSourceButton.element, this._scriptViewStatusBarItemsContainer];
  159. },
  160. /**
  161. * @return {?Element}
  162. */
  163. statusBarText: function()
  164. {
  165. return this._scriptViewStatusBarTextContainer;
  166. },
  167. defaultFocusedElement: function()
  168. {
  169. return this._editorContainer.view.defaultFocusedElement() || this._navigator.view.defaultFocusedElement();
  170. },
  171. get paused()
  172. {
  173. return this._paused;
  174. },
  175. wasShown: function()
  176. {
  177. WebInspector.Panel.prototype.wasShown.call(this);
  178. this._navigatorController.wasShown();
  179. },
  180. willHide: function()
  181. {
  182. WebInspector.Panel.prototype.willHide.call(this);
  183. WebInspector.closeViewInDrawer();
  184. },
  185. /**
  186. * @param {WebInspector.Event} event
  187. */
  188. _uiSourceCodeAdded: function(event)
  189. {
  190. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
  191. this._addUISourceCode(uiSourceCode);
  192. },
  193. /**
  194. * @param {WebInspector.UISourceCode} uiSourceCode
  195. */
  196. _addUISourceCode: function(uiSourceCode)
  197. {
  198. if (this._toggleFormatSourceButton.toggled)
  199. uiSourceCode.setFormatted(true);
  200. if (uiSourceCode.project().isServiceProject())
  201. return;
  202. this._navigator.addUISourceCode(uiSourceCode);
  203. this._editorContainer.addUISourceCode(uiSourceCode);
  204. // Replace debugger script-based uiSourceCode with a network-based one.
  205. var currentUISourceCode = this._currentUISourceCode;
  206. if (currentUISourceCode && currentUISourceCode.project().isServiceProject() && currentUISourceCode !== uiSourceCode && currentUISourceCode.url === uiSourceCode.url) {
  207. this._showFile(uiSourceCode);
  208. this._editorContainer.removeUISourceCode(currentUISourceCode);
  209. }
  210. },
  211. _uiSourceCodeRemoved: function(event)
  212. {
  213. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
  214. this._removeUISourceCodes([uiSourceCode]);
  215. },
  216. /**
  217. * @param {Array.<WebInspector.UISourceCode>} uiSourceCodes
  218. */
  219. _removeUISourceCodes: function(uiSourceCodes)
  220. {
  221. for (var i = 0; i < uiSourceCodes.length; ++i) {
  222. this._navigator.removeUISourceCode(uiSourceCodes[i]);
  223. this._removeSourceFrame(uiSourceCodes[i]);
  224. }
  225. this._editorContainer.removeUISourceCodes(uiSourceCodes);
  226. },
  227. _consoleCommandEvaluatedInSelectedCallFrame: function(event)
  228. {
  229. this.sidebarPanes.scopechain.update(WebInspector.debuggerModel.selectedCallFrame());
  230. },
  231. _debuggerPaused: function()
  232. {
  233. var details = WebInspector.debuggerModel.debuggerPausedDetails();
  234. this._paused = true;
  235. this._waitingToPause = false;
  236. this._stepping = false;
  237. this._updateDebuggerButtons();
  238. WebInspector.inspectorView.setCurrentPanel(this);
  239. this.sidebarPanes.callstack.update(details.callFrames);
  240. if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) {
  241. WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData);
  242. function didCreateBreakpointHitStatusMessage(element)
  243. {
  244. this.sidebarPanes.callstack.setStatus(element);
  245. }
  246. WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details.auxData, didCreateBreakpointHitStatusMessage.bind(this));
  247. } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) {
  248. var eventName = details.auxData.eventName;
  249. this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.auxData.eventName);
  250. var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);
  251. this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
  252. } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) {
  253. this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);
  254. this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
  255. } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception)
  256. this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData.description));
  257. else if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert)
  258. this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));
  259. else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation)
  260. this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"]));
  261. else {
  262. function didGetUILocation(uiLocation)
  263. {
  264. var breakpoint = WebInspector.breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber);
  265. if (!breakpoint)
  266. return;
  267. this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);
  268. this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
  269. }
  270. if (details.callFrames.length)
  271. details.callFrames[0].createLiveLocation(didGetUILocation.bind(this));
  272. else
  273. console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
  274. }
  275. this._showDebuggerSidebar();
  276. this._toggleDebuggerSidebarButton.setEnabled(false);
  277. window.focus();
  278. InspectorFrontendHost.bringToFront();
  279. },
  280. _debuggerResumed: function()
  281. {
  282. this._paused = false;
  283. this._waitingToPause = false;
  284. this._stepping = false;
  285. this._clearInterface();
  286. this._toggleDebuggerSidebarButton.setEnabled(true);
  287. },
  288. _debuggerWasEnabled: function()
  289. {
  290. this._updateDebuggerButtons();
  291. },
  292. _debuggerWasDisabled: function()
  293. {
  294. this._debuggerReset();
  295. },
  296. _debuggerReset: function()
  297. {
  298. this._debuggerResumed();
  299. this.sidebarPanes.watchExpressions.reset();
  300. },
  301. _projectWillReset: function(event)
  302. {
  303. var project = event.data;
  304. var uiSourceCodes = project.uiSourceCodes();
  305. this._removeUISourceCodes(uiSourceCodes);
  306. if (project.type() === WebInspector.projectTypes.Network)
  307. this._editorContainer.reset();
  308. },
  309. get visibleView()
  310. {
  311. return this._editorContainer.visibleView;
  312. },
  313. _updateScriptViewStatusBarItems: function()
  314. {
  315. this._scriptViewStatusBarItemsContainer.removeChildren();
  316. this._scriptViewStatusBarTextContainer.removeChildren();
  317. var sourceFrame = this.visibleView;
  318. if (sourceFrame) {
  319. var statusBarItems = sourceFrame.statusBarItems() || [];
  320. for (var i = 0; i < statusBarItems.length; ++i)
  321. this._scriptViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
  322. var statusBarText = sourceFrame.statusBarText();
  323. if (statusBarText)
  324. this._scriptViewStatusBarTextContainer.appendChild(statusBarText);
  325. }
  326. },
  327. canShowAnchorLocation: function(anchor)
  328. {
  329. if (WebInspector.debuggerModel.debuggerEnabled() && anchor.uiSourceCode)
  330. return true;
  331. var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(anchor.href);
  332. if (uiSourceCode) {
  333. anchor.uiSourceCode = uiSourceCode;
  334. return true;
  335. }
  336. return false;
  337. },
  338. showAnchorLocation: function(anchor)
  339. {
  340. this._showSourceLine(anchor.uiSourceCode, anchor.lineNumber);
  341. },
  342. /**
  343. * @param {WebInspector.UISourceCode} uiSourceCode
  344. * @param {number} lineNumber
  345. */
  346. showUISourceCode: function(uiSourceCode, lineNumber)
  347. {
  348. this._showSourceLine(uiSourceCode, lineNumber);
  349. },
  350. /**
  351. * @param {WebInspector.UISourceCode} uiSourceCode
  352. * @param {number=} lineNumber
  353. */
  354. _showSourceLine: function(uiSourceCode, lineNumber)
  355. {
  356. var sourceFrame = this._showFile(uiSourceCode);
  357. if (typeof lineNumber === "number")
  358. sourceFrame.highlightLine(lineNumber);
  359. sourceFrame.focus();
  360. WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
  361. action: WebInspector.UserMetrics.UserActionNames.OpenSourceLink,
  362. url: uiSourceCode.originURL(),
  363. lineNumber: lineNumber
  364. });
  365. },
  366. /**
  367. * @param {WebInspector.UISourceCode} uiSourceCode
  368. * @return {WebInspector.SourceFrame}
  369. */
  370. _showFile: function(uiSourceCode)
  371. {
  372. var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
  373. if (this._currentUISourceCode === uiSourceCode)
  374. return sourceFrame;
  375. this._currentUISourceCode = uiSourceCode;
  376. if (!uiSourceCode.project().isServiceProject())
  377. this._navigator.revealUISourceCode(uiSourceCode, true);
  378. this._editorContainer.showFile(uiSourceCode);
  379. this._updateScriptViewStatusBarItems();
  380. return sourceFrame;
  381. },
  382. /**
  383. * @param {WebInspector.UISourceCode} uiSourceCode
  384. * @return {WebInspector.SourceFrame}
  385. */
  386. _createSourceFrame: function(uiSourceCode)
  387. {
  388. var sourceFrame;
  389. switch (uiSourceCode.contentType()) {
  390. case WebInspector.resourceTypes.Script:
  391. if (uiSourceCode.project().type() === WebInspector.projectTypes.Snippets)
  392. sourceFrame = new WebInspector.SnippetJavaScriptSourceFrame(this, uiSourceCode);
  393. else
  394. sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
  395. break;
  396. case WebInspector.resourceTypes.Document:
  397. sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
  398. break;
  399. case WebInspector.resourceTypes.Stylesheet:
  400. default:
  401. sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
  402. break;
  403. }
  404. this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame);
  405. return sourceFrame;
  406. },
  407. /**
  408. * @param {WebInspector.UISourceCode} uiSourceCode
  409. * @return {WebInspector.SourceFrame}
  410. */
  411. _getOrCreateSourceFrame: function(uiSourceCode)
  412. {
  413. return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._createSourceFrame(uiSourceCode);
  414. },
  415. /**
  416. * @param {WebInspector.UISourceCode} uiSourceCode
  417. * @return {WebInspector.SourceFrame}
  418. */
  419. viewForFile: function(uiSourceCode)
  420. {
  421. return this._getOrCreateSourceFrame(uiSourceCode);
  422. },
  423. /**
  424. * @param {WebInspector.UISourceCode} uiSourceCode
  425. */
  426. _removeSourceFrame: function(uiSourceCode)
  427. {
  428. var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
  429. if (!sourceFrame)
  430. return;
  431. this._sourceFramesByUISourceCode.remove(uiSourceCode);
  432. sourceFrame.dispose();
  433. },
  434. _clearCurrentExecutionLine: function()
  435. {
  436. if (this._executionSourceFrame)
  437. this._executionSourceFrame.clearExecutionLine();
  438. delete this._executionSourceFrame;
  439. },
  440. _executionLineChanged: function(event)
  441. {
  442. var uiLocation = event.data;
  443. this._clearCurrentExecutionLine();
  444. if (!uiLocation)
  445. return;
  446. var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode);
  447. sourceFrame.setExecutionLine(uiLocation.lineNumber);
  448. this._executionSourceFrame = sourceFrame;
  449. },
  450. _revealExecutionLine: function(uiLocation)
  451. {
  452. var uiSourceCode = uiLocation.uiSourceCode;
  453. // Some scripts (anonymous and snippets evaluations) are not added to files select by default.
  454. if (this._currentUISourceCode && this._currentUISourceCode.scriptFile() && this._currentUISourceCode.scriptFile().isDivergingFromVM())
  455. return;
  456. if (this._toggleFormatSourceButton.toggled && !uiSourceCode.formatted())
  457. uiSourceCode.setFormatted(true);
  458. var sourceFrame = this._showFile(uiSourceCode);
  459. sourceFrame.revealLine(uiLocation.lineNumber);
  460. sourceFrame.focus();
  461. },
  462. _callFrameSelected: function(event)
  463. {
  464. var callFrame = event.data;
  465. if (!callFrame)
  466. return;
  467. this.sidebarPanes.scopechain.update(callFrame);
  468. this.sidebarPanes.watchExpressions.refreshExpressions();
  469. this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
  470. callFrame.createLiveLocation(this._revealExecutionLine.bind(this));
  471. },
  472. _editorClosed: function(event)
  473. {
  474. this._navigatorController.hideNavigatorOverlay();
  475. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
  476. if (this._currentUISourceCode === uiSourceCode)
  477. delete this._currentUISourceCode;
  478. // ScriptsNavigator does not need to update on EditorClosed.
  479. this._updateScriptViewStatusBarItems();
  480. WebInspector.searchController.resetSearch();
  481. },
  482. _editorSelected: function(event)
  483. {
  484. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
  485. var sourceFrame = this._showFile(uiSourceCode);
  486. this._navigatorController.hideNavigatorOverlay();
  487. sourceFrame.focus();
  488. WebInspector.searchController.resetSearch();
  489. },
  490. _scriptSelected: function(event)
  491. {
  492. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data.uiSourceCode);
  493. var sourceFrame = this._showFile(uiSourceCode);
  494. this._navigatorController.hideNavigatorOverlay();
  495. if (sourceFrame && event.data.focusSource)
  496. sourceFrame.focus();
  497. },
  498. _pauseOnExceptionStateChanged: function()
  499. {
  500. var pauseOnExceptionsState = WebInspector.settings.pauseOnExceptionStateString.get();
  501. switch (pauseOnExceptionsState) {
  502. case WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions:
  503. this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
  504. break;
  505. case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions:
  506. this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
  507. break;
  508. case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions:
  509. this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
  510. break;
  511. }
  512. this._pauseOnExceptionButton.state = pauseOnExceptionsState;
  513. },
  514. _updateDebuggerButtons: function()
  515. {
  516. if (WebInspector.debuggerModel.debuggerEnabled()) {
  517. this.enableToggleButton.title = WebInspector.UIString("Debugging enabled. Click to disable.");
  518. this.enableToggleButton.toggled = true;
  519. this._pauseOnExceptionButton.visible = true;
  520. this.panelEnablerView.detach();
  521. } else {
  522. this.enableToggleButton.title = WebInspector.UIString("Debugging disabled. Click to enable.");
  523. this.enableToggleButton.toggled = false;
  524. this._pauseOnExceptionButton.visible = false;
  525. this.panelEnablerView.show(this.element);
  526. }
  527. if (this._paused) {
  528. this._updateButtonTitle(this.pauseButton, WebInspector.UIString("Resume script execution (%s)."))
  529. this.pauseButton.addStyleClass("paused");
  530. this.pauseButton.disabled = false;
  531. this.stepOverButton.disabled = false;
  532. this.stepIntoButton.disabled = false;
  533. this.stepOutButton.disabled = false;
  534. this.debuggerStatusElement.textContent = WebInspector.UIString("Paused");
  535. } else {
  536. this._updateButtonTitle(this.pauseButton, WebInspector.UIString("Pause script execution (%s)."))
  537. this.pauseButton.removeStyleClass("paused");
  538. this.pauseButton.disabled = this._waitingToPause;
  539. this.stepOverButton.disabled = true;
  540. this.stepIntoButton.disabled = true;
  541. this.stepOutButton.disabled = true;
  542. if (this._waitingToPause)
  543. this.debuggerStatusElement.textContent = WebInspector.UIString("Pausing");
  544. else if (this._stepping)
  545. this.debuggerStatusElement.textContent = WebInspector.UIString("Stepping");
  546. else
  547. this.debuggerStatusElement.textContent = "";
  548. }
  549. },
  550. _clearInterface: function()
  551. {
  552. this.sidebarPanes.callstack.update(null);
  553. this.sidebarPanes.scopechain.update(null);
  554. this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
  555. WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight();
  556. this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
  557. this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
  558. this._clearCurrentExecutionLine();
  559. this._updateDebuggerButtons();
  560. },
  561. _enableDebugging: function()
  562. {
  563. this._toggleDebugging(this.panelEnablerView.alwaysEnabled);
  564. },
  565. _toggleDebugging: function(optionalAlways)
  566. {
  567. this._paused = false;
  568. this._waitingToPause = false;
  569. this._stepping = false;
  570. if (WebInspector.debuggerModel.debuggerEnabled()) {
  571. WebInspector.settings.debuggerEnabled.set(false);
  572. WebInspector.debuggerModel.disableDebugger();
  573. } else {
  574. WebInspector.settings.debuggerEnabled.set(!!optionalAlways);
  575. WebInspector.debuggerModel.enableDebugger();
  576. }
  577. },
  578. _togglePauseOnExceptions: function()
  579. {
  580. var nextStateMap = {};
  581. var stateEnum = WebInspector.DebuggerModel.PauseOnExceptionsState;
  582. nextStateMap[stateEnum.DontPauseOnExceptions] = stateEnum.PauseOnAllExceptions;
  583. nextStateMap[stateEnum.PauseOnAllExceptions] = stateEnum.PauseOnUncaughtExceptions;
  584. nextStateMap[stateEnum.PauseOnUncaughtExceptions] = stateEnum.DontPauseOnExceptions;
  585. WebInspector.settings.pauseOnExceptionStateString.set(nextStateMap[this._pauseOnExceptionButton.state]);
  586. },
  587. /**
  588. * @param {Event=} event
  589. * @return {boolean}
  590. */
  591. _togglePause: function(event)
  592. {
  593. if (this._paused) {
  594. this._paused = false;
  595. this._waitingToPause = false;
  596. DebuggerAgent.resume();
  597. } else {
  598. this._stepping = false;
  599. this._waitingToPause = true;
  600. DebuggerAgent.pause();
  601. }
  602. this._clearInterface();
  603. return true;
  604. },
  605. /**
  606. * @param {Event=} event
  607. * @return {boolean}
  608. */
  609. _stepOverClicked: function(event)
  610. {
  611. if (!this._paused)
  612. return true;
  613. this._paused = false;
  614. this._stepping = true;
  615. this._clearInterface();
  616. DebuggerAgent.stepOver();
  617. return true;
  618. },
  619. /**
  620. * @param {Event=} event
  621. * @return {boolean}
  622. */
  623. _stepIntoClicked: function(event)
  624. {
  625. if (!this._paused)
  626. return true;
  627. this._paused = false;
  628. this._stepping = true;
  629. this._clearInterface();
  630. DebuggerAgent.stepInto();
  631. return true;
  632. },
  633. /**
  634. * @param {Event=} event
  635. * @return {boolean}
  636. */
  637. _stepOutClicked: function(event)
  638. {
  639. if (!this._paused)
  640. return true;
  641. this._paused = false;
  642. this._stepping = true;
  643. this._clearInterface();
  644. DebuggerAgent.stepOut();
  645. return true;
  646. },
  647. _toggleBreakpointsClicked: function(event)
  648. {
  649. WebInspector.debuggerModel.setBreakpointsActive(!WebInspector.debuggerModel.breakpointsActive());
  650. },
  651. _breakpointsActiveStateChanged: function(event)
  652. {
  653. var active = event.data;
  654. this._toggleBreakpointsButton.toggled = active;
  655. if (active) {
  656. this._toggleBreakpointsButton.title = WebInspector.UIString("Deactivate breakpoints.");
  657. WebInspector.inspectorView.element.removeStyleClass("breakpoints-deactivated");
  658. this.sidebarPanes.jsBreakpoints.listElement.removeStyleClass("breakpoints-list-deactivated");
  659. } else {
  660. this._toggleBreakpointsButton.title = WebInspector.UIString("Activate breakpoints.");
  661. WebInspector.inspectorView.element.addStyleClass("breakpoints-deactivated");
  662. this.sidebarPanes.jsBreakpoints.listElement.addStyleClass("breakpoints-list-deactivated");
  663. }
  664. },
  665. /**
  666. * @param {Event=} event
  667. * @return {boolean}
  668. */
  669. _evaluateSelectionInConsole: function(event)
  670. {
  671. var selection = window.getSelection();
  672. if (selection.type !== "Range" || selection.isCollapsed)
  673. return false;
  674. WebInspector.evaluateInConsole(selection.toString());
  675. return true;
  676. },
  677. _createDebugToolbar: function()
  678. {
  679. var debugToolbar = document.createElement("div");
  680. debugToolbar.className = "status-bar";
  681. debugToolbar.id = "scripts-debug-toolbar";
  682. var title, handler;
  683. var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
  684. // Continue.
  685. handler = this._togglePause.bind(this);
  686. this.pauseButton = this._createButtonAndRegisterShortcuts("scripts-pause", "", handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.PauseContinue);
  687. debugToolbar.appendChild(this.pauseButton);
  688. // Step over.
  689. title = WebInspector.UIString("Step over next function call (%s).");
  690. handler = this._stepOverClicked.bind(this);
  691. this.stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOver);
  692. debugToolbar.appendChild(this.stepOverButton);
  693. // Step into.
  694. title = WebInspector.UIString("Step into next function call (%s).");
  695. handler = this._stepIntoClicked.bind(this);
  696. this.stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepInto);
  697. debugToolbar.appendChild(this.stepIntoButton);
  698. // Step out.
  699. title = WebInspector.UIString("Step out of current function (%s).");
  700. handler = this._stepOutClicked.bind(this);
  701. this.stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, WebInspector.ScriptsPanelDescriptor.ShortcutKeys.StepOut);
  702. debugToolbar.appendChild(this.stepOutButton);
  703. this._toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate breakpoints."), "toggle-breakpoints");
  704. this._toggleBreakpointsButton.toggled = true;
  705. this._toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this);
  706. debugToolbar.appendChild(this._toggleBreakpointsButton.element);
  707. this.debuggerStatusElement = document.createElement("div");
  708. this.debuggerStatusElement.id = "scripts-debugger-status";
  709. debugToolbar.appendChild(this.debuggerStatusElement);
  710. return debugToolbar;
  711. },
  712. _updateButtonTitle: function(button, buttonTitle)
  713. {
  714. button.buttonTitle = buttonTitle;
  715. var hasShortcuts = button.shortcuts && button.shortcuts.length;
  716. if (hasShortcuts)
  717. button.title = String.vsprintf(buttonTitle, [button.shortcuts[0].name]);
  718. else
  719. button.title = buttonTitle;
  720. },
  721. /**
  722. * @param {string} buttonId
  723. * @param {string} buttonTitle
  724. * @param {function(Event=):boolean} handler
  725. * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
  726. */
  727. _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts)
  728. {
  729. var button = document.createElement("button");
  730. button.className = "status-bar-item";
  731. button.id = buttonId;
  732. button.shortcuts = shortcuts;
  733. this._updateButtonTitle(button, buttonTitle);
  734. button.disabled = true;
  735. button.appendChild(document.createElement("img"));
  736. button.addEventListener("click", handler, false);
  737. this.registerShortcuts(shortcuts, handler);
  738. return button;
  739. },
  740. searchCanceled: function()
  741. {
  742. if (this._searchView)
  743. this._searchView.searchCanceled();
  744. delete this._searchView;
  745. delete this._searchQuery;
  746. },
  747. /**
  748. * @param {string} query
  749. */
  750. performSearch: function(query)
  751. {
  752. WebInspector.searchController.updateSearchMatchesCount(0, this);
  753. if (!this.visibleView)
  754. return;
  755. // Call searchCanceled since it will reset everything we need before doing a new search.
  756. this.searchCanceled();
  757. this._searchView = this.visibleView;
  758. this._searchQuery = query;
  759. function finishedCallback(view, searchMatches)
  760. {
  761. if (!searchMatches)
  762. return;
  763. WebInspector.searchController.updateSearchMatchesCount(searchMatches, this);
  764. view.jumpToNextSearchResult();
  765. WebInspector.searchController.updateCurrentMatchIndex(view.currentSearchResultIndex, this);
  766. }
  767. this._searchView.performSearch(query, finishedCallback.bind(this));
  768. },
  769. jumpToNextSearchResult: function()
  770. {
  771. if (!this._searchView)
  772. return;
  773. if (this._searchView !== this.visibleView) {
  774. this.performSearch(this._searchQuery);
  775. return;
  776. }
  777. if (this._searchView.showingLastSearchResult())
  778. this._searchView.jumpToFirstSearchResult();
  779. else
  780. this._searchView.jumpToNextSearchResult();
  781. WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this);
  782. return true;
  783. },
  784. jumpToPreviousSearchResult: function()
  785. {
  786. if (!this._searchView)
  787. return;
  788. if (this._searchView !== this.visibleView) {
  789. this.performSearch(this._searchQuery);
  790. if (this._searchView)
  791. this._searchView.jumpToLastSearchResult();
  792. return;
  793. }
  794. if (this._searchView.showingFirstSearchResult())
  795. this._searchView.jumpToLastSearchResult();
  796. else
  797. this._searchView.jumpToPreviousSearchResult();
  798. WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this);
  799. },
  800. /**
  801. * @return {boolean}
  802. */
  803. canSearchAndReplace: function()
  804. {
  805. var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
  806. return !!view && view.canEditSource();
  807. },
  808. /**
  809. * @param {string} text
  810. */
  811. replaceSelectionWith: function(text)
  812. {
  813. var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
  814. view.replaceSearchMatchWith(text);
  815. },
  816. /**
  817. * @param {string} query
  818. * @param {string} text
  819. */
  820. replaceAllWith: function(query, text)
  821. {
  822. var view = /** @type {WebInspector.SourceFrame} */ (this.visibleView);
  823. view.replaceAllWith(query, text);
  824. },
  825. _toggleFormatSource: function()
  826. {
  827. this._toggleFormatSourceButton.toggled = !this._toggleFormatSourceButton.toggled;
  828. var uiSourceCodes = this._workspace.uiSourceCodes();
  829. for (var i = 0; i < uiSourceCodes.length; ++i)
  830. uiSourceCodes[i].setFormatted(this._toggleFormatSourceButton.toggled);
  831. var currentFile = this._editorContainer.currentFile();
  832. WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
  833. action: WebInspector.UserMetrics.UserActionNames.TogglePrettyPrint,
  834. enabled: this._toggleFormatSourceButton.toggled,
  835. url: currentFile ? currentFile.originURL() : null
  836. });
  837. },
  838. addToWatch: function(expression)
  839. {
  840. this.sidebarPanes.watchExpressions.addExpression(expression);
  841. },
  842. /**
  843. * @return {boolean}
  844. */
  845. _toggleBreakpoint: function()
  846. {
  847. var sourceFrame = this.visibleView;
  848. if (!sourceFrame)
  849. return false;
  850. if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
  851. var javaScriptSourceFrame = /** @type {WebInspector.JavaScriptSourceFrame} */ (sourceFrame);
  852. javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
  853. return true;
  854. }
  855. return false;
  856. },
  857. /**
  858. * @param {Event=} event
  859. * @return {boolean}
  860. */
  861. _showOutlineDialog: function(event)
  862. {
  863. var uiSourceCode = this._editorContainer.currentFile();
  864. if (!uiSourceCode)
  865. return false;
  866. switch (uiSourceCode.contentType()) {
  867. case WebInspector.resourceTypes.Document:
  868. case WebInspector.resourceTypes.Script:
  869. WebInspector.JavaScriptOutlineDialog.show(this.visibleView, uiSourceCode);
  870. return true;
  871. case WebInspector.resourceTypes.Stylesheet:
  872. WebInspector.StyleSheetOutlineDialog.show(this.visibleView, uiSourceCode);
  873. return true;
  874. }
  875. return false;
  876. },
  877. _installDebuggerSidebarController: function()
  878. {
  879. this._toggleDebuggerSidebarButton = new WebInspector.StatusBarButton(WebInspector.UIString("Hide debugger"), "scripts-debugger-show-hide-button", 3);
  880. this._toggleDebuggerSidebarButton.state = "shown";
  881. this._toggleDebuggerSidebarButton.addEventListener("click", clickHandler, this);
  882. function clickHandler()
  883. {
  884. if (this._toggleDebuggerSidebarButton.state === "shown")
  885. this._hideDebuggerSidebar();
  886. else
  887. this._showDebuggerSidebar();
  888. }
  889. this.editorView.element.appendChild(this._toggleDebuggerSidebarButton.element);
  890. if (WebInspector.settings.debuggerSidebarHidden.get())
  891. this._hideDebuggerSidebar();
  892. },
  893. _showDebuggerSidebar: function()
  894. {
  895. if (this._toggleDebuggerSidebarButton.state === "shown")
  896. return;
  897. this._toggleDebuggerSidebarButton.state = "shown";
  898. this._toggleDebuggerSidebarButton.title = WebInspector.UIString("Hide debugger");
  899. this.splitView.showSidebarElement();
  900. this.debugSidebarResizeWidgetElement.removeStyleClass("hidden");
  901. WebInspector.settings.debuggerSidebarHidden.set(false);
  902. },
  903. _hideDebuggerSidebar: function()
  904. {
  905. if (this._toggleDebuggerSidebarButton.state === "hidden")
  906. return;
  907. this._toggleDebuggerSidebarButton.state = "hidden";
  908. this._toggleDebuggerSidebarButton.title = WebInspector.UIString("Show debugger");
  909. this.splitView.hideSidebarElement();
  910. this.debugSidebarResizeWidgetElement.addStyleClass("hidden");
  911. WebInspector.settings.debuggerSidebarHidden.set(true);
  912. },
  913. _fileRenamed: function(event)
  914. {
  915. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data.uiSourceCode);
  916. var name = /** @type {string} */ (event.data.name);
  917. if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
  918. return;
  919. WebInspector.scriptSnippetModel.renameScriptSnippet(uiSourceCode, name);
  920. uiSourceCode.rename(name);
  921. },
  922. /**
  923. * @param {WebInspector.Event} event
  924. */
  925. _snippetCreationRequested: function(event)
  926. {
  927. var uiSourceCode = WebInspector.scriptSnippetModel.createScriptSnippet();
  928. this._showSourceLine(uiSourceCode);
  929. var shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
  930. if (this._navigatorController.isNavigatorHidden())
  931. this._navigatorController.showNavigatorOverlay();
  932. this._navigator.rename(uiSourceCode, callback.bind(this));
  933. /**
  934. * @param {boolean} committed
  935. */
  936. function callback(committed)
  937. {
  938. if (shouldHideNavigator)
  939. this._navigatorController.hideNavigatorOverlay();
  940. if (!committed) {
  941. WebInspector.scriptSnippetModel.deleteScriptSnippet(uiSourceCode);
  942. return;
  943. }
  944. this._showSourceLine(uiSourceCode);
  945. }
  946. },
  947. /**
  948. * @param {WebInspector.Event} event
  949. */
  950. _itemRenamingRequested: function(event)
  951. {
  952. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
  953. var shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
  954. if (this._navigatorController.isNavigatorHidden())
  955. this._navigatorController.showNavigatorOverlay();
  956. this._navigator.rename(uiSourceCode, callback.bind(this));
  957. /**
  958. * @param {boolean} committed
  959. */
  960. function callback(committed)
  961. {
  962. if (shouldHideNavigator && committed) {
  963. this._navigatorController.hideNavigatorOverlay();
  964. this._showSourceLine(uiSourceCode);
  965. }
  966. }
  967. },
  968. /**
  969. * @param {WebInspector.UISourceCode} uiSourceCode
  970. */
  971. _showLocalHistory: function(uiSourceCode)
  972. {
  973. WebInspector.RevisionHistoryView.showHistory(uiSourceCode);
  974. },
  975. /**
  976. * @param {WebInspector.ContextMenu} contextMenu
  977. * @param {Object} target
  978. */
  979. appendApplicableItems: function(event, contextMenu, target)
  980. {
  981. this._appendUISourceCodeItems(contextMenu, target);
  982. this._appendFunctionItems(contextMenu, target);
  983. },
  984. /**
  985. * @param {WebInspector.UISourceCode} uiSourceCode
  986. */
  987. _mapFileSystemToNetwork: function(uiSourceCode)
  988. {
  989. WebInspector.SelectUISourceCodeForProjectTypeDialog.show(uiSourceCode.name(), WebInspector.projectTypes.Network, mapFileSystemToNetwork.bind(this), this.editorView.mainElement)
  990. /**
  991. * @param {WebInspector.UISourceCode} networkUISourceCode
  992. */
  993. function mapFileSystemToNetwork(networkUISourceCode)
  994. {
  995. this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceProvider);
  996. }
  997. },
  998. /**
  999. * @param {WebInspector.UISourceCode} uiSourceCode
  1000. */
  1001. _removeNetworkMapping: function(uiSourceCode)
  1002. {
  1003. if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?")))
  1004. this._workspace.removeMapping(uiSourceCode);
  1005. },
  1006. /**
  1007. * @param {WebInspector.UISourceCode} networkUISourceCode
  1008. */
  1009. _mapNetworkToFileSystem: function(networkUISourceCode)
  1010. {
  1011. WebInspector.SelectUISourceCodeForProjectTypeDialog.show(networkUISourceCode.name(), WebInspector.projectTypes.FileSystem, mapNetworkToFileSystem.bind(this), this.editorView.mainElement)
  1012. /**
  1013. * @param {WebInspector.UISourceCode} uiSourceCode
  1014. */
  1015. function mapNetworkToFileSystem(uiSourceCode)
  1016. {
  1017. this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceProvider);
  1018. }
  1019. },
  1020. /**
  1021. * @param {WebInspector.ContextMenu} contextMenu
  1022. * @param {WebInspector.UISourceCode} uiSourceCode
  1023. */
  1024. _appendUISourceCodeMappingItems: function(contextMenu, uiSourceCode)
  1025. {
  1026. if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
  1027. var hasMappings = !!uiSourceCode.url;
  1028. if (!hasMappings)
  1029. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this._mapFileSystemToNetwork.bind(this, uiSourceCode));
  1030. else
  1031. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode));
  1032. }
  1033. if (uiSourceCode.project().type() === WebInspector.projectTypes.Network) {
  1034. /**
  1035. * @param {WebInspector.Project} project
  1036. */
  1037. function filterProject(project)
  1038. {
  1039. return project.type() === WebInspector.projectTypes.FileSystem;
  1040. }
  1041. if (!this._workspace.projects().filter(filterProject).length)
  1042. return;
  1043. if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode)
  1044. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this._mapNetworkToFileSystem.bind(this, uiSourceCode));
  1045. }
  1046. },
  1047. /**
  1048. * @param {WebInspector.ContextMenu} contextMenu
  1049. * @param {Object} target
  1050. */
  1051. _appendUISourceCodeItems: function(contextMenu, target)
  1052. {
  1053. if (!(target instanceof WebInspector.UISourceCode))
  1054. return;
  1055. var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (target);
  1056. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Local modifications\u2026" : "Local Modifications\u2026"), this._showLocalHistory.bind(this, uiSourceCode));
  1057. if (WebInspector.isolatedFileSystemManager.supportsFileSystems() && WebInspector.experimentsSettings.fileSystemProject.isEnabled())
  1058. this._appendUISourceCodeMappingItems(contextMenu, uiSourceCode);
  1059. var resource = WebInspector.resourceForURL(uiSourceCode.url);
  1060. if (resource && resource.request)
  1061. contextMenu.appendApplicableItems(resource.request);
  1062. },
  1063. /**
  1064. * @param {WebInspector.ContextMenu} contextMenu
  1065. * @param {Object} target
  1066. */
  1067. _appendFunctionItems: function(contextMenu, target)
  1068. {
  1069. if (!(target instanceof WebInspector.RemoteObject))
  1070. return;
  1071. var remoteObject = /** @type {WebInspector.RemoteObject} */ (target);
  1072. if (remoteObject.type !== "function")
  1073. return;
  1074. function didGetDetails(error, response)
  1075. {
  1076. if (error) {
  1077. console.error(error);
  1078. return;
  1079. }
  1080. WebInspector.inspectorView.showPanelForAnchorNavigation(this);
  1081. var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(response.location);
  1082. this._showSourceLine(uiLocation.uiSourceCode, uiLocation.lineNumber);
  1083. }
  1084. function revealFunction()
  1085. {
  1086. DebuggerAgent.getFunctionDetails(remoteObject.objectId, didGetDetails.bind(this));
  1087. }
  1088. contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Show function definition" : "Show Function Definition"), revealFunction.bind(this));
  1089. },
  1090. showGoToSourceDialog: function()
  1091. {
  1092. WebInspector.OpenResourceDialog.show(this, this.editorView.mainElement);
  1093. },
  1094. _dockSideChanged: function()
  1095. {
  1096. var dockSide = WebInspector.dockController.dockSide();
  1097. var vertically = dockSide === WebInspector.DockController.State.DockedToRight && WebInspector.settings.splitVerticallyWhenDockedToRight.get();
  1098. this._splitVertically(vertically);
  1099. },
  1100. /**
  1101. * @param {boolean} vertically
  1102. */
  1103. _splitVertically: function(vertically)
  1104. {
  1105. if (this.sidebarPaneView && vertically === !this.splitView.isVertical())
  1106. return;
  1107. if (this.sidebarPaneView)
  1108. this.sidebarPaneView.detach();
  1109. this.splitView.setVertical(!vertically);
  1110. if (!vertically) {
  1111. this.sidebarPaneView = new WebInspector.SidebarPaneStack();
  1112. for (var pane in this.sidebarPanes)
  1113. this.sidebarPaneView.addPane(this.sidebarPanes[pane]);
  1114. this.sidebarElement.appendChild(this.debugToolbar);
  1115. } else {
  1116. this._showDebuggerSidebar();
  1117. this.sidebarPaneView = new WebInspector.SplitView(true, this.name + "PanelSplitSidebarRatio", 0.5);
  1118. var group1 = new WebInspector.SidebarPaneStack();
  1119. group1.show(this.sidebarPaneView.firstElement());
  1120. group1.element.id = "scripts-sidebar-stack-pane";
  1121. group1.addPane(this.sidebarPanes.watchExpressions);
  1122. group1.addPane(this.sidebarPanes.callstack);
  1123. group1.addPane(this.sidebarPanes.scopechain);
  1124. var group2 = new WebInspector.SidebarTabbedPane();
  1125. group2.show(this.sidebarPaneView.secondElement());
  1126. group2.addPane(this.sidebarPanes.jsBreakpoints);
  1127. group2.addPane(this.sidebarPanes.domBreakpoints);
  1128. group2.addPane(this.sidebarPanes.xhrBreakpoints);
  1129. group2.addPane(this.sidebarPanes.eventListenerBreakpoints);
  1130. group2.addPane(this.sidebarPanes.workerList);
  1131. this.sidebarPaneView.firstElement().appendChild(this.debugToolbar);
  1132. }
  1133. this.sidebarPaneView.element.id = "scripts-debug-sidebar-contents";
  1134. this.sidebarPaneView.show(this.splitView.sidebarElement);
  1135. this.sidebarPanes.scopechain.expand();
  1136. this.sidebarPanes.jsBreakpoints.expand();
  1137. this.sidebarPanes.callstack.expand();
  1138. if (WebInspector.settings.watchExpressions.get().length > 0)
  1139. this.sidebarPanes.watchExpressions.expand();
  1140. },
  1141. __proto__: WebInspector.Panel.prototype
  1142. }