Diff
Modified: trunk/LayoutTests/ChangeLog (106237 => 106238)
--- trunk/LayoutTests/ChangeLog 2012-01-30 13:04:28 UTC (rev 106237)
+++ trunk/LayoutTests/ChangeLog 2012-01-30 13:10:24 UTC (rev 106238)
@@ -1,3 +1,13 @@
+2012-01-27 Vsevolod Vlasov <vse...@chromium.org>
+
+ Web Inspector: TabbedEditorContainer should save open tabs.
+ https://bugs.webkit.org/show_bug.cgi?id=76912
+
+ Reviewed by Pavel Feldman.
+
+ * inspector/tabbed-editors-history-expected.txt: Added.
+ * inspector/tabbed-editors-history.html: Added.
+
2012-01-30 Alexander Pavlov <apav...@chromium.org>
Web Inspector: [Styles] Unable to paste and subsequently edit multiple properties in the Styles pane
Added: trunk/LayoutTests/inspector/tabbed-editors-history-expected.txt (0 => 106238)
--- trunk/LayoutTests/inspector/tabbed-editors-history-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/tabbed-editors-history-expected.txt 2012-01-30 13:10:24 UTC (rev 106238)
@@ -0,0 +1,27 @@
+Tests history saving logic in TabbedEditorContainer.
+
+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 = []
+
Property changes on: trunk/LayoutTests/inspector/tabbed-editors-history-expected.txt
___________________________________________________________________
Added: svn:eol-style
Added: trunk/LayoutTests/inspector/tabbed-editors-history.html (0 => 106238)
--- trunk/LayoutTests/inspector/tabbed-editors-history.html (rev 0)
+++ trunk/LayoutTests/inspector/tabbed-editors-history.html 2012-01-30 13:10:24 UTC (rev 106238)
@@ -0,0 +1,70 @@
+<html>
+<head>
+<script src=""
+<script type="text/_javascript_">
+var test = function()
+{
+ function dumpHistory(history)
+ {
+ InspectorTest.addResult(" history = [" + String(history._urls) + "]");
+ }
+
+ function updateAndDump(history, urls)
+ {
+ history.update(urls);
+ dumpHistory(history);
+ }
+
+ function removeAndDump(history, url)
+ {
+ history.remove(url);
+ dumpHistory(history);
+ }
+
+ function url(index)
+ {
+ return "url_" + index;
+ }
+
+ var history = new WebInspector.TabbedEditorContainer.History([]);
+
+ dumpHistory(history);
+ // Emulate opening of several tabs.
+ updateAndDump(history, [url(1)]);
+ updateAndDump(history, [url(2), url(1)]);
+ updateAndDump(history, [url(3), url(2), url(1)]);
+ // Emulate switching between tabs.
+ updateAndDump(history, [url(2), url(3), url(1)]);
+ updateAndDump(history, [url(1), url(2), url(3)]);
+ // Emulate opening of several tabs from another page.
+ updateAndDump(history, [url(11)]);
+ updateAndDump(history, [url(12), url(11)]);
+ updateAndDump(history, [url(13), url(12), url(11)]);
+ // ... and switching between them.
+ updateAndDump(history, [url(12), url(13), url(11)]);
+ updateAndDump(history, [url(11), url(12), url(13)]);
+ // Now close some tabs.
+ removeAndDump(history, url(11));
+ removeAndDump(history, url(13));
+ // Now open some other instead of them.
+ updateAndDump(history, [url(14), url(12)]);
+ updateAndDump(history, [url(15), url(14), url(12)]);
+ updateAndDump(history, [url(16), url(15), url(14), url(12)]);
+ // Close all of them one by one.
+ removeAndDump(history, url(16));
+ removeAndDump(history, url(15));
+ removeAndDump(history, url(14));
+ removeAndDump(history, url(12));
+ removeAndDump(history, url(1));
+ removeAndDump(history, url(2));
+ removeAndDump(history, url(3));
+
+ InspectorTest.completeTest();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests history saving logic in TabbedEditorContainer.</p>
+<a href="" 76912</a>
+</body>
+</html>
Property changes on: trunk/LayoutTests/inspector/tabbed-editors-history.html
___________________________________________________________________
Added: svn:eol-style
Modified: trunk/Source/WebCore/ChangeLog (106237 => 106238)
--- trunk/Source/WebCore/ChangeLog 2012-01-30 13:04:28 UTC (rev 106237)
+++ trunk/Source/WebCore/ChangeLog 2012-01-30 13:10:24 UTC (rev 106238)
@@ -1,3 +1,45 @@
+2012-01-27 Vsevolod Vlasov <vse...@chromium.org>
+
+ Web Inspector: TabbedEditorContainer should save open tabs.
+ https://bugs.webkit.org/show_bug.cgi?id=76912
+
+ Reviewed by Pavel Feldman.
+
+ Test: inspector/tabbed-editors-history.html
+
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel.prototype._uiSourceCodeAdded):
+ (WebInspector.ScriptsPanel.prototype._reset):
+ (WebInspector.ScriptsPanel.prototype._showFile):
+ (WebInspector.ScriptsPanel.prototype._updateExecutionLine):
+ (WebInspector.ScriptsPanel.prototype._editorSelected):
+ (WebInspector.EditorContainer.prototype.uiSourceCodeAdded):
+ (WebInspector.ScriptsPanel.SingleFileEditorContainer.prototype.showFile):
+ (WebInspector.ScriptsPanel.SingleFileEditorContainer.prototype.reset):
+ * inspector/front-end/TabbedEditorContainer.js:
+ (WebInspector.TabbedEditorContainer):
+ (WebInspector.TabbedEditorContainer.prototype.showFile):
+ (WebInspector.TabbedEditorContainer.prototype._editorClosedByUserAction):
+ (WebInspector.TabbedEditorContainer.prototype._editorSelectedByUserAction):
+ (WebInspector.TabbedEditorContainer.prototype._updateHistory.tabIdToURL):
+ (WebInspector.TabbedEditorContainer.prototype._updateHistory):
+ (WebInspector.TabbedEditorContainer.prototype._appendFileTab):
+ (WebInspector.TabbedEditorContainer.prototype._tabClosed):
+ (WebInspector.TabbedEditorContainer.prototype._tabSelected):
+ (WebInspector.TabbedEditorContainer.prototype.reset):
+ (WebInspector.TabbedEditorContainer.History):
+ (WebInspector.TabbedEditorContainer.History.prototype.index):
+ (WebInspector.TabbedEditorContainer.History.prototype.update):
+ (WebInspector.TabbedEditorContainer.History.prototype.remove):
+ (WebInspector.TabbedEditorContainer.History.prototype.save):
+ * inspector/front-end/TabbedPane.js:
+ (WebInspector.TabbedPane.prototype.appendTab):
+ (WebInspector.TabbedPane.prototype.closeTab):
+ (WebInspector.TabbedPane.prototype._innerCloseTab):
+ (WebInspector.TabbedPane.prototype.closeAllTabs):
+ (WebInspector.TabbedPane.prototype.lastOpenedTabIds):
+ (WebInspector.TabbedPane.prototype._tabsSelectChanged):
+
2012-01-30 Alexander Pavlov <apav...@chromium.org>
Web Inspector: [Styles] Unable to paste and subsequently edit multiple properties in the Styles pane
Modified: trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js (106237 => 106238)
--- trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js 2012-01-30 13:04:28 UTC (rev 106237)
+++ trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js 2012-01-30 13:10:24 UTC (rev 106238)
@@ -256,18 +256,7 @@
return;
}
this._fileSelector.addUISourceCode(uiSourceCode);
-
- var lastViewedURL = WebInspector.settings.lastViewedScriptFile.get();
- if (!this._initialViewSelectionProcessed) {
- this._initialViewSelectionProcessed = true;
- // Option we just added is the only option in files select.
- // We have to show corresponding source frame immediately.
- this._showFile(uiSourceCode);
- // Restore original value of lastViewedScriptFile because
- // source frame was shown as a result of initial load.
- WebInspector.settings.lastViewedScriptFile.set(lastViewedURL);
- } else if (uiSourceCode.url ="" lastViewedURL)
- this._showFile(uiSourceCode);
+ this._editorContainer.uiSourceCodeAdded(uiSourceCode);
},
_uiSourceCodeRemoved: function(event)
@@ -415,9 +404,7 @@
this._debuggerResumed();
- delete this._initialViewSelectionProcessed;
delete this._curentUISourceCode;
-
this._editorContainer.reset();
this._updateScriptViewStatusBarItems();
@@ -486,7 +473,7 @@
{
if (!this._fileSelector.isScriptSourceAdded(uiSourceCode))
return null;
-
+
var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
if (this._curentUISourceCode === uiSourceCode)
return sourceFrame;
@@ -496,9 +483,6 @@
this._editorContainer.showFile(uiSourceCode);
this._updateScriptViewStatusBarItems();
- if (uiSourceCode.url)
- WebInspector.settings.lastViewedScriptFile.set(uiSourceCode.url);
-
return sourceFrame;
},
@@ -617,7 +601,7 @@
// Anonymous scripts are not added to files select by default.
this._fileSelector.addUISourceCode(uiLocation.uiSourceCode);
-
+
var sourceFrame = this._showFile(uiLocation.uiSourceCode);
sourceFrame.setExecutionLine(uiLocation.lineNumber);
this._executionSourceFrame = sourceFrame;
@@ -1112,6 +1096,11 @@
setFileIsDirty: function(uiSourceCode, isDirty) { },
/**
+ * @param {WebInspector.UISourceCode} uiSourceCode
+ */
+ uiSourceCodeAdded: function(uiSourceCode) { },
+
+ /**
* @param {Array.<WebInspector.UISourceCode>} oldUISourceCodeList
* @param {Array.<WebInspector.UISourceCode>} uiSourceCodeList
*/
@@ -1529,18 +1518,49 @@
if (this._currentSourceFrame === sourceFrame)
return;
+ this._innerShowFile(uiSourceCode, true);
+ },
+
+ /**
+ * @param {WebInspector.UISourceCode} uiSourceCode
+ * @param {boolean} userGesture
+ */
+ _innerShowFile: function(uiSourceCode, userGesture)
+ {
if (this._currentSourceFrame)
this._currentSourceFrame.detach();
+ this._initialViewSelectionProcessed = true;
+
+ var sourceFrame = this._delegate.viewForFile(uiSourceCode);
this._currentSourceFrame = sourceFrame;
this._currentFile = uiSourceCode;
+
+ if (userGesture) {
+ this._userSelectedFiles = true;
+ WebInspector.settings.lastViewedScriptFile.set(uiSourceCode.url);
+ }
if (sourceFrame)
sourceFrame.show(this.element);
+ this.dispatchEventToListeners(WebInspector.EditorContainer.Events.EditorSelected, uiSourceCode);
},
/**
* @param {WebInspector.UISourceCode} uiSourceCode
+ */
+ uiSourceCodeAdded: function(uiSourceCode)
+ {
+ var lastViewedURL = WebInspector.settings.lastViewedScriptFile.get();
+ // Show first file that was added or file with the last viewed url.
+ if (this._userSelectedFiles)
+ return;
+ if (uiSourceCode.url ="" lastViewedURL || !this._initialViewSelectionProcessed)
+ this._innerShowFile(uiSourceCode, false);
+ },
+
+ /**
+ * @param {WebInspector.UISourceCode} uiSourceCode
* @param {boolean} isDirty
*/
setFileIsDirty: function(uiSourceCode, isDirty)
@@ -1564,6 +1584,8 @@
this._currentSourceFrame.detach();
this._currentSourceFrame = null;
this._currentFile = null;
+ delete this._initialViewSelectionProcessed;
+ delete this._userSelectedFiles;
}
}
Modified: trunk/Source/WebCore/inspector/front-end/TabbedEditorContainer.js (106237 => 106238)
--- trunk/Source/WebCore/inspector/front-end/TabbedEditorContainer.js 2012-01-30 13:04:28 UTC (rev 106237)
+++ trunk/Source/WebCore/inspector/front-end/TabbedEditorContainer.js 2012-01-30 13:10:24 UTC (rev 106238)
@@ -43,12 +43,18 @@
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
- this._tabIds = new Map();
+ this._tabIds = new Map();
this._files = {};
+ this._loadedURLs = {};
+
+ this._previouslyViewedFilesSetting = WebInspector.settings.createSetting("previouslyViewedFiles", []);
+ this._history = new WebInspector.TabbedEditorContainer.History(this._previouslyViewedFilesSetting.get());
}
WebInspector.TabbedEditorContainer._tabId = 0;
+WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount = 30;
+
WebInspector.TabbedEditorContainer.prototype = {
/**
* @type {WebInspector.SourceFrame}
@@ -71,12 +77,26 @@
*/
showFile: function(uiSourceCode)
{
+ this._innerShowFile(uiSourceCode, true);
+ },
+
+ /**
+ * @param {WebInspector.UISourceCode} uiSourceCode
+ * @param {boolean=} userGesture
+ */
+ _innerShowFile: function(uiSourceCode, userGesture)
+ {
if (this._currentFile === uiSourceCode)
return;
+ this._currentFile = uiSourceCode;
- this._currentFile = uiSourceCode;
- var tabId = this._tabIds.get(uiSourceCode) || this._appendFileTab(uiSourceCode);
- this._tabbedPane.selectTab(tabId);
+ var tabId = this._tabIds.get(uiSourceCode) || this._appendFileTab(uiSourceCode, userGesture);
+
+ this._tabbedPane.selectTab(tabId, userGesture);
+ if (userGesture)
+ this._editorSelectedByUserAction();
+
+ this.dispatchEventToListeners(WebInspector.EditorContainer.Events.EditorSelected, this._currentFile);
},
/**
@@ -90,6 +110,55 @@
/**
* @param {WebInspector.UISourceCode} uiSourceCode
+ */
+ uiSourceCodeAdded: function(uiSourceCode)
+ {
+ if (this._userSelectedFiles || this._loadedURLs[uiSourceCode.url])
+ return;
+ this._loadedURLs[uiSourceCode.url] = true;
+
+ var index = this._history.index(uiSourceCode.url)
+ if (index === -1)
+ return;
+
+ var tabId = this._tabIds.get(uiSourceCode) || this._appendFileTab(uiSourceCode, false);
+
+ // Select tab if this file was the last to be shown.
+ if (index === 0)
+ this._innerShowFile(uiSourceCode, false);
+ },
+
+ /**
+ * @param {WebInspector.UISourceCode} uiSourceCode
+ */
+ _editorClosedByUserAction: function(uiSourceCode)
+ {
+ this._userSelectedFiles = true;
+ this._history.remove(uiSourceCode.url);
+ this._updateHistory();
+ },
+
+ _editorSelectedByUserAction: function()
+ {
+ this._userSelectedFiles = true;
+ this._updateHistory();
+ },
+
+ _updateHistory: function()
+ {
+ var tabIds = this._tabbedPane.lastOpenedTabIds(WebInspector.TabbedEditorContainer.maximalPreviouslyViewedFilesCount);
+
+ function tabIdToURL(tabId)
+ {
+ return this._files[tabId].url;
+ }
+
+ this._history.update(tabIds.map(tabIdToURL.bind(this)));
+ this._history.save(this._previouslyViewedFilesSetting);
+ },
+
+ /**
+ * @param {WebInspector.UISourceCode} uiSourceCode
* @return {string}
*/
_tooltipForFile: function(uiSourceCode)
@@ -99,8 +168,9 @@
/**
* @param {WebInspector.UISourceCode} uiSourceCode
+ * @param {boolean=} userGesture
*/
- _appendFileTab: function(uiSourceCode)
+ _appendFileTab: function(uiSourceCode, userGesture)
{
var view = this._delegate.viewForFile(uiSourceCode);
var title = this._titleForFile(uiSourceCode);
@@ -110,7 +180,7 @@
this._tabIds.put(uiSourceCode, tabId);
this._files[tabId] = uiSourceCode;
- this._tabbedPane.appendTab(tabId, title, view, tooltip);
+ this._tabbedPane.appendTab(tabId, title, view, tooltip, userGesture);
return tabId;
},
@@ -131,12 +201,16 @@
_tabClosed: function(event)
{
var tabId = /** @type {string} */ event.data.tabId;
+ var userGesture = /** @type {boolean} */ event.data.isUserGesture;
var uiSourceCode = this._files[tabId];
this._tabIds.remove(uiSourceCode);
delete this._files[tabId];
- this.dispatchEventToListeners(WebInspector.ScriptsPanel.EditorContainer.Events.EditorClosed, uiSourceCode);
+ this.dispatchEventToListeners(WebInspector.EditorContainer.Events.EditorClosed, uiSourceCode);
+
+ if (userGesture)
+ this._editorClosedByUserAction(uiSourceCode);
},
/**
@@ -145,11 +219,10 @@
_tabSelected: function(event)
{
var tabId = /** @type {string} */ event.data.tabId;
+ var userGesture = /** @type {boolean} */ event.data.isUserGesture;
+
var uiSourceCode = this._files[tabId];
-
- if (this._currentFile === uiSourceCode)
- return;
- this.dispatchEventToListeners(WebInspector.EditorContainer.Events.EditorSelected, uiSourceCode);
+ this._innerShowFile(uiSourceCode, userGesture);
},
/**
@@ -217,6 +290,8 @@
this._tabIds = new Map();
this._files = {};
delete this._currentFile;
+ delete this._userSelectedFiles;
+ this._loadedURLs = {};
},
/**
@@ -229,3 +304,54 @@
}
WebInspector.TabbedEditorContainer.prototype.__proto__ = WebInspector.Object.prototype;
+
+/**
+ * @constructor
+ */
+WebInspector.TabbedEditorContainer.History = function(urls)
+{
+ this._urls = urls;
+}
+
+WebInspector.TabbedEditorContainer.History.prototype = {
+ /**
+ * @param {string} url
+ */
+ index: function(url)
+ {
+ return this._urls.indexOf(url);
+ },
+
+ /**
+ * @param {Array.<string>} urls
+ */
+ 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]);
+ }
+ },
+
+ /**
+ * @param {string} url
+ */
+ remove: function(url)
+ {
+ var index = this._urls.indexOf(url);
+ if (index !== -1)
+ this._urls.splice(index, 1);
+ },
+
+ /**
+ * @param {WebInspector.Setting} setting
+ */
+ save: function(setting)
+ {
+ setting.set(this._urls);
+ }
+}
+
+WebInspector.TabbedEditorContainer.History.prototype.__proto__ = WebInspector.Object.prototype;
Modified: trunk/Source/WebCore/inspector/front-end/TabbedPane.js (106237 => 106238)
--- trunk/Source/WebCore/inspector/front-end/TabbedPane.js 2012-01-30 13:04:28 UTC (rev 106237)
+++ trunk/Source/WebCore/inspector/front-end/TabbedPane.js 2012-01-30 13:10:24 UTC (rev 106238)
@@ -91,14 +91,19 @@
* @param {string} tabTitle
* @param {WebInspector.View} view
* @param {string=} tabTooltip
+ * @param {boolean=} userGesture
*/
- appendTab: function(id, tabTitle, view, tabTooltip)
+ appendTab: function(id, tabTitle, view, tabTooltip, userGesture)
{
var tab = new WebInspector.TabbedPaneTab(this, this._tabsElement, id, tabTitle, this._closeableTabs, view, tabTooltip);
+ this._tabsById[id] = tab;
this._tabs.push(tab);
- this._tabsById[id] = tab;
this._tabsHistory.push(tab);
+
+ if (this._tabsHistory[0] === tab)
+ this.selectTab(tab.id, userGesture);
+
this._updateTabElements();
},
@@ -108,6 +113,20 @@
*/
closeTab: function(id, userGesture)
{
+ this._innerCloseTab(id, userGesture);
+
+ if (this._tabsHistory.length)
+ this.selectTab(this._tabsHistory[0].id, userGesture);
+ else
+ this._updateTabElements();
+ },
+
+ /**
+ * @param {string} id
+ * @param {boolean=} userGesture
+ */
+ _innerCloseTab: function(id, userGesture)
+ {
if (this._currentTab && this._currentTab.id === id)
this._hideCurrentTab();
@@ -119,21 +138,20 @@
if (tab.shown)
this._hideTabElement(tab);
- if (this._tabsHistory.length)
- this.selectTab(this._tabsHistory[0].id);
- else
- this._updateTabElements();
-
var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed, eventData);
return true;
},
- closeAllTabs: function()
+ /**
+ * @param {boolean=} userGesture
+ */
+ closeAllTabs: function(userGesture)
{
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i)
- this.closeTab(tabs[i].id, false);
+ this._innerCloseTab(tabs[i].id, userGesture);
+ this._updateTabElements();
},
/**
@@ -163,6 +181,19 @@
},
/**
+ * @param {number} tabsCount
+ * @return {Array.<string>}
+ */
+ lastOpenedTabIds: function(tabsCount)
+ {
+ function tabToTabId(tab) {
+ return tab.id;
+ }
+
+ return this._tabsHistory.slice(0, tabsCount).map(tabToTabId);
+ },
+
+ /**
* @param {string} id
* @param {string} tabTitle
*/
@@ -296,7 +327,7 @@
{
var options = this._tabsSelect.options;
var selectedOption = options[this._tabsSelect.selectedIndex];
- this.selectTab(selectedOption.tab.id);
+ this.selectTab(selectedOption.tab.id, true);
},
_measureDropDownButton: function()