Bug 254021: Ability to open accidentally closed tabs (r=mconnor)

This commit is contained in:
dietrich%mozilla.com 2006-06-20 07:30:00 +00:00
Родитель 780d129c37
Коммит 8cad9e879f
4 изменённых файлов: 106 добавлений и 27 удалений

Просмотреть файл

@ -1121,6 +1121,9 @@ function delayedStartup()
}
}
}
// browser-specific tab augmentation
AugmentTabs.init();
}
function BrowserShutdown()
@ -6599,3 +6602,57 @@ window.controllers.appendController(BrowserController);
#include ../../../toolkit/content/debug.js
#endif
/**
* This object is for augmenting tabs
*/
var AugmentTabs = {
/**
* Called in delayedStartup
*/
init: function at_init() {
// add the tab context menu for undo-close-tab (bz254021)
var ssEnabled = true;
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
try {
ssEnabled = prefBranch.getBoolPref("browser.sessionstore.enabled");
} catch (ex) {}
if (ssEnabled)
this._addUndoCloseTabContextMenu();
},
/**
* Add undo-close-tab to tab context menu
*/
_addUndoCloseTabContextMenu: function at_addUndoCloseTabContextMenu() {
// get tab context menu
var tabbrowser = getBrowser();
var tabMenu = document.getAnonymousElementByAttribute(tabbrowser,"anonid","tabContextMenu");
// get strings
var menuLabel = gNavigatorBundle.getString("tabContext.undoCloseTab");
var menuAccessKey = gNavigatorBundle.getString("tabContext.undoCloseTabAccessKey");
// create new menu item
var undoCloseTabItem = document.createElement("menuitem");
undoCloseTabItem.setAttribute("label", menuLabel);
undoCloseTabItem.setAttribute("accesskey", menuAccessKey);
undoCloseTabItem.addEventListener("command", this.undoCloseTab, false);
// add to tab context menu
var insertPos = tabMenu.lastChild.previousSibling;
tabMenu.insertBefore(undoCloseTabItem, insertPos);
},
/**
* Re-open the most-recently-closed tab
*/
undoCloseTab: function at_undoCloseTab() {
// get session-store service
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
ss.undoCloseTab(window, 0);
}
};

Просмотреть файл

@ -46,11 +46,19 @@ interface nsIDOMWindow;
* - and allows to restore everything into one window.
*/
[scriptable, uuid(ca4e1d40-ec1b-11da-8ad9-0800200c9a66)]
[scriptable, uuid(38bad250-0021-11db-92e3-0800200c9a66)]
interface nsISessionStore : nsISupports
{
/**
* Initialize the service
*/
void init(in nsIDOMWindow aWindow);
/**
* @param aWindow
* The window to reopen a closed tab in.
* @param aIndex
* Indicates the window to be restored (FIFO ordered).
*/
void undoCloseTab(in nsIDOMWindow aWindow, in unsigned long aIndex);
};

Просмотреть файл

