mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-12 18:50:08 +00:00
Bug 342700 Make undo close tab more discoverable (r=mconnor, r=gavin)
This commit is contained in:
parent
d6fc93d5fd
commit
159e64a564
@ -363,6 +363,10 @@
|
||||
command="Browser:ShowHistory"/>
|
||||
<menuseparator id="startTabHistorySeparator"/>
|
||||
<menuseparator hidden="true" id="endTabHistorySeparator"/>
|
||||
<menu label="&historyUndoMenu.label;" disabled="true">
|
||||
<menupopup id="historyUndoPopup"/>
|
||||
</menu>
|
||||
<menuseparator id="endUndoSeparator"/>
|
||||
<menuitem id="sanitizeItem"
|
||||
accesskey="&clearPrivateDataCmd.accesskey;"
|
||||
label="&clearPrivateDataCmd.label;"
|
||||
|
@ -1124,6 +1124,9 @@ function delayedStartup()
|
||||
|
||||
// browser-specific tab augmentation
|
||||
AugmentTabs.init();
|
||||
|
||||
// set up history menu
|
||||
HistoryMenu.init();
|
||||
}
|
||||
|
||||
function BrowserShutdown()
|
||||
@ -6716,23 +6719,13 @@ var AugmentTabs = {
|
||||
var undoCloseTabItem = document.createElement("menuitem");
|
||||
undoCloseTabItem.setAttribute("label", menuLabel);
|
||||
undoCloseTabItem.setAttribute("accesskey", menuAccessKey);
|
||||
undoCloseTabItem.addEventListener("command", this.undoCloseTab, false);
|
||||
undoCloseTabItem.addEventListener("command", function() { undoCloseTab(0); }, false);
|
||||
|
||||
// add to tab context menu
|
||||
var insertPos = this.tabContextMenu.lastChild.previousSibling;
|
||||
this.undoCloseTabMenu = this.tabContextMenu.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);
|
||||
},
|
||||
|
||||
onTabContextMenuLoad: function at_onTabContextMenuLoad() {
|
||||
if (AugmentTabs.undoCloseTabMenu) {
|
||||
// only add the menu of there are tabs to restore
|
||||
@ -6742,3 +6735,81 @@ var AugmentTabs = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* History menu initialization
|
||||
*/
|
||||
#ifndef MOZ_PLACES
|
||||
var HistoryMenu = {};
|
||||
#endif
|
||||
|
||||
HistoryMenu.init = function PHM_init() {
|
||||
this.initializeUndoSubmenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the "Undo Close Tabs" menu
|
||||
*/
|
||||
HistoryMenu.initializeUndoSubmenu = function PHM_initializeUndoSubmenu() {
|
||||
// get history menupopup
|
||||
var histMenu = document.getElementById("goPopup");
|
||||
histMenu.addEventListener("popupshowing", function() { HistoryMenu.populateUndoSubmenu(); }, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate when the history menu is opened
|
||||
*/
|
||||
HistoryMenu.populateUndoSubmenu = function PHM_populateUndoSubmenu() {
|
||||
var undoPopup = document.getElementById("historyUndoPopup");
|
||||
|
||||
// remove existing menu items
|
||||
while (undoPopup.hasChildNodes())
|
||||
undoPopup.removeChild(undoPopup.firstChild);
|
||||
|
||||
// get closed-tabs from nsSessionStore
|
||||
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
// no restorable tabs, so make sure menu is disabled, and return
|
||||
if (ss.getClosedTabCount(window) == 0) {
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
return;
|
||||
}
|
||||
|
||||
// enable menu
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
|
||||
// populate menu
|
||||
var urls = [];
|
||||
var undoItems = ss.getClosedTabData(window);
|
||||
var keys = undoItems.getKeys({});
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var tabData = undoItems.getValue(key).wrappedJSObject;
|
||||
var m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.setAttribute("label", tabData.title);
|
||||
m.setAttribute("value", key);
|
||||
m.addEventListener("command", function(aEvent) {
|
||||
undoCloseTab(aEvent.originalTarget.getAttribute("value"));
|
||||
}, false);
|
||||
urls.push(tabData.state.entries[0].url);
|
||||
}
|
||||
|
||||
// "open in tabs"
|
||||
var strings = document.getElementById("placeBundle");
|
||||
undoPopup.appendChild(document.createElement("menuseparator"));
|
||||
m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.setAttribute("label", strings.getString("menuOpenInTabs.label"));
|
||||
m.setAttribute("accesskey", strings.getString("menuOpenInTabs.accesskey"));
|
||||
m.addEventListener("command", function() { loadOneOrMoreURIs(urls.join("|")); }, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-open a closed tab.
|
||||
* @param aIndex
|
||||
* The index of the tab (via nsSessionStore.getClosedTabData)
|
||||
*/
|
||||
function undoCloseTab(aIndex) {
|
||||
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
ss.undoCloseTab(window, aIndex);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
interface nsIDOMWindow;
|
||||
interface nsIDOMNode;
|
||||
interface nsIDictionary;
|
||||
|
||||
/**
|
||||
* nsISessionStore keeps track of the current browsing state - i.e.
|
||||
@ -47,7 +48,7 @@ interface nsIDOMNode;
|
||||
* - and allows to restore everything into one window.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(320996f0-0c5e-11db-9cd8-0800200c9a66)]
|
||||
[scriptable, uuid(f217cde0-0c68-11db-9cd8-0800200c9a66)]
|
||||
interface nsISessionStore : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -60,6 +61,12 @@ interface nsISessionStore : nsISupports
|
||||
*/
|
||||
unsigned long getClosedTabCount(in nsIDOMWindow aWindow);
|
||||
|
||||
/**
|
||||
* Get closed tab data
|
||||
* XXX - This format is not final, and will be updated when a better way is found.
|
||||
*/
|
||||
nsIDictionary getClosedTabData(in nsIDOMWindow aWindow);
|
||||
|
||||
/**
|
||||
* @param aWindow
|
||||
* The window to reopen a closed tab in.
|
||||
|
@ -543,7 +543,9 @@ SessionStoreService.prototype = {
|
||||
pos: aTab._tPos
|
||||
});
|
||||
var maxTabsUndo = this._getPref("sessionstore.max_tabs_undo", DEFAULT_MAX_TABS_UNDO);
|
||||
this._windows[aWindow.__SSi]._closedTabs.splice(maxTabsUndo);
|
||||
var length = this._windows[aWindow.__SSi]._closedTabs.length;
|
||||
if (length > maxTabsUndo)
|
||||
this._windows[aWindow.__SSi]._closedTabs.splice(maxTabsUndo, length - maxTabsUndo);
|
||||
}
|
||||
},
|
||||
|
||||
@ -677,8 +679,22 @@ SessionStoreService.prototype = {
|
||||
return aIx in tabs ? tabs[aIx].title : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns nsIDictionary
|
||||
*/
|
||||
getClosedTabData: function sss_getClosedTabDataAt(aWindow) {
|
||||
return this._windows[aWindow.__SSi]._closedTabs;
|
||||
try {
|
||||
var wrappedData = Cc["@mozilla.org/dictionary;1"].createInstance(Ci.nsIDictionary);
|
||||
var closedTabData = this._windows[aWindow.__SSi]._closedTabs;
|
||||
if (closedTabData.length == 0)
|
||||
return wrappedData;
|
||||
|
||||
// wrap it
|
||||
for (var i = 0; i < closedTabData.length; i++)
|
||||
wrappedData.setValue(i, {wrappedJSObject: closedTabData[i]});
|
||||
|
||||
return wrappedData;
|
||||
} catch(ex) { debug("getClosedTabData: " + ex); }
|
||||
},
|
||||
|
||||
setClosedTabData: function sss_setClosedTabDataAt(aWindow, aData) {
|
||||
@ -690,7 +706,7 @@ SessionStoreService.prototype = {
|
||||
|
||||
// default to the most-recently closed tab
|
||||
aIndex = aIndex || 0;
|
||||
|
||||
|
||||
if (aIndex in closedTabs) {
|
||||
var browser = aWindow.getBrowser();
|
||||
|
||||
|
@ -185,6 +185,9 @@
|
||||
<!-- XXX historyMenu entities are used with or without places (bug 336058) -->
|
||||
<!ENTITY historyMenu.label "History">
|
||||
<!ENTITY historyMenu.accesskey "i">
|
||||
<!ENTITY historyUndoMenu.label "Recently Closed Tabs">
|
||||
<!ENTITY historyUndoMenu.accesskey "u">
|
||||
|
||||
<!-- XXX places only -->
|
||||
<!ENTITY historyHomeCmd.label "Home">
|
||||
<!ENTITY historyHomeCmd.accesskey "h">
|
||||
|
Loading…
x
Reference in New Issue
Block a user