Bug 941540 - Use browser.permanentKey to handle docShell swaps more easily r=yoric

This commit is contained in:
Tim Taubert 2014-01-20 20:50:17 +01:00
parent 50366764fc
commit 1098386144
4 changed files with 14 additions and 98 deletions

View File

@ -712,12 +712,6 @@ let SessionStoreInternal = {
var win = aEvent.currentTarget.ownerDocument.defaultView;
let browser;
switch (aEvent.type) {
case "SwapDocShells":
browser = aEvent.currentTarget;
let otherBrowser = aEvent.detail;
TabState.onBrowserContentsSwapped(browser, otherBrowser);
TabStateCache.onBrowserContentsSwapped(browser, otherBrowser);
break;
case "TabOpen":
this.onTabAdd(win, aEvent.originalTarget);
break;
@ -1297,10 +1291,7 @@ let SessionStoreInternal = {
* bool Do not save state if we're updating an existing tab
*/
onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser;
browser.addEventListener("SwapDocShells", this, true);
let mm = browser.messageManager;
let mm = aTab.linkedBrowser.messageManager;
MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
// Load the frame script after registering listeners.
@ -1324,8 +1315,6 @@ let SessionStoreInternal = {
*/
onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser;
browser.removeEventListener("SwapDocShells", this, true);
let mm = browser.messageManager;
MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));
@ -2602,7 +2591,7 @@ let SessionStoreInternal = {
// message. If a message is received that relates to a previous epoch, we
// discard it.
let epoch = this._nextRestoreEpoch++;
this._browserEpochs.set(browser, epoch);
this._browserEpochs.set(browser.permanentKey, epoch);
// keep the data around to prevent dataloss in case
// a tab gets closed before it's been properly restored
@ -3468,7 +3457,7 @@ let SessionStoreInternal = {
// The browser is no longer in any sort of restoring state.
delete browser.__SS_restoreState;
this._browserEpochs.delete(browser);
this._browserEpochs.delete(browser.permanentKey);
aTab.removeAttribute("pending");
browser.removeAttribute("pending");
@ -3500,7 +3489,7 @@ let SessionStoreInternal = {
* with respect to |browser|.
*/
isCurrentEpoch: function (browser, epoch) {
return this._browserEpochs.get(browser, 0) == epoch;
return this._browserEpochs.get(browser.permanentKey, 0) == epoch;
},
};

View File

@ -20,8 +20,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "TabStateCache",
"resource:///modules/sessionstore/TabStateCache.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TabAttributes",
"resource:///modules/sessionstore/TabAttributes.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Utils",
"resource:///modules/sessionstore/Utils.jsm");
/**
* Module that contains tab state collection methods.
@ -31,10 +29,6 @@ this.TabState = Object.freeze({
TabStateInternal.setSyncHandler(browser, handler);
},
onBrowserContentsSwapped: function (browser, otherBrowser) {
TabStateInternal.onBrowserContentsSwapped(browser, otherBrowser);
},
update: function (browser, data) {
TabStateInternal.update(browser, data);
},
@ -70,8 +64,8 @@ let TabStateInternal = {
* Install the sync handler object from a given tab.
*/
setSyncHandler: function (browser, handler) {
this._syncHandlers.set(browser, handler);
this._latestMessageID.set(browser, 0);
this._syncHandlers.set(browser.permanentKey, handler);
this._latestMessageID.set(browser.permanentKey, 0);
},
/**
@ -81,8 +75,8 @@ let TabStateInternal = {
// Only ever process messages that have an ID higher than the last one we
// saw. This ensures we don't use stale data that has already been received
// synchronously.
if (id > this._latestMessageID.get(browser)) {
this._latestMessageID.set(browser, id);
if (id > this._latestMessageID.get(browser.permanentKey)) {
this._latestMessageID.set(browser.permanentKey, id);
TabStateCache.update(browser, data);
}
},
@ -91,9 +85,9 @@ let TabStateInternal = {
* Flushes all data currently queued in the given browser's content script.
*/
flush: function (browser) {
if (this._syncHandlers.has(browser)) {
let lastID = this._latestMessageID.get(browser);
this._syncHandlers.get(browser).flush(lastID);
if (this._syncHandlers.has(browser.permanentKey)) {
let lastID = this._latestMessageID.get(browser.permanentKey);
this._syncHandlers.get(browser.permanentKey).flush(lastID);
}
},
@ -106,18 +100,6 @@ let TabStateInternal = {
}
},
/**
* When a docshell swap happens, a xul:browser element will be
* associated with a different content-sessionStore.js script
* global. In this case, the sync handler for the element needs to
* be swapped just like the docshell.
*/
onBrowserContentsSwapped: function (browser, otherBrowser) {
// Swap data stored per-browser.
[this._syncHandlers, this._latestMessageID]
.forEach(map => Utils.swapMapEntries(map, browser, otherBrowser));
},
/**
* Collect data related to a single tab, synchronously.
*

View File

@ -6,13 +6,6 @@
this.EXPORTED_SYMBOLS = ["TabStateCache"];
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
XPCOMUtils.defineLazyModuleGetter(this, "Utils",
"resource:///modules/sessionstore/Utils.jsm");
/**
* A cache for tabs data.
*
@ -24,18 +17,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Utils",
* - caching private data in addition to public data is memory consuming.
*/
this.TabStateCache = Object.freeze({
/**
* Swap cached data for two given browsers.
*
* @param {xul:browser} browser
* The first of the two browsers that swapped docShells.
* @param {xul:browser} otherBrowser
* The second of the two browsers that swapped docShells.
*/
onBrowserContentsSwapped: function(browser, otherBrowser) {
TabStateCacheInternal.onBrowserContentsSwapped(browser, otherBrowser);
},
/**
* Retrieves cached data for a given |browser|.
*
@ -64,19 +45,6 @@ this.TabStateCache = Object.freeze({
let TabStateCacheInternal = {
_data: new WeakMap(),
/**
* Swap cached data for two given browsers.
*
* @param {xul:browser} browser
* The first of the two browsers that swapped docShells.
* @param {xul:browser} otherBrowser
* The second of the two browsers that swapped docShells.
*/
onBrowserContentsSwapped: function(browser, otherBrowser) {
// Swap data stored per-browser.
Utils.swapMapEntries(this._data, browser, otherBrowser);
},
/**
* Retrieves cached data for a given |browser|.
*
@ -86,7 +54,7 @@ let TabStateCacheInternal = {
* The cached data stored for the given |browser|.
*/
get: function (browser) {
return this._data.get(browser);
return this._data.get(browser.permanentKey);
},
/**
@ -98,7 +66,7 @@ let TabStateCacheInternal = {
* The new data to be stored for the given |browser|.
*/
update: function (browser, newData) {
let data = this._data.get(browser) || {};
let data = this._data.get(browser.permanentKey) || {};
for (let key of Object.keys(newData)) {
let value = newData[key];
@ -109,6 +77,6 @@ let TabStateCacheInternal = {
}
}
this._data.set(browser, data);
this._data.set(browser.permanentKey, data);
}
};

View File

@ -41,28 +41,5 @@ this.Utils = Object.freeze({
let prevChar = host[index - 1];
return (index == (host.length - domain.length)) &&
(prevChar == "." || prevChar == "/");
},
swapMapEntries: function (map, key, otherKey) {
// Make sure that one or the other of these has an entry in the map,
// and let it be |key|.
if (!map.has(key)) {
[key, otherKey] = [otherKey, key];
if (!map.has(key)) {
return;
}
}
// At this point, |key| is guaranteed to have an entry,
// although |otherKey| may not. Perform the swap.
let value = map.get(key);
if (map.has(otherKey)) {
let otherValue = map.get(otherKey);
map.set(key, otherValue);
map.set(otherKey, value);
} else {
map.set(otherKey, value);
map.delete(key);
}
}
});