1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * @implements {WebInspector.TabbedEditorContainerDelegate}
8 * @implements {WebInspector.Searchable}
9 * @implements {WebInspector.Replaceable}
10 * @extends {WebInspector.VBox}
11 * @param {!WebInspector.Workspace} workspace
12 * @param {!WebInspector.SourcesPanel} sourcesPanel
13 * @suppressGlobalPropertiesCheck
15 WebInspector.SourcesView = function(workspace, sourcesPanel)
17 WebInspector.VBox.call(this);
18 this.registerRequiredCSS("sources/sourcesView.css");
19 this.element.id = "sources-panel-sources-view";
20 this.setMinimumAndPreferredSizes(50, 52, 150, 100);
22 this._workspace = workspace;
23 this._sourcesPanel = sourcesPanel;
25 this._searchableView = new WebInspector.SearchableView(this, "sourcesViewSearchConfig");
26 this._searchableView.setMinimalSearchQuerySize(0);
27 this._searchableView.show(this.element);
29 /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.UISourceCodeFrame>} */
30 this._sourceFramesByUISourceCode = new Map();
32 var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIString("Hit Cmd+P to open a file") : WebInspector.UIString("Hit Ctrl+P to open a file");
33 this._editorContainer = new WebInspector.TabbedEditorContainer(this, WebInspector.settings.createLocalSetting("previouslyViewedFiles", []), tabbedEditorPlaceholderText);
34 this._editorContainer.show(this._searchableView.element);
35 this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
36 this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
38 this._historyManager = new WebInspector.EditingLocationHistoryManager(this, this.currentSourceFrame.bind(this));
40 this._toolbarContainerElement = this.element.createChild("div", "sources-toolbar");
41 this._toolbarEditorActions = new WebInspector.Toolbar(this._toolbarContainerElement);
43 self.runtime.instancesPromise(WebInspector.SourcesView.EditorAction).then(appendButtonsForExtensions.bind(this));
45 * @param {!Array.<!WebInspector.SourcesView.EditorAction>} actions
46 * @this {WebInspector.SourcesView}
48 function appendButtonsForExtensions(actions)
50 for (var i = 0; i < actions.length; ++i)
51 this._toolbarEditorActions.appendToolbarItem(actions[i].button(this));
53 this._scriptViewToolbarText = new WebInspector.Toolbar(this._toolbarContainerElement);
55 WebInspector.startBatchUpdate();
56 this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
57 WebInspector.endBatchUpdate();
59 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
60 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
61 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved.bind(this), this);
63 function handleBeforeUnload(event)
65 if (event.returnValue)
67 var unsavedSourceCodes = WebInspector.workspace.unsavedSourceCodes();
68 if (!unsavedSourceCodes.length)
71 event.returnValue = WebInspector.UIString("DevTools have unsaved changes that will be permanently lost.");
72 WebInspector.inspectorView.setCurrentPanel(WebInspector.SourcesPanel.instance());
73 for (var i = 0; i < unsavedSourceCodes.length; ++i)
74 WebInspector.Revealer.reveal(unsavedSourceCodes[i]);
77 window.addEventListener("beforeunload", handleBeforeUnload, true);
80 this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
83 WebInspector.SourcesView.Events = {
84 EditorClosed: "EditorClosed",
85 EditorSelected: "EditorSelected",
89 * @param {!WebInspector.UISourceCode} uiSourceCode
92 WebInspector.SourcesView.uiSourceCodeHighlighterType = function(uiSourceCode)
94 var networkContentType = WebInspector.NetworkProject.uiSourceCodeContentType(uiSourceCode);
95 if (networkContentType)
96 return networkContentType.canonicalMimeType();
98 var mimeType = WebInspector.ResourceType.mimeTypesForExtensions[uiSourceCode.extension().toLowerCase()];
99 return mimeType || uiSourceCode.contentType().canonicalMimeType();
102 WebInspector.SourcesView.prototype = {
104 * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, function(!Event=):boolean)} registerShortcutDelegate
106 registerShortcuts: function(registerShortcutDelegate)
109 * @this {WebInspector.SourcesView}
110 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
111 * @param {function(!Event=):boolean} handler
113 function registerShortcut(shortcuts, handler)
115 registerShortcutDelegate(shortcuts, handler);
116 this._registerShortcuts(shortcuts, handler);
119 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousLocation, this._onJumpToPreviousLocation.bind(this));
120 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocation, this._onJumpToNextLocation.bind(this));
121 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab, this._onCloseEditorTab.bind(this));
122 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine, this._showGoToLineDialog.bind(this));
123 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember, this._showOutlineDialog.bind(this));
124 registerShortcut.call(this, [WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift)], this._showOutlineDialog.bind(this));
125 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
126 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.Save, this._save.bind(this));
127 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SaveAll, this._saveAll.bind(this));
131 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
132 * @param {function(!Event=):boolean} handler
134 _registerShortcuts: function(keys, handler)
136 for (var i = 0; i < keys.length; ++i)
137 this._shortcuts[keys[i].key] = handler;
140 _handleKeyDown: function(event)
142 var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
143 var handler = this._shortcuts[shortcutKey];
144 if (handler && handler())
150 WebInspector.VBox.prototype.wasShown.call(this);
151 WebInspector.context.setFlavor(WebInspector.SourcesView, this);
156 WebInspector.context.setFlavor(WebInspector.SourcesView, null);
157 WebInspector.VBox.prototype.willHide.call(this);
163 toolbarContainerElement: function()
165 return this._toolbarContainerElement;
172 defaultFocusedElement: function()
174 return this._editorContainer.view.defaultFocusedElement();
178 * @return {!WebInspector.SearchableView}
180 searchableView: function()
182 return this._searchableView;
186 * @return {!WebInspector.Widget}
188 visibleView: function()
190 return this._editorContainer.visibleView;
194 * @return {?WebInspector.SourceFrame}
196 currentSourceFrame: function()
198 var view = this.visibleView();
199 if (!(view instanceof WebInspector.SourceFrame))
201 return /** @type {!WebInspector.SourceFrame} */ (view);
205 * @return {?WebInspector.UISourceCode}
207 currentUISourceCode: function()
209 return this._currentUISourceCode;
213 * @param {!Event=} event
215 _onCloseEditorTab: function(event)
217 var uiSourceCode = this.currentUISourceCode();
220 this._editorContainer.closeFile(uiSourceCode);
225 * @param {!Event=} event
227 _onJumpToPreviousLocation: function(event)
229 this._historyManager.rollback();
234 * @param {!Event=} event
236 _onJumpToNextLocation: function(event)
238 this._historyManager.rollover();
243 * @param {!WebInspector.Event} event
245 _uiSourceCodeAdded: function(event)
247 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
248 this._addUISourceCode(uiSourceCode);
252 * @param {!WebInspector.UISourceCode} uiSourceCode
254 _addUISourceCode: function(uiSourceCode)
256 if (uiSourceCode.project().isServiceProject())
258 this._editorContainer.addUISourceCode(uiSourceCode);
259 // Replace debugger script-based uiSourceCode with a network-based one.
260 var currentUISourceCode = this._currentUISourceCode;
261 if (!currentUISourceCode)
263 var networkURL = WebInspector.networkMapping.networkURL(uiSourceCode);
264 var currentNetworkURL = WebInspector.networkMapping.networkURL(currentUISourceCode);
265 if (currentUISourceCode.project().isServiceProject() && currentUISourceCode !== uiSourceCode && currentNetworkURL === networkURL && networkURL) {
266 this._showFile(uiSourceCode);
267 this._editorContainer.removeUISourceCode(currentUISourceCode);
271 _uiSourceCodeRemoved: function(event)
273 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
274 this._removeUISourceCodes([uiSourceCode]);
278 * @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes
280 _removeUISourceCodes: function(uiSourceCodes)
282 this._editorContainer.removeUISourceCodes(uiSourceCodes);
283 for (var i = 0; i < uiSourceCodes.length; ++i) {
284 this._removeSourceFrame(uiSourceCodes[i]);
285 this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]);
289 _projectRemoved: function(event)
291 var project = event.data;
292 var uiSourceCodes = project.uiSourceCodes();
293 this._removeUISourceCodes(uiSourceCodes);
294 if (project.type() === WebInspector.projectTypes.Network)
295 this._editorContainer.reset();
298 _updateScriptViewToolbarItems: function()
300 this._scriptViewToolbarText.removeToolbarItems();
301 var sourceFrame = this.currentSourceFrame();
305 var toolbarText = sourceFrame.toolbarText();
306 this._scriptViewToolbarText.appendToolbarItem(toolbarText);
310 * @param {!WebInspector.UISourceCode} uiSourceCode
311 * @param {number=} lineNumber 0-based
312 * @param {number=} columnNumber
313 * @param {boolean=} omitFocus
314 * @param {boolean=} omitHighlight
316 showSourceLocation: function(uiSourceCode, lineNumber, columnNumber, omitFocus, omitHighlight)
318 this._historyManager.updateCurrentState();
319 var sourceFrame = this._showFile(uiSourceCode);
320 if (typeof lineNumber === "number")
321 sourceFrame.revealPosition(lineNumber, columnNumber, !omitHighlight);
322 this._historyManager.pushNewState();
328 * @param {!WebInspector.UISourceCode} uiSourceCode
329 * @return {!WebInspector.SourceFrame}
331 _showFile: function(uiSourceCode)
333 var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
334 if (this._currentUISourceCode === uiSourceCode)
337 this._currentUISourceCode = uiSourceCode;
338 this._editorContainer.showFile(uiSourceCode);
339 this._updateScriptViewToolbarItems();
344 * @param {!WebInspector.UISourceCode} uiSourceCode
345 * @return {!WebInspector.UISourceCodeFrame}
347 _createSourceFrame: function(uiSourceCode)
350 switch (uiSourceCode.contentType()) {
351 case WebInspector.resourceTypes.Script:
352 sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPanel, uiSourceCode);
354 case WebInspector.resourceTypes.Document:
355 sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPanel, uiSourceCode);
357 case WebInspector.resourceTypes.Stylesheet:
358 sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode);
361 sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
364 sourceFrame.setHighlighterType(WebInspector.SourcesView.uiSourceCodeHighlighterType(uiSourceCode));
365 this._sourceFramesByUISourceCode.set(uiSourceCode, sourceFrame);
366 this._historyManager.trackSourceFrameCursorJumps(sourceFrame);
371 * @param {!WebInspector.UISourceCode} uiSourceCode
372 * @return {!WebInspector.UISourceCodeFrame}
374 _getOrCreateSourceFrame: function(uiSourceCode)
376 return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._createSourceFrame(uiSourceCode);
380 * @param {!WebInspector.SourceFrame} sourceFrame
381 * @param {!WebInspector.UISourceCode} uiSourceCode
384 _sourceFrameMatchesUISourceCode: function(sourceFrame, uiSourceCode)
386 switch (uiSourceCode.contentType()) {
387 case WebInspector.resourceTypes.Script:
388 case WebInspector.resourceTypes.Document:
389 return sourceFrame instanceof WebInspector.JavaScriptSourceFrame;
390 case WebInspector.resourceTypes.Stylesheet:
391 return sourceFrame instanceof WebInspector.CSSSourceFrame;
393 return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame);
398 * @param {!WebInspector.UISourceCode} uiSourceCode
400 _recreateSourceFrameIfNeeded: function(uiSourceCode)
402 var oldSourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
405 if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode)) {
406 oldSourceFrame.setHighlighterType(WebInspector.SourcesView.uiSourceCodeHighlighterType(uiSourceCode));
408 this._editorContainer.removeUISourceCode(uiSourceCode);
409 this._removeSourceFrame(uiSourceCode);
415 * @param {!WebInspector.UISourceCode} uiSourceCode
416 * @return {!WebInspector.UISourceCodeFrame}
418 viewForFile: function(uiSourceCode)
420 return this._getOrCreateSourceFrame(uiSourceCode);
424 * @param {!WebInspector.UISourceCode} uiSourceCode
426 _removeSourceFrame: function(uiSourceCode)
428 var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
431 this._sourceFramesByUISourceCode.remove(uiSourceCode);
432 sourceFrame.dispose();
435 clearCurrentExecutionLine: function()
437 if (this._executionSourceFrame)
438 this._executionSourceFrame.clearExecutionLine();
439 delete this._executionSourceFrame;
443 * @param {!WebInspector.UILocation} uiLocation
445 setExecutionLocation: function(uiLocation)
447 var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode);
448 sourceFrame.setExecutionLocation(uiLocation);
449 this._executionSourceFrame = sourceFrame;
452 _editorClosed: function(event)
454 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
455 this._historyManager.removeHistoryForSourceCode(uiSourceCode);
457 var wasSelected = false;
458 if (this._currentUISourceCode === uiSourceCode) {
459 delete this._currentUISourceCode;
463 // SourcesNavigator does not need to update on EditorClosed.
464 this._updateScriptViewToolbarItems();
465 this._searchableView.resetSearch();
468 data.uiSourceCode = uiSourceCode;
469 data.wasSelected = wasSelected;
470 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorClosed, data);
473 _editorSelected: function(event)
475 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.currentFile);
476 var shouldUseHistoryManager = uiSourceCode !== this._currentUISourceCode && event.data.userGesture;
477 if (shouldUseHistoryManager)
478 this._historyManager.updateCurrentState();
479 var sourceFrame = this._showFile(uiSourceCode);
480 if (shouldUseHistoryManager)
481 this._historyManager.pushNewState();
483 this._searchableView.setReplaceable(!!sourceFrame && sourceFrame.canEditSource());
484 this._searchableView.refreshSearch();
486 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorSelected, uiSourceCode);
490 * @param {!WebInspector.UISourceCode} uiSourceCode
492 sourceRenamed: function(uiSourceCode)
494 this._recreateSourceFrameIfNeeded(uiSourceCode);
500 searchCanceled: function()
502 if (this._searchView)
503 this._searchView.searchCanceled();
505 delete this._searchView;
506 delete this._searchConfig;
511 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
512 * @param {boolean} shouldJump
513 * @param {boolean=} jumpBackwards
515 performSearch: function(searchConfig, shouldJump, jumpBackwards)
517 this._searchableView.updateSearchMatchesCount(0);
519 var sourceFrame = this.currentSourceFrame();
523 this._searchView = sourceFrame;
524 this._searchConfig = searchConfig;
527 * @param {!WebInspector.Widget} view
528 * @param {number} searchMatches
529 * @this {WebInspector.SourcesView}
531 function finishedCallback(view, searchMatches)
536 this._searchableView.updateSearchMatchesCount(searchMatches);
540 * @param {number} currentMatchIndex
541 * @this {WebInspector.SourcesView}
543 function currentMatchChanged(currentMatchIndex)
545 this._searchableView.updateCurrentMatchIndex(currentMatchIndex);
549 * @this {WebInspector.SourcesView}
551 function searchResultsChanged()
553 this.performSearch(this._searchConfig, false, false);
556 this._searchView.performSearch(this._searchConfig, shouldJump, !!jumpBackwards, finishedCallback.bind(this), currentMatchChanged.bind(this), searchResultsChanged.bind(this));
562 jumpToNextSearchResult: function()
564 if (!this._searchView)
567 if (this._searchView !== this.currentSourceFrame()) {
568 this.performSearch(this._searchConfig, true);
572 this._searchView.jumpToNextSearchResult();
578 jumpToPreviousSearchResult: function()
580 if (!this._searchView)
583 if (this._searchView !== this.currentSourceFrame()) {
584 this.performSearch(this._searchConfig, true);
585 if (this._searchView)
586 this._searchView.jumpToLastSearchResult();
590 this._searchView.jumpToPreviousSearchResult();
597 supportsCaseSensitiveSearch: function()
606 supportsRegexSearch: function()
613 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
614 * @param {string} replacement
616 replaceSelectionWith: function(searchConfig, replacement)
618 var sourceFrame = this.currentSourceFrame();
620 console.assert(sourceFrame);
623 sourceFrame.replaceSelectionWith(searchConfig, replacement);
628 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig
629 * @param {string} replacement
631 replaceAllWith: function(searchConfig, replacement)
633 var sourceFrame = this.currentSourceFrame();
635 console.assert(sourceFrame);
638 sourceFrame.replaceAllWith(searchConfig, replacement);
642 * @param {!Event=} event
645 _showOutlineDialog: function(event)
647 var uiSourceCode = this._editorContainer.currentFile();
651 switch (uiSourceCode.contentType()) {
652 case WebInspector.resourceTypes.Document:
653 case WebInspector.resourceTypes.Script:
654 WebInspector.JavaScriptOutlineDialog.show(this, uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode));
656 case WebInspector.resourceTypes.Stylesheet:
657 WebInspector.StyleSheetOutlineDialog.show(this, uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode));
660 // We don't want default browser shortcut to be executed, so pretend to handle this event.
666 * @param {string=} query
668 showOpenResourceDialog: function(query)
670 var uiSourceCodes = this._editorContainer.historyUISourceCodes();
671 /** @type {!Map.<!WebInspector.UISourceCode, number>} */
672 var defaultScores = new Map();
673 for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element
674 defaultScores.set(uiSourceCodes[i], uiSourceCodes.length - i);
675 WebInspector.OpenResourceDialog.show(this, this.element, query, defaultScores);
679 * @param {!Event=} event
682 _showGoToLineDialog: function(event)
684 if (this._currentUISourceCode)
685 this.showOpenResourceDialog(":");
694 this._saveSourceFrame(this.currentSourceFrame());
703 var sourceFrames = this._editorContainer.fileViews();
704 sourceFrames.forEach(this._saveSourceFrame.bind(this));
709 * @param {?WebInspector.SourceFrame} sourceFrame
711 _saveSourceFrame: function(sourceFrame)
715 if (!(sourceFrame instanceof WebInspector.UISourceCodeFrame))
717 var uiSourceCodeFrame = /** @type {!WebInspector.UISourceCodeFrame} */ (sourceFrame);
718 uiSourceCodeFrame.commitEditing();
723 _toggleBreakpoint: function()
725 var sourceFrame = this.currentSourceFrame();
729 if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
730 var javaScriptSourceFrame = /** @type {!WebInspector.JavaScriptSourceFrame} */ (sourceFrame);
731 javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
738 * @param {boolean} active
740 toggleBreakpointsActiveState: function(active)
742 this._editorContainer.view.element.classList.toggle("breakpoints-deactivated", !active);
745 __proto__: WebInspector.VBox.prototype
751 WebInspector.SourcesView.EditorAction = function()
755 WebInspector.SourcesView.EditorAction.prototype = {
757 * @param {!WebInspector.SourcesView} sourcesView
758 * @return {!WebInspector.ToolbarButton}
760 button: function(sourcesView) { }
765 * @implements {WebInspector.ActionDelegate}
767 WebInspector.SourcesView.SwitchFileActionDelegate = function()
772 * @param {!WebInspector.UISourceCode} currentUISourceCode
773 * @return {?WebInspector.UISourceCode}
775 WebInspector.SourcesView.SwitchFileActionDelegate._nextFile = function(currentUISourceCode)
778 * @param {string} name
781 function fileNamePrefix(name)
783 var lastDotIndex = name.lastIndexOf(".");
784 var namePrefix = name.substr(0, lastDotIndex !== -1 ? lastDotIndex : name.length);
785 return namePrefix.toLowerCase();
788 var uiSourceCodes = currentUISourceCode.project().uiSourceCodes();
790 var path = currentUISourceCode.parentPath();
791 var name = currentUISourceCode.name();
792 var namePrefix = fileNamePrefix(name);
793 for (var i = 0; i < uiSourceCodes.length; ++i) {
794 var uiSourceCode = uiSourceCodes[i];
795 if (path !== uiSourceCode.parentPath())
797 if (fileNamePrefix(uiSourceCode.name()) === namePrefix)
798 candidates.push(uiSourceCode.name());
800 candidates.sort(String.naturalOrderComparator);
801 var index = mod(candidates.indexOf(name) + 1, candidates.length);
802 var fullPath = (path ? path + "/" : "") + candidates[index];
803 var nextUISourceCode = currentUISourceCode.project().uiSourceCode(fullPath);
804 return nextUISourceCode !== currentUISourceCode ? nextUISourceCode : null;
808 WebInspector.SourcesView.SwitchFileActionDelegate.prototype = {
811 * @param {!WebInspector.Context} context
812 * @param {string} actionId
814 handleAction: function(context, actionId)
816 var sourcesView = WebInspector.context.flavor(WebInspector.SourcesView);
817 var currentUISourceCode = sourcesView.currentUISourceCode();
818 if (!currentUISourceCode)
820 var nextUISourceCode = WebInspector.SourcesView.SwitchFileActionDelegate._nextFile(currentUISourceCode);
821 if (!nextUISourceCode)
823 sourcesView.showSourceLocation(nextUISourceCode);