Chromium Code Reviews| Index: Source/devtools/front_end/ScriptsPanel.js |
| diff --git a/Source/devtools/front_end/ScriptsPanel.js b/Source/devtools/front_end/ScriptsPanel.js |
| index ed44ed32cf1f1784b3284d48eacd1417ad41a472..38786a79bcfcbf68c1637f85d7dbe70297313467 100644 |
| --- a/Source/devtools/front_end/ScriptsPanel.js |
| +++ b/Source/devtools/front_end/ScriptsPanel.js |
| @@ -128,6 +128,8 @@ WebInspector.ScriptsPanel = function(workspaceForTest) |
| this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this)); |
| this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.GoToMember, this._showOutlineDialog.bind(this)); |
| this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.ToggleBreakpoint, this._toggleBreakpoint.bind(this)); |
| + this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.JumpToPreviousPosition, this._previousPosition.bind(this)); |
| + this.registerShortcuts(WebInspector.ScriptsPanelDescriptor.ShortcutKeys.JumpToNextPosition, this._nextPosition.bind(this)); |
| this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3); |
| this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this); |
| @@ -177,6 +179,8 @@ WebInspector.ScriptsPanel = function(workspaceForTest) |
| this._boundOnKeyUp = this._onKeyUp.bind(this); |
| this._boundOnKeyDown = this._onKeyDown.bind(this); |
| + |
| + this._jumpHistoryManager = new WebInspector.ScriptsPanel.JumpHistoryManager(); |
| } |
| WebInspector.ScriptsPanel.prototype = { |
| @@ -362,6 +366,7 @@ WebInspector.ScriptsPanel.prototype = { |
| this._removeUISourceCodes(uiSourceCodes); |
| if (project.type() === WebInspector.projectTypes.Network) |
| this._editorContainer.reset(); |
| + this._jumpHistoryManager.dropHistoryEntries(project.id(), null); |
|
vsevik
2013/08/29 10:46:16
move this to _removeUISourceCodes
|
| }, |
| get visibleView() |
| @@ -462,6 +467,69 @@ WebInspector.ScriptsPanel.prototype = { |
| /** |
| * @param {WebInspector.UISourceCode} uiSourceCode |
| + * @param {WebInspector.TextEditorPositionHandler} from |
| + * @param {WebInspector.TextEditorPositionHandler} to |
| + */ |
| + _onJumpToPosition: function(uiSourceCode, from, to) |
| + { |
| + if (this._searchQuery || !WebInspector.experimentsSettings.jumpToPreviousLocation.isEnabled()) |
| + return; |
| + if (this._muteJumpToPositionEvent) { |
| + if (from) |
| + this._jumpHistoryManager.updateEntry(this._historyEntryToUpdate, uiSourceCode.project().id(), uiSourceCode.path(), from); |
| + return; |
| + } |
| + if (from && !this._jumpHistoryManager.empty()) |
| + this._jumpHistoryManager.updateEntry(this._jumpHistoryManager.current(), uiSourceCode.project().id(), uiSourceCode.path(), from); |
| + if (to) |
| + this._jumpHistoryManager.push(uiSourceCode.project().id(), uiSourceCode.path(), to); |
| + }, |
| + |
| + /** |
| + * @param {?Event=} event |
| + * @return {boolean} |
| + */ |
| + _previousPosition: function(event) |
| + { |
| + var previous = this._jumpHistoryManager.current(); |
| + var entry = this._jumpHistoryManager.rollback(); |
| + if (!entry) |
| + return false; |
| + this._applyHistoryEntry(previous, entry); |
| + return true; |
| + }, |
| + |
| + /** |
| + * @param {?Event=} event |
| + * @return {boolean} |
| + */ |
| + _nextPosition: function(event) |
| + { |
| + var previous = this._jumpHistoryManager.current(); |
| + var entry = this._jumpHistoryManager.rollover(); |
| + if (!entry) |
| + return false; |
| + this._applyHistoryEntry(previous, entry); |
| + return true; |
| + }, |
| + |
| + /** |
| + * @param {WebInspector.ScriptsPanel.JumpHistoryEntry} previousEntry |
| + * @param {WebInspector.ScriptsPanel.JumpHistoryEntry} newEntry |
| + */ |
| + _applyHistoryEntry: function(previousEntry, newEntry) |
| + { |
| + var position = newEntry.position.resolve(); |
| + var uiSourceCode = WebInspector.workspace.project(newEntry.projectId).uiSourceCode(newEntry.path); |
| + this._muteJumpToPositionEvent = true; |
| + this._historyEntryToUpdate = previousEntry; |
| + this._showSourceLocation(uiSourceCode, position.lineNumber, position.columnNumber); |
| + delete this._historyEntryToUpdate; |
| + delete this._muteJumpToPositionEvent; |
| + }, |
| + |
| + /** |
| + * @param {WebInspector.UISourceCode} uiSourceCode |
| * @return {WebInspector.SourceFrame} |
| */ |
| _createSourceFrame: function(uiSourceCode) |
| @@ -480,6 +548,7 @@ WebInspector.ScriptsPanel.prototype = { |
| break; |
| } |
| this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame); |
| + sourceFrame.setJumpToPositionDelegate(this._onJumpToPosition.bind(this, uiSourceCode)); |
| return sourceFrame; |
| }, |
| @@ -566,6 +635,7 @@ WebInspector.ScriptsPanel.prototype = { |
| if (this._currentUISourceCode === uiSourceCode) |
| delete this._currentUISourceCode; |
| + this._jumpHistoryManager.dropHistoryEntries(uiSourceCode.project().id(), uiSourceCode.path()); |
|
vsevik
2013/08/29 10:46:16
So you don't need to listen for uiSourceCodeRemove
|
| // ScriptsNavigator does not need to update on EditorClosed. |
| this._updateScriptViewStatusBarItems(); |
| WebInspector.searchController.resetSearch(); |
| @@ -1447,3 +1517,135 @@ WebInspector.ScriptsPanel.prototype = { |
| __proto__: WebInspector.Panel.prototype |
| } |
| + |
| +/** |
| + * @constructor |
| + * @param {string} projectId |
| + * @param {string} path |
| + * @param {WebInspector.TextEditorPositionHandler} position |
| + */ |
| +WebInspector.ScriptsPanel.JumpHistoryEntry = function(projectId, path, position) |
| +{ |
| + this.projectId = projectId; |
| + this.path = path; |
| + this.position = position; |
| +} |
| + |
| +WebInspector.ScriptsPanel.JumpHistoryDepth = 20; |
| + |
| +/** |
| + * @constructor |
| + */ |
| +WebInspector.ScriptsPanel.JumpHistoryManager = function() |
| +{ |
| + this._history = []; |
| + this._index = -1; |
| +} |
| + |
| +WebInspector.ScriptsPanel.JumpHistoryManager.prototype = { |
|
vsevik
2013/08/29 10:46:16
Let's extract it to a separate file and delegate r
|
| + /** |
| + * @return {boolean} |
| + */ |
| + empty: function() |
| + { |
| + return !this._history.length; |
| + }, |
| + |
| + /** |
| + * @return {WebInspector.ScriptsPanel.JumpHistoryEntry} |
| + */ |
| + current: function() |
| + { |
| + if (this.empty()) |
| + return null; |
| + return this._history[this._index]; |
| + }, |
| + |
| + /** |
| + * @param {WebInspector.ScriptsPanel.JumpHistoryEntry} entry |
| + * @param {string} projectId |
| + * @param {string} path |
| + * @param {WebInspector.TextEditorPositionHandler} newPosition |
| + */ |
| + updateEntry: function(entry, projectId, path, newPosition) |
| + { |
| + if (entry.projectId === projectId && entry.path === path) |
| + entry.position = newPosition; |
| + }, |
| + |
| + /** |
| + * @param {string} projectId |
| + * @param {string} path |
| + * @param {WebInspector.TextEditorPositionHandler} position |
| + */ |
| + push: function(projectId, path, position) |
| + { |
| + if (this._history.length) { |
| + var entry = this._history[this._index]; |
| + if (entry.projectId === projectId && entry.path === path && entry.position.equal(position)) |
| + return; |
| + } |
| + this._history.splice(++this._index, Infinity, new WebInspector.ScriptsPanel.JumpHistoryEntry(projectId, path, position)); |
| + if (this._history.length > WebInspector.ScriptsPanel.JumpHistoryDepth) { |
| + this._history.shift(); |
| + --this._index; |
| + } |
| + }, |
| + |
| + /** |
| + * @param {string} projectId |
| + * @param {?string} path |
| + */ |
| + dropHistoryEntries: function(projectId, path) |
| + { |
| + for(var i = this._history.length - 1; i >= 0; --i) { |
| + var entry = this._history[i]; |
| + if (entry.projectId === projectId && (!path || entry.path === path)) { |
| + this._history.remove(entry); |
| + if (this._index >= i) |
| + --this._index; |
| + } |
| + } |
| + if (this._index < 0 && this._history.length > 0) |
| + this._index = 0; |
| + }, |
| + |
| + /** |
| + * @return {?WebInspector.ScriptsPanel.JumpHistoryEntry} |
| + */ |
| + rollback: function() { |
| + if (this.empty()) |
| + return null; |
| + for (var validEntryIndex = this._index - 1; validEntryIndex >= 0; --validEntryIndex) { |
| + if (this._history[validEntryIndex].position.resolve()) |
| + break; |
| + } |
| + if (validEntryIndex < 0) { |
| + this._history.splice(0, this._index); |
| + this._index = 0; |
| + return null; |
| + } |
| + this._history.splice(validEntryIndex + 1, this._index - validEntryIndex - 1); |
| + this._index = validEntryIndex; |
| + return this._history[this._index]; |
| + }, |
| + |
| + /** |
| + * @return {?WebInspector.ScriptsPanel.JumpHistoryEntry} |
| + */ |
| + rollover: function() { |
|
vsevik
2013/08/29 10:49:29
{ on the next line, here and below and above.
|
| + if (this.empty()) |
| + return null; |
| + for (var validEntryIndex = this._index + 1; validEntryIndex < this._history.length; ++validEntryIndex) { |
| + if (this._history[validEntryIndex].position.resolve()) |
| + break; |
| + } |
| + if (validEntryIndex >= this._history.length) { |
| + this._history.splice(this._index + 1); |
| + return null; |
| + } |
| + this._history.splice(this._index + 1, validEntryIndex - this._index - 1); |
| + ++this._index; |
| + return this._history[this._index]; |
| + } |
| +} |