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]; |
+ } |
+} |