https://bugs.webkit.org/show_bug.cgi?id=90294
Reviewed by Yury Semikhatsky.
Source/WebCore:
Scroll and selection change handling is now delegated from TextViewer to SourceFrame.
SourceFrame now dispatches ScrollChanged and SelectionChanged events.
TabbedEditorContainer now saves scroll and selection information together
with the url history and restores scroll and selection on resource opening.
* inspector/front-end/JavaScriptSourceFrame.js:
(WebInspector.JavaScriptSourceFrame.prototype.setExecutionLine):
* inspector/front-end/SourceFrame.js:
(WebInspector.SourceFrame.prototype.wasShown):
(WebInspector.SourceFrame.prototype.highlightLine):
(WebInspector.SourceFrame.prototype._innerHighlightLineIfNeeded):
(WebInspector.SourceFrame.prototype._clearLineHighlight):
(WebInspector.SourceFrame.prototype.revealLine):
(WebInspector.SourceFrame.prototype._innerRevealLineIfNeeded):
(WebInspector.SourceFrame.prototype._clearLineToReveal):
(WebInspector.SourceFrame.prototype.scrollToLine):
(WebInspector.SourceFrame.prototype._innerScrollToLineIfNeeded):
(WebInspector.SourceFrame.prototype._clearLineToScrollTo):
(WebInspector.SourceFrame.prototype.setSelection):
(WebInspector.SourceFrame.prototype._innerSetSelectionIfNeeded):
(WebInspector.SourceFrame.prototype._wasShownOrLoaded):
(WebInspector.SourceFrame.prototype.setContent):
(WebInspector.SourceFrame.prototype.commitEditing):
(WebInspector.SourceFrame.prototype.selectionChanged):
(WebInspector.SourceFrame.prototype.scrollChanged):
(WebInspector.TextViewerDelegateForSourceFrame.prototype.selectionChanged):
(WebInspector.TextViewerDelegateForSourceFrame.prototype.scrollChanged):
* inspector/front-end/TabbedEditorContainer.js:
(WebInspector.TabbedEditorContainer):
(WebInspector.TabbedEditorContainer.prototype._addScrollAndSelectionListeners):
(WebInspector.TabbedEditorContainer.prototype._removeScrollAndSelectionListeners):
(WebInspector.TabbedEditorContainer.prototype._scrollChanged):
(WebInspector.TabbedEditorContainer.prototype._selectionChanged):
(WebInspector.TabbedEditorContainer.prototype._appendFileTab):
(WebInspector.TabbedEditorContainer.prototype._tabClosed):
(WebInspector.TabbedEditorContainer.HistoryItem):
(WebInspector.TabbedEditorContainer.HistoryItem.fromObject):
(WebInspector.TabbedEditorContainer.HistoryItem.prototype.serializeToObject):
(WebInspector.TabbedEditorContainer.History):
(WebInspector.TabbedEditorContainer.History.fromObject):
(WebInspector.TabbedEditorContainer.History.prototype.index):
(WebInspector.TabbedEditorContainer.History.prototype.selectionRange):
(WebInspector.TabbedEditorContainer.History.prototype.updateSelectionRange):
(WebInspector.TabbedEditorContainer.History.prototype.scrollLineNumber):
(WebInspector.TabbedEditorContainer.History.prototype.updateScrollLineNumber):
(WebInspector.TabbedEditorContainer.History.prototype.update):
(WebInspector.TabbedEditorContainer.History.prototype.remove):
(WebInspector.TabbedEditorContainer.History.prototype.save):
(WebInspector.TabbedEditorContainer.History.prototype.set _serializeToObject):
* inspector/front-end/TextEditorModel.js:
(WebInspector.TextRange.fromObject):
(WebInspector.TextRange.prototype.clone):
(WebInspector.TextRange.prototype.serializeToObject):
* inspector/front-end/TextViewer.js:
(WebInspector.TextViewer.prototype._handleScrollChanged):
(WebInspector.TextViewer.prototype.scrollToLine):
(WebInspector.TextViewer.prototype._handleSelectionChange):
(WebInspector.TextViewer.prototype.setSelection):
(WebInspector.TextViewer.prototype.wasShown):
(WebInspector.TextViewer.prototype._handleFocused):
(WebInspector.TextViewer.prototype.willHide):
(WebInspector.TextViewerDelegate.prototype.selectionChanged):
(WebInspector.TextViewerDelegate.prototype.scrollChanged):
(WebInspector.TextEditorChunkedPanel.prototype.scrollToLine):
LayoutTests:
* inspector/tabbed-editors-history-expected.txt:
* inspector/tabbed-editors-history.html:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121750
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-07-03 Vsevolod Vlasov <vsevik@chromium.org>
+
+ Web Inspector: Save scroll selection and cursor position of SourceFrames in sources panel.
+ https://bugs.webkit.org/show_bug.cgi?id=90294
+
+ Reviewed by Yury Semikhatsky.
+
+ * inspector/tabbed-editors-history-expected.txt:
+ * inspector/tabbed-editors-history.html:
+
2012-07-03 Taiju Tsuiki <tzik@chromium.org>
Web Inspector: Make DirectoryContentView sortable
Bug 76912
history = []
- history = [url_1]
- history = [url_2,url_1]
- history = [url_3,url_2,url_1]
- history = [url_2,url_3,url_1]
- history = [url_1,url_2,url_3]
- history = [url_11,url_1,url_2,url_3]
- history = [url_12,url_11,url_1,url_2,url_3]
- history = [url_13,url_12,url_11,url_1,url_2,url_3]
- history = [url_12,url_13,url_11,url_1,url_2,url_3]
- history = [url_11,url_12,url_13,url_1,url_2,url_3]
- history = [url_12,url_13,url_1,url_2,url_3]
- history = [url_12,url_1,url_2,url_3]
- history = [url_14,url_12,url_1,url_2,url_3]
- history = [url_15,url_14,url_12,url_1,url_2,url_3]
- history = [url_16,url_15,url_14,url_12,url_1,url_2,url_3]
- history = [url_15,url_14,url_12,url_1,url_2,url_3]
- history = [url_14,url_12,url_1,url_2,url_3]
- history = [url_12,url_1,url_2,url_3]
- history = [url_1,url_2,url_3]
- history = [url_2,url_3]
- history = [url_3]
+ history = [{"url":"url_1"}]
+ history = [{"url":"url_2"},{"url":"url_1"}]
+ history = [{"url":"url_3"},{"url":"url_2"},{"url":"url_1"}]
+ history = [{"url":"url_2"},{"url":"url_3"},{"url":"url_1"}]
+ history = [{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_11"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_12"},{"url":"url_11"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_13"},{"url":"url_12"},{"url":"url_11"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_12"},{"url":"url_13"},{"url":"url_11"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_11"},{"url":"url_12"},{"url":"url_13"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_11","selectionRange":{"startLine":15,"startColumn":5,"endLine":15,"endColumn":10},"scrollLineNumber":10},{"url":"url_12"},{"url":"url_13"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_12"},{"url":"url_13"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_12"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_14"},{"url":"url_12"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_15"},{"url":"url_14"},{"url":"url_12"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_16"},{"url":"url_15"},{"url":"url_14"},{"url":"url_12"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_15"},{"url":"url_14"},{"url":"url_12"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_14"},{"url":"url_12"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_12"},{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_1"},{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_2"},{"url":"url_3"}]
+ history = [{"url":"url_3"}]
history = []
{
function dumpHistory(history)
{
- InspectorTest.addResult(" history = [" + String(history._urls) + "]");
+ InspectorTest.addResult(" history = " + JSON.stringify(history._serializeToObject()) + "");
+ }
+
+ function updateScrollAndSelectionAndDump(history, url, scrollLineNumber, selection)
+ {
+ history.updateScrollLineNumber(url, scrollLineNumber);
+ history.updateSelectionRange(url, selection);
+ dumpHistory(history);
}
function updateAndDump(history, urls)
// ... and switching between them.
updateAndDump(history, [url(12), url(13), url(11)]);
updateAndDump(history, [url(11), url(12), url(13)]);
+ updateScrollAndSelectionAndDump(history, url(11), 10, new WebInspector.TextRange(15, 5, 15, 10));
// Now close some tabs.
removeAndDump(history, url(11));
removeAndDump(history, url(13));
+2012-07-03 Vsevolod Vlasov <vsevik@chromium.org>
+
+ Web Inspector: Save scroll selection and cursor position of SourceFrames in sources panel.
+ https://bugs.webkit.org/show_bug.cgi?id=90294
+
+ Reviewed by Yury Semikhatsky.
+
+ Scroll and selection change handling is now delegated from TextViewer to SourceFrame.
+ SourceFrame now dispatches ScrollChanged and SelectionChanged events.
+ TabbedEditorContainer now saves scroll and selection information together
+ with the url history and restores scroll and selection on resource opening.
+
+ * inspector/front-end/JavaScriptSourceFrame.js:
+ (WebInspector.JavaScriptSourceFrame.prototype.setExecutionLine):
+ * inspector/front-end/SourceFrame.js:
+ (WebInspector.SourceFrame.prototype.wasShown):
+ (WebInspector.SourceFrame.prototype.highlightLine):
+ (WebInspector.SourceFrame.prototype._innerHighlightLineIfNeeded):
+ (WebInspector.SourceFrame.prototype._clearLineHighlight):
+ (WebInspector.SourceFrame.prototype.revealLine):
+ (WebInspector.SourceFrame.prototype._innerRevealLineIfNeeded):
+ (WebInspector.SourceFrame.prototype._clearLineToReveal):
+ (WebInspector.SourceFrame.prototype.scrollToLine):
+ (WebInspector.SourceFrame.prototype._innerScrollToLineIfNeeded):
+ (WebInspector.SourceFrame.prototype._clearLineToScrollTo):
+ (WebInspector.SourceFrame.prototype.setSelection):
+ (WebInspector.SourceFrame.prototype._innerSetSelectionIfNeeded):
+ (WebInspector.SourceFrame.prototype._wasShownOrLoaded):
+ (WebInspector.SourceFrame.prototype.setContent):
+ (WebInspector.SourceFrame.prototype.commitEditing):
+ (WebInspector.SourceFrame.prototype.selectionChanged):
+ (WebInspector.SourceFrame.prototype.scrollChanged):
+ (WebInspector.TextViewerDelegateForSourceFrame.prototype.selectionChanged):
+ (WebInspector.TextViewerDelegateForSourceFrame.prototype.scrollChanged):
+ * inspector/front-end/TabbedEditorContainer.js:
+ (WebInspector.TabbedEditorContainer):
+ (WebInspector.TabbedEditorContainer.prototype._addScrollAndSelectionListeners):
+ (WebInspector.TabbedEditorContainer.prototype._removeScrollAndSelectionListeners):
+ (WebInspector.TabbedEditorContainer.prototype._scrollChanged):
+ (WebInspector.TabbedEditorContainer.prototype._selectionChanged):
+ (WebInspector.TabbedEditorContainer.prototype._appendFileTab):
+ (WebInspector.TabbedEditorContainer.prototype._tabClosed):
+ (WebInspector.TabbedEditorContainer.HistoryItem):
+ (WebInspector.TabbedEditorContainer.HistoryItem.fromObject):
+ (WebInspector.TabbedEditorContainer.HistoryItem.prototype.serializeToObject):
+ (WebInspector.TabbedEditorContainer.History):
+ (WebInspector.TabbedEditorContainer.History.fromObject):
+ (WebInspector.TabbedEditorContainer.History.prototype.index):
+ (WebInspector.TabbedEditorContainer.History.prototype.selectionRange):
+ (WebInspector.TabbedEditorContainer.History.prototype.updateSelectionRange):
+ (WebInspector.TabbedEditorContainer.History.prototype.scrollLineNumber):
+ (WebInspector.TabbedEditorContainer.History.prototype.updateScrollLineNumber):
+ (WebInspector.TabbedEditorContainer.History.prototype.update):
+ (WebInspector.TabbedEditorContainer.History.prototype.remove):
+ (WebInspector.TabbedEditorContainer.History.prototype.save):
+ (WebInspector.TabbedEditorContainer.History.prototype.set _serializeToObject):
+ * inspector/front-end/TextEditorModel.js:
+ (WebInspector.TextRange.fromObject):
+ (WebInspector.TextRange.prototype.clone):
+ (WebInspector.TextRange.prototype.serializeToObject):
+ * inspector/front-end/TextViewer.js:
+ (WebInspector.TextViewer.prototype._handleScrollChanged):
+ (WebInspector.TextViewer.prototype.scrollToLine):
+ (WebInspector.TextViewer.prototype._handleSelectionChange):
+ (WebInspector.TextViewer.prototype.setSelection):
+ (WebInspector.TextViewer.prototype.wasShown):
+ (WebInspector.TextViewer.prototype._handleFocused):
+ (WebInspector.TextViewer.prototype.willHide):
+ (WebInspector.TextViewerDelegate.prototype.selectionChanged):
+ (WebInspector.TextViewerDelegate.prototype.scrollChanged):
+ (WebInspector.TextEditorChunkedPanel.prototype.scrollToLine):
+
2012-07-03 Taiju Tsuiki <tzik@chromium.org>
Web Inspector: Make DirectoryContentView sortable
if (this.loaded) {
this.textEditor.addDecoration(lineNumber, "webkit-execution-line");
this.revealLine(this._executionLineNumber);
+ if (this.canEditSource())
+ this.setSelection(WebInspector.TextRange.createFromLocation(lineNumber, 0));
}
- if (this.canEditSource())
- this.setSelection(WebInspector.TextRange.createFromLocation(lineNumber, 0));
},
clearExecutionLine: function()
return regex;
}
+WebInspector.SourceFrame.Events = {
+ ScrollChanged: "ScrollChanged",
+ SelectionChanged: "SelectionChanged"
+}
+
WebInspector.SourceFrame.prototype = {
wasShown: function()
{
this._ensureContentLoaded();
this._textEditor.show(this.element);
+ this._wasShownOrLoaded();
},
willHide: function()
return this._textModel;
},
+ /**
+ * @param {number} line
+ */
canHighlightLine: function(line)
{
return true;
},
+ /**
+ * @param {number} line
+ */
highlightLine: function(line)
{
this._clearLineToReveal();
- if (this.loaded)
- this._textEditor.highlightLine(line);
- else
- this._lineToHighlight = line;
+ this._clearLineToScrollTo();
+ this._lineToHighlight = line;
+ this._innerHighlightLineIfNeeded();
+ },
+
+ _innerHighlightLineIfNeeded: function()
+ {
+ if (typeof this._lineToHighlight === "number") {
+ if (this.loaded && this._textEditor.isShowing()) {
+ this._textEditor.highlightLine(this._lineToHighlight);
+ delete this._lineToHighlight
+ }
+ }
},
_clearLineHighlight: function()
{
- if (this.loaded)
- this._textEditor.clearLineHighlight();
- else
- delete this._lineToHighlight;
+ this._textEditor.clearLineHighlight();
+ delete this._lineToHighlight;
},
+ /**
+ * @param {number} line
+ */
revealLine: function(line)
{
this._clearLineHighlight();
- if (this.loaded)
- this._textEditor.revealLine(line);
- else
- this._lineToReveal = line;
+ this._clearLineToScrollTo();
+ this._lineToReveal = line;
+ this._innerRevealLineIfNeeded();
+ },
+
+ _innerRevealLineIfNeeded: function()
+ {
+ if (typeof this._lineToReveal === "number") {
+ if (this.loaded && this._textEditor.isShowing()) {
+ this._textEditor.revealLine(this._lineToReveal);
+ delete this._lineToReveal
+ }
+ }
+ },
+
+ _clearLineToReveal: function()
+ {
+ delete this._lineToReveal;
+ },
+
+ /**
+ * @param {number} line
+ */
+ scrollToLine: function(line)
+ {
+ this._clearLineHighlight();
+ this._clearLineToReveal();
+ this._lineToScrollTo = line;
+ this._innerScrollToLineIfNeeded();
+ },
+
+ _innerScrollToLineIfNeeded: function()
+ {
+ if (typeof this._lineToScrollTo === "number") {
+ if (this.loaded && this._textEditor.isShowing()) {
+ this._textEditor.scrollToLine(this._lineToScrollTo);
+ delete this._lineToScrollTo
+ }
+ }
+ },
+
+ _clearLineToScrollTo: function()
+ {
+ delete this._lineToScrollTo;
},
/**
*/
setSelection: function(textRange)
{
- if (this.loaded)
- this._textEditor.setSelection(textRange);
- else
- this._selectionToSet = textRange;
+ this._selectionToSet = textRange;
+ this._innerSetSelectionIfNeeded();
},
- _clearLineToReveal: function()
+ _innerSetSelectionIfNeeded: function()
{
- delete this._lineToReveal;
+ if (this._selectionToSet && this.loaded && this._textEditor.isShowing()) {
+ this._textEditor.setSelection(this._selectionToSet);
+ delete this._selectionToSet;
+ }
+ },
+
+ _wasShownOrLoaded: function()
+ {
+ this._innerHighlightLineIfNeeded();
+ this._innerRevealLineIfNeeded();
+ this._innerScrollToLineIfNeeded();
+ this._innerSetSelectionIfNeeded();
},
beforeTextChanged: function()
this._setTextEditorDecorations();
- if (typeof this._lineToHighlight === "number") {
- this.highlightLine(this._lineToHighlight);
- delete this._lineToHighlight;
- }
-
- if (typeof this._lineToReveal === "number") {
- this.revealLine(this._lineToReveal);
- delete this._lineToReveal;
- }
-
- if (typeof this._selectionToSet === "object") {
- this.setSelection(this._selectionToSet);
- delete this._selectionToSet;
- }
+ this._wasShownOrLoaded();
if (this._delayedFindSearchMatches) {
this._delayedFindSearchMatches();
*/
commitEditing: function(text)
{
+ },
+
+ /**
+ * @param {WebInspector.TextRange} textRange
+ */
+ selectionChanged: function(textRange)
+ {
+ this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
+ },
+
+ /**
+ * @param {number} lineNumber
+ */
+ scrollChanged: function(lineNumber)
+ {
+ this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged, lineNumber);
}
}
this._sourceFrame.commitEditing(this._sourceFrame._textModel.text);
},
+ /**
+ * @param {WebInspector.TextRange} textRange
+ */
+ selectionChanged: function(textRange)
+ {
+ this._sourceFrame.selectionChanged(textRange);
+ },
+
+ /**
+ * @param {number} lineNumber
+ */
+ scrollChanged: function(lineNumber)
+ {
+ this._sourceFrame.scrollChanged(lineNumber);
+ },
+
populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
this._sourceFrame.populateLineGutterContextMenu(contextMenu, lineNumber);
this._loadedURLs = {};
this._previouslyViewedFilesSetting = WebInspector.settings.createSetting(settingName, []);
- this._history = new WebInspector.TabbedEditorContainer.History(this._previouslyViewedFilesSetting.get());
+ this._history = WebInspector.TabbedEditorContainer.History.fromObject(this._previouslyViewedFilesSetting.get());
}
this._innerShowFile(uiSourceCode, true);
},
+ _addScrollAndSelectionListeners: function()
+ {
+ console.assert(this._currentFile);
+ var sourceFrame = this._delegate.viewForFile(this._currentFile);
+ sourceFrame.addEventListener(WebInspector.SourceFrame.Events.ScrollChanged, this._scrollChanged, this);
+ sourceFrame.addEventListener(WebInspector.SourceFrame.Events.SelectionChanged, this._selectionChanged, this);
+ },
+
+ _removeScrollAndSelectionListeners: function()
+ {
+ if (!this._currentFile)
+ return;
+ var sourceFrame = this._delegate.viewForFile(this._currentFile);
+ sourceFrame.removeEventListener(WebInspector.SourceFrame.Events.ScrollChanged, this._scrollChanged, this);
+ sourceFrame.removeEventListener(WebInspector.SourceFrame.Events.SelectionChanged, this._selectionChanged, this);
+ },
+
+ _scrollChanged: function(event)
+ {
+ var lineNumber = /** @type {number} */ event.data;
+ this._history.updateScrollLineNumber(this._currentFile.url, lineNumber);
+ this._history.save(this._previouslyViewedFilesSetting);
+ },
+
+ _selectionChanged: function(event)
+ {
+ var range = /** @type {WebInspector.TextRange} */ event.data;
+ this._history.updateSelectionRange(this._currentFile.url, range);
+ this._history.save(this._previouslyViewedFilesSetting);
+ },
+
/**
* @param {WebInspector.UISourceCode} uiSourceCode
* @param {boolean=} userGesture
{
if (this._currentFile === uiSourceCode)
return;
+ this._removeScrollAndSelectionListeners();
this._currentFile = uiSourceCode;
var tabId = this._tabIds.get(uiSourceCode) || this._appendFileTab(uiSourceCode, userGesture);
if (userGesture)
this._editorSelectedByUserAction();
+ this._addScrollAndSelectionListeners();
+
this.dispatchEventToListeners(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._currentFile);
},
this._tabIds.put(uiSourceCode, tabId);
this._files[tabId] = uiSourceCode;
+ var savedScrollLineNumber = this._history.scrollLineNumber(uiSourceCode.url);
+ if (savedScrollLineNumber)
+ view.scrollToLine(savedScrollLineNumber);
+ var savedSelectionRange = this._history.selectionRange(uiSourceCode.url);
+ if (savedSelectionRange)
+ view.setSelection(savedSelectionRange);
+
this._tabbedPane.appendTab(tabId, title, view, tooltip, userGesture);
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleChanged, this);
var tabId = /** @type {string} */ event.data.tabId;
var userGesture = /** @type {boolean} */ event.data.isUserGesture;
+ this._removeScrollAndSelectionListeners();
var uiSourceCode = this._files[tabId];
this._tabIds.remove(uiSourceCode);
delete this._files[tabId];
/**
* @constructor
+ * @param {string} url
+ * @param {WebInspector.TextRange=} selectionRange
+ * @param {number=} scrollLineNumber
+ */
+WebInspector.TabbedEditorContainer.HistoryItem = function(url, selectionRange, scrollLineNumber)
+{
+ this.url = url;
+ this.selectionRange = selectionRange;
+ this.scrollLineNumber = scrollLineNumber;
+}
+
+/**
+ * @param {Object} serializedHistoryItem
+ * @return {WebInspector.TabbedEditorContainer.HistoryItem}
+ */
+WebInspector.TabbedEditorContainer.HistoryItem.fromObject = function (serializedHistoryItem)
+{
+ var selectionRange = serializedHistoryItem.selectionRange ? WebInspector.TextRange.fromObject(serializedHistoryItem.selectionRange) : null;
+ return new WebInspector.TabbedEditorContainer.HistoryItem(serializedHistoryItem.url, selectionRange, serializedHistoryItem.scrollLineNumber);
+}
+
+WebInspector.TabbedEditorContainer.HistoryItem.prototype = {
+ /**
+ * @return {Object}
+ */
+ serializeToObject: function()
+ {
+ var serializedHistoryItem = {};
+ serializedHistoryItem.url = this.url;
+ serializedHistoryItem.selectionRange = this.selectionRange;
+ serializedHistoryItem.scrollLineNumber = this.scrollLineNumber;
+ return serializedHistoryItem;
+ }
+}
+
+WebInspector.TabbedEditorContainer.HistoryItem.prototype.__proto__ = WebInspector.Object.prototype;
+
+/**
+ * @constructor
+ * @param {Array.<WebInspector.TabbedEditorContainer.HistoryItem>} items
*/
-WebInspector.TabbedEditorContainer.History = function(urls)
+WebInspector.TabbedEditorContainer.History = function(items)
{
- this._urls = urls;
+ this._items = items;
+}
+
+/**
+ * @param {Object} serializedHistory
+ * @return {WebInspector.TabbedEditorContainer.History}
+ */
+WebInspector.TabbedEditorContainer.History.fromObject = function(serializedHistory)
+{
+ var items = [];
+ for (var i = 0; i < serializedHistory.length; ++i)
+ items.push(WebInspector.TabbedEditorContainer.HistoryItem.fromObject(serializedHistory[i]));
+ return new WebInspector.TabbedEditorContainer.History(items);
}
WebInspector.TabbedEditorContainer.History.prototype = {
/**
* @param {string} url
+ * @return {number}
*/
index: function(url)
{
- return this._urls.indexOf(url);
+ for (var i = 0; i < this._items.length; ++i) {
+ if (this._items[i].url === url)
+ return i;
+ }
+ return -1;
+ },
+
+ /**
+ * @param {string} url
+ * @return {WebInspector.TextRange|undefined}
+ */
+ selectionRange: function(url)
+ {
+ var index = this.index(url);
+ return index !== -1 ? this._items[index].selectionRange : undefined;
+ },
+
+ /**
+ * @param {string} url
+ * @param {WebInspector.TextRange} selectionRange
+ */
+ updateSelectionRange: function(url, selectionRange)
+ {
+ if (!selectionRange)
+ return;
+ var index = this.index(url);
+ if (index === -1)
+ return;
+ this._items[index].selectionRange = selectionRange;
+ },
+
+ /**
+ * @param {string} url
+ * @return {number|undefined}
+ */
+ scrollLineNumber: function(url)
+ {
+ var index = this.index(url);
+ return index !== -1 ? this._items[index].scrollLineNumber : undefined;
+ },
+
+ /**
+ * @param {string} url
+ * @param {number} scrollLineNumber
+ */
+ updateScrollLineNumber: function(url, scrollLineNumber)
+ {
+ var index = this.index(url);
+ if (index === -1)
+ return;
+ this._items[index].scrollLineNumber = scrollLineNumber;
},
/**
update: function(urls)
{
for (var i = urls.length - 1; i >= 0; --i) {
- var index = this._urls.indexOf(urls[i]);
- if (index !== -1)
- this._urls.splice(index, 1);
- this._urls.unshift(urls[i]);
+ var index = this.index(urls[i]);
+ var item;
+ if (index !== -1) {
+ item = this._items[index];
+ this._items.splice(index, 1);
+ } else
+ item = new WebInspector.TabbedEditorContainer.HistoryItem(urls[i]);
+ this._items.unshift(item);
}
},
*/
remove: function(url)
{
- var index = this._urls.indexOf(url);
+ var index = this.index(url);
if (index !== -1)
- this._urls.splice(index, 1);
+ this._items.splice(index, 1);
},
/**
*/
save: function(setting)
{
- setting.set(this._urls);
+ setting.set(this._serializeToObject());
+ },
+
+ /**
+ * @return {Object}
+ */
+ _serializeToObject: function()
+ {
+ var serializedHistory = [];
+ for (var i = 0; i < this._items.length; ++i)
+ serializedHistory.push(this._items[i].serializeToObject());
+ return serializedHistory;
}
}
var syncLineHeightListener = this._syncLineHeight.bind(this);
this._mainPanel = new WebInspector.TextEditorMainPanel(this._textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode);
this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener, syncLineHeightListener);
+
+ this._mainPanel.element.addEventListener("scroll", this._handleScrollChanged.bind(this), false);
+ this._mainPanel._container.addEventListener("focus", this._handleFocused.bind(this), false);
+
this.element.appendChild(this._mainPanel.element);
this.element.appendChild(this._gutterPanel.element);
return true;
},
+ _handleScrollChanged: function(event)
+ {
+ var visibleFrom = this._mainPanel.element.scrollTop;
+ var firstVisibleLineNumber = this._mainPanel._findFirstVisibleLineNumber(visibleFrom);
+ this._delegate.scrollChanged(firstVisibleLineNumber);
+ },
+
+ /**
+ * @param {number} lineNumber
+ */
+ scrollToLine: function(lineNumber)
+ {
+ this._mainPanel.scrollToLine(lineNumber);
+ },
+
+ _handleSelectionChange: function(event)
+ {
+ var textRange = this._mainPanel._getSelection();
+ if (textRange)
+ this._lastSelection = textRange;
+ this._delegate.selectionChanged(textRange);
+ },
+
/**
* @return {WebInspector.TextRange}
*/
*/
setSelection: function(textRange)
{
+ this._lastSelection = textRange;
this._mainPanel._restoreSelection(textRange);
},
{
if (!this.readOnly())
WebInspector.markBeingEdited(this.element, true);
+
+ this._boundSelectionChangeListener = this._handleSelectionChange.bind(this);
+ document.addEventListener("selectionchange", this._boundSelectionChangeListener, false);
+ },
+
+ _handleFocused: function()
+ {
+ if (this._lastSelection) {
+ // We do not restore selection after focus lost to avoid selection blinking. We restore only cursor position instead.
+ // FIXME: consider adding selection decoration to blurred editor.
+ var newSelection = WebInspector.TextRange.createFromLocation(this._lastSelection.endLine, this._lastSelection.endColumn);
+ this.setSelection(newSelection);
+ }
},
willHide: function()
{
+ document.removeEventListener("selectionchange", this._boundSelectionChangeListener, false);
+ delete this._boundSelectionChangeListener;
+
if (!this.readOnly())
WebInspector.markBeingEdited(this.element, false);
}
commitEditing: function() { },
/**
+ * @param {WebInspector.TextRange} textRange
+ */
+ selectionChanged: function(textRange) { },
+
+ /**
+ * @param {number} lineNumber
+ */
+ scrollChanged: function(lineNumber) { },
+
+ /**
* @param {WebInspector.ContextMenu} contextMenu
* @param {number} lineNumber
*/
/**
* @param {number} lineNumber
*/
+ scrollToLine: function(lineNumber)
+ {
+ if (lineNumber >= this._textModel.linesCount)
+ return;
+
+ var chunk = this.makeLineAChunk(lineNumber);
+ this.element.scrollTop = chunk.offsetTop;
+ },
+
+ /**
+ * @param {number} lineNumber
+ */
revealLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return new WebInspector.TextRange(line, column, line, column);
}
+/**
+ * @param {Object} serializedTextRange
+ * @return {WebInspector.TextRange}
+ */
+WebInspector.TextRange.fromObject = function (serializedTextRange)
+{
+ return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn);
+}
+
WebInspector.TextRange.prototype = {
/**
* @return {boolean}
clone: function()
{
return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn);
+ },
+
+ /**
+ * @return {Object}
+ */
+ serializeToObject: function()
+ {
+ var serializedTextRange = {};
+ serializedTextRange.startLine = this.startLine;
+ serializedTextRange.startColumn = this.startColumn;
+ serializedTextRange.endLine = this.endLine;
+ serializedTextRange.endColumn = this.endColumn;
+ return serializedTextRange;
}
}