mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 1148505, remove cpow usage from back-forward menu by using sessionstore data, r=dao,billm
This commit is contained in:
parent
ccba1d71a6
commit
4ca387549d
@ -1831,7 +1831,8 @@ function gotoHistoryIndex(aEvent) {
|
||||
}
|
||||
// Modified click. Go there in a new tab/window.
|
||||
|
||||
duplicateTabIn(gBrowser.selectedTab, where, index - gBrowser.sessionHistory.index);
|
||||
let historyindex = aEvent.target.getAttribute("historyindex");
|
||||
duplicateTabIn(gBrowser.selectedTab, where, Number(historyindex));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3753,66 +3754,108 @@ function FillHistoryMenu(aParent) {
|
||||
}
|
||||
|
||||
// Remove old entries if any
|
||||
var children = aParent.childNodes;
|
||||
let children = aParent.childNodes;
|
||||
for (var i = children.length - 1; i >= 0; --i) {
|
||||
if (children[i].hasAttribute("index"))
|
||||
aParent.removeChild(children[i]);
|
||||
}
|
||||
|
||||
var webNav = gBrowser.webNavigation;
|
||||
var sessionHistory = webNav.sessionHistory;
|
||||
const MAX_HISTORY_MENU_ITEMS = 15;
|
||||
|
||||
var count = sessionHistory.count;
|
||||
if (count <= 1) // don't display the popup for a single item
|
||||
const tooltipBack = gNavigatorBundle.getString("tabHistory.goBack");
|
||||
const tooltipCurrent = gNavigatorBundle.getString("tabHistory.current");
|
||||
const tooltipForward = gNavigatorBundle.getString("tabHistory.goForward");
|
||||
|
||||
function updateSessionHistory(sessionHistory, initial)
|
||||
{
|
||||
let count = sessionHistory.entries.length;
|
||||
|
||||
if (!initial) {
|
||||
if (count <= 1) {
|
||||
// if there is only one entry now, close the popup.
|
||||
aParent.hidePopup();
|
||||
return;
|
||||
} else if (!aParent.parentNode.open) {
|
||||
// if the popup wasn't open before, but now needs to be, reopen the menu.
|
||||
// It should trigger FillHistoryMenu again.
|
||||
aParent.parentNode.open = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let index = sessionHistory.index;
|
||||
let half_length = Math.floor(MAX_HISTORY_MENU_ITEMS / 2);
|
||||
let start = Math.max(index - half_length, 0);
|
||||
let end = Math.min(start == 0 ? MAX_HISTORY_MENU_ITEMS : index + half_length + 1, count);
|
||||
if (end == count) {
|
||||
start = Math.max(count - MAX_HISTORY_MENU_ITEMS, 0);
|
||||
}
|
||||
|
||||
let existingIndex = 0;
|
||||
|
||||
for (let j = end - 1; j >= start; j--) {
|
||||
let entry = sessionHistory.entries[j];
|
||||
let uri = entry.url;
|
||||
|
||||
let item = existingIndex < children.length ?
|
||||
children[existingIndex] : document.createElement("menuitem");
|
||||
|
||||
let entryURI = BrowserUtils.makeURI(entry.url, entry.charset, null);
|
||||
item.setAttribute("uri", uri);
|
||||
item.setAttribute("label", entry.title || uri);
|
||||
item.setAttribute("index", j);
|
||||
|
||||
// Cache this so that gotoHistoryIndex doesn't need the original index
|
||||
item.setAttribute("historyindex", j - index);
|
||||
|
||||
if (j != index) {
|
||||
PlacesUtils.favicons.getFaviconURLForPage(entryURI, function (aURI) {
|
||||
if (aURI) {
|
||||
let iconURL = PlacesUtils.favicons.getFaviconLinkForIcon(aURI).spec;
|
||||
iconURL = PlacesUtils.getImageURLForResolution(window, iconURL);
|
||||
item.style.listStyleImage = "url(" + iconURL + ")";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (j < index) {
|
||||
item.className = "unified-nav-back menuitem-iconic menuitem-with-favicon";
|
||||
item.setAttribute("tooltiptext", tooltipBack);
|
||||
} else if (j == index) {
|
||||
item.setAttribute("type", "radio");
|
||||
item.setAttribute("checked", "true");
|
||||
item.className = "unified-nav-current";
|
||||
item.setAttribute("tooltiptext", tooltipCurrent);
|
||||
} else {
|
||||
item.className = "unified-nav-forward menuitem-iconic menuitem-with-favicon";
|
||||
item.setAttribute("tooltiptext", tooltipForward);
|
||||
}
|
||||
|
||||
if (!item.parentNode) {
|
||||
aParent.appendChild(item);
|
||||
}
|
||||
|
||||
existingIndex++;
|
||||
}
|
||||
|
||||
if (!initial) {
|
||||
let existingLength = children.length;
|
||||
while (existingIndex < existingLength) {
|
||||
aParent.removeChild(aParent.lastChild);
|
||||
existingIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sessionHistory = SessionStore.getSessionHistory(gBrowser.selectedTab, updateSessionHistory);
|
||||
if (!sessionHistory)
|
||||
return false;
|
||||
|
||||
const MAX_HISTORY_MENU_ITEMS = 15;
|
||||
var index = sessionHistory.index;
|
||||
var half_length = Math.floor(MAX_HISTORY_MENU_ITEMS / 2);
|
||||
var start = Math.max(index - half_length, 0);
|
||||
var end = Math.min(start == 0 ? MAX_HISTORY_MENU_ITEMS : index + half_length + 1, count);
|
||||
if (end == count)
|
||||
start = Math.max(count - MAX_HISTORY_MENU_ITEMS, 0);
|
||||
// don't display the popup for a single item
|
||||
if (sessionHistory.entries.length <= 1)
|
||||
return false;
|
||||
|
||||
var tooltipBack = gNavigatorBundle.getString("tabHistory.goBack");
|
||||
var tooltipCurrent = gNavigatorBundle.getString("tabHistory.current");
|
||||
var tooltipForward = gNavigatorBundle.getString("tabHistory.goForward");
|
||||
|
||||
for (var j = end - 1; j >= start; j--) {
|
||||
let item = document.createElement("menuitem");
|
||||
let entry = sessionHistory.getEntryAtIndex(j, false);
|
||||
let uri = entry.URI.spec;
|
||||
let entryURI = BrowserUtils.makeURIFromCPOW(entry.URI);
|
||||
|
||||
item.setAttribute("uri", uri);
|
||||
item.setAttribute("label", entry.title || uri);
|
||||
item.setAttribute("index", j);
|
||||
|
||||
if (j != index) {
|
||||
PlacesUtils.favicons.getFaviconURLForPage(entryURI, function (aURI) {
|
||||
if (aURI) {
|
||||
let iconURL = PlacesUtils.favicons.getFaviconLinkForIcon(aURI).spec;
|
||||
iconURL = PlacesUtils.getImageURLForResolution(window, iconURL);
|
||||
item.style.listStyleImage = "url(" + iconURL + ")";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (j < index) {
|
||||
item.className = "unified-nav-back menuitem-iconic menuitem-with-favicon";
|
||||
item.setAttribute("tooltiptext", tooltipBack);
|
||||
} else if (j == index) {
|
||||
item.setAttribute("type", "radio");
|
||||
item.setAttribute("checked", "true");
|
||||
item.className = "unified-nav-current";
|
||||
item.setAttribute("tooltiptext", tooltipCurrent);
|
||||
} else {
|
||||
item.className = "unified-nav-forward menuitem-iconic menuitem-with-favicon";
|
||||
item.setAttribute("tooltiptext", tooltipForward);
|
||||
}
|
||||
|
||||
aParent.appendChild(item);
|
||||
}
|
||||
updateSessionHistory(sessionHistory, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,21 @@ add_task(function* () {
|
||||
|
||||
ok(true, "history menu opened");
|
||||
|
||||
// Wait for the session data to be flushed before continuing the test
|
||||
yield new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve));
|
||||
|
||||
is(event.target.children.length, 2, "Two history items");
|
||||
|
||||
let node = event.target.firstChild;
|
||||
is(node.getAttribute("uri"), "http://example.com/2.html", "first item uri");
|
||||
is(node.getAttribute("index"), "1", "first item index");
|
||||
is(node.getAttribute("historyindex"), "0", "first item historyindex");
|
||||
|
||||
node = event.target.lastChild;
|
||||
is(node.getAttribute("uri"), "http://example.com/", "second item uri");
|
||||
is(node.getAttribute("index"), "0", "second item index");
|
||||
is(node.getAttribute("historyindex"), "-1", "second item historyindex");
|
||||
|
||||
event.target.hidePopup();
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
@ -123,6 +123,8 @@ let SessionHistoryInternal = {
|
||||
entry.subframe = true;
|
||||
}
|
||||
|
||||
entry.charset = shEntry.URI.originCharset;
|
||||
|
||||
let cacheKey = shEntry.cacheKey;
|
||||
if (cacheKey && cacheKey instanceof Ci.nsISupportsPRUint32 &&
|
||||
cacheKey.data != 0) {
|
||||
@ -289,7 +291,7 @@ let SessionHistoryInternal = {
|
||||
var shEntry = Cc["@mozilla.org/browser/session-history-entry;1"].
|
||||
createInstance(Ci.nsISHEntry);
|
||||
|
||||
shEntry.setURI(Utils.makeURI(entry.url));
|
||||
shEntry.setURI(Utils.makeURI(entry.url, entry.charset));
|
||||
shEntry.setTitle(entry.title || entry.url);
|
||||
if (entry.subframe)
|
||||
shEntry.setIsSubFrame(entry.subframe || false);
|
||||
|
@ -312,6 +312,10 @@ this.SessionStore = {
|
||||
|
||||
navigateAndRestore(tab, loadArguments, historyIndex) {
|
||||
return SessionStoreInternal.navigateAndRestore(tab, loadArguments, historyIndex);
|
||||
},
|
||||
|
||||
getSessionHistory(tab, updatedCallback) {
|
||||
return SessionStoreInternal.getSessionHistory(tab, updatedCallback);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2262,6 +2266,34 @@ let SessionStoreInternal = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the latest session history information for a tab. The cached data
|
||||
* is returned immediately, but a callback may be provided that supplies
|
||||
* up-to-date data when or if it is available. The callback is passed a single
|
||||
* argument with data in the same format as the return value.
|
||||
*
|
||||
* @param tab tab to retrieve the session history for
|
||||
* @param updatedCallback function to call with updated data as the single argument
|
||||
* @returns a object containing 'index' specifying the current index, and an
|
||||
* array 'entries' containing an object for each history item.
|
||||
*/
|
||||
getSessionHistory(tab, updatedCallback) {
|
||||
if (updatedCallback) {
|
||||
TabStateFlusher.flush(tab.linkedBrowser).then(() => {
|
||||
let sessionHistory = this.getSessionHistory(tab);
|
||||
if (sessionHistory) {
|
||||
updatedCallback(sessionHistory);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Don't continue if the tab was closed before TabStateFlusher.flush resolves.
|
||||
if (tab.linkedBrowser) {
|
||||
let tabState = TabState.collect(tab);
|
||||
return { index: tabState.index - 1, entries: tabState.entries }
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* See if aWindow is usable for use when restoring a previous session via
|
||||
* restoreLastSession. If usable, prepare it for use.
|
||||
|
Loading…
Reference in New Issue
Block a user