@ -423,7 +423,7 @@ SessionStoreService.prototype = {
tabpanels.addEventListener("select", function(aEvent) {
_this.onTabSelect(aEvent.currentTarget.ownerDocument.defaultView, aEvent.currentTarget);
}, false);
tabbrowser.addEventListener("TabClose", function(aEvent) {
tabbrowser.addEventListener("DOMNodeRemoved", function(aEvent) {
_this.onTabClose(aEvent.currentTarget.ownerDocument.defaultView, aEvent.originalTarget);
}, false);
},
@ -540,12 +540,17 @@ SessionStoreService.prototype = {
this._saveWindowHistory(aWindow);
this._updateTextAndScrollData(aWindow);
this._windows[aWindow.__SSi]._closedTabs.unshift({
state: this._windows[aWindow.__SSi].Tab[aTab._tPos],
title: aTab.getAttribute("label"),
pos: aTab._tPos
});
this._windows[aWindow.__SSi]._closedTabs.splice(this._getPref("sessionstore.max_tabs_undo", DEFAULT_MAX_TABS_UNDO));
// DOMNodeRemoved is received *twice* after closing a tab, only take the first
var tabState = this._windows[aWindow.__SSi].Tab[aTab._tPos];
if (tabState) {
this._windows[aWindow.__SSi]._closedTabs.unshift({
state: tabState,
title: aTab.getAttribute("label"),
pos: aTab._tPos
});
var maxTabsUndo = this._getPref("sessionstore.max_tabs_undo", DEFAULT_MAX_TABS_UNDO);
this._windows[aWindow.__SSi]._closedTabs.splice(maxTabsUndo);
}
},
/**
@ -686,22 +691,30 @@ SessionStoreService.prototype = {
this._windows[aWindow.__SSi]._closedTabs = IniObjectSerializer.decode(aData);
},
undoCloseTab: function sss_undoCloseWindow(aWindow, aIx) {
var tabs = this._windows[aWindow.__SSi]._closedTabs;
if (aIx in tabs) {
var browser = aWindow.getBrowser();
var tabData = tabs.splice(aIx, 1);
tabData._tab = browser.addTab();
// restore the tab's position
browser.moveTabTo(tabData._tab, tabData[0].pos);
undoCloseTab: function sss_undoCloseTab(aWindow, aIndex) {
var closedTabs = this._windows[aWindow.__SSi]._closedTabs;
// restore the tab's state
aWindow.setTimeout(this.restoreHistory_proxy, 0, tabData, 1, 0, 0);
// default to the most-recently closed tab
aIndex = aIndex || 0;
if (aIndex in closedTabs) {
var browser = aWindow.getBrowser();
// fetch the data of closed tab, while removing it from the array
var closedTab = closedTabs.splice(aIndex, 1).shift();
var closedTabState = closedTab.state;
// create a new tab
closedTabState._tab = browser.addTab();
// restore the tab's position
browser.moveTabTo(closedTabState._tab, closedTab.pos);
// restore tab content
this.restoreHistoryPrecursor(aWindow, [closedTabState], 1, 0, 0);
}
else {
Components.returnCode = -1; //zeniko: or should we rather fail silently?
Components.returnCode = Cr.NS_ERROR_INVALID_ARG;
}
},
@ -1196,11 +1209,8 @@ SessionStoreService.prototype = {
}
}
var restoreHistoryFunc = function(self) {
self.restoreHistory_proxy(aWindow, winData.Tab, (aOverwriteTabs ?
this.restoreHistoryPrecursor(aWindow, winData.Tab, (aOverwriteTabs ?
(parseInt(winData.selected) || 1) : 0), 0, 0);
};
aWindow.setTimeout(restoreHistoryFunc, 0, this);
},
/**
@ -1214,7 +1224,7 @@ SessionStoreService.prototype = {
* @param aCount
* Counter for number of times delaying b/c browser or history aren't ready
*/
restoreHistory_proxy: function sss_restoreHistory_proxy(aWindow, aTabs, aSelectTab, aIx, aCount) {
restoreHistoryPrecursor: function sss_restoreHistoryPrecursor(aWindow, aTabs, aSelectTab, aIx, aCount) {
var tabbrowser = aWindow.getBrowser();
// make sure that all browsers and their histories are available
@ -1228,7 +1238,7 @@ SessionStoreService.prototype = {
catch (ex) { // in case browser or history aren't ready yet
if (aCount < 10) {
var restoreHistoryFunc = function(self) {
self.restoreHistory_proxy(aWindow, aTabs, aSelectTab, aIx, aCount + 1);
self.restoreHistoryPrecursor(aWindow, aTabs, aSelectTab, aIx, aCount + 1);
}
aWindow.setTimeout(restoreHistoryFunc, 100, this);
return;

Просмотреть файл

@ -119,3 +119,7 @@ feedHasFeeds=Add Live Bookmark...
feedNoFeeds=Page has no feeds
feedShowFeedNew=Subscribe to '%S'...
feedHasFeedsNew=Subscribe to this page...
# tab context menu additions
tabContext.undoCloseTab=Undo Close Tab
tabContext.undoCloseTabAccessKey=U