Bug 407162 - "Refactor SessionStore so that it could retrieve data for a single tab" [p=zeniko@gmail.com (Simon B��nzli) r=dietrich a1.9=mconnor]

This commit is contained in:
reed%reedloden.com 2007-12-11 11:01:48 +00:00
Родитель 98ba9d0e15
Коммит 8226ceaa2a
1 изменённых файлов: 149 добавлений и 123 удалений

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

@ -547,13 +547,11 @@ SessionStoreService.prototype = {
}
// make sure that the tab related data is up-to-date
this._saveWindowHistory(aWindow);
this._updateTextAndScrollData(aWindow);
var tabState = this._collectTabData(aTab);
this._updateTextAndScrollDataForTab(aWindow, aTab.linkedBrowser, tabState);
// store closed-tab data for undo
var tabState = this._windows[aWindow.__SSi].tabs[aTab._tPos];
if (tabState && (tabState.entries.length > 1 ||
tabState.entries[0].url != "about:blank")) {
if (tabState.entries.length > 1 || tabState.entries[0].url != "about:blank") {
this._windows[aWindow.__SSi]._closedTabs.unshift({
state: tabState,
title: aTab.getAttribute("label"),
@ -787,80 +785,81 @@ SessionStoreService.prototype = {
*/
_saveWindowHistory: function sss_saveWindowHistory(aWindow) {
var tabbrowser = aWindow.getBrowser();
var browsers = tabbrowser.browsers;
var tabs = this._windows[aWindow.__SSi].tabs = [];
this._windows[aWindow.__SSi].selected = 0;
var tabs = tabbrowser.mTabs;
var tabsData = this._windows[aWindow.__SSi].tabs = [];
for (var i = 0; i < browsers.length; i++) {
var tabData = { entries: [], index: 0 };
var browser = browsers[i];
if (!browser || !browser.currentURI) {
// can happen when calling this function right after .addTab()
tabs.push(tabData);
continue;
}
else if (browser.parentNode.__SS_data && browser.parentNode.__SS_data._tab) {
// use the data to be restored when the tab hasn't been completely loaded
tabs.push(browser.parentNode.__SS_data);
continue;
}
for (var i = 0; i < tabs.length; i++)
tabsData.push(this._collectTabData(tabs[i]));
this._windows[aWindow.__SSi].selected = tabbrowser.mTabBox.selectedIndex + 1;
},
var history = null;
try {
history = browser.sessionHistory;
}
catch (ex) { } // this could happen if we catch a tab during (de)initialization
if (history && browser.parentNode.__SS_data && browser.parentNode.__SS_data.entries[history.index]) {
tabData = browser.parentNode.__SS_data;
tabData.index = history.index + 1;
}
else if (history && history.count > 0) {
for (var j = 0; j < history.count; j++) {
tabData.entries.push(this._serializeHistoryEntry(history.getEntryAtIndex(j, false)));
}
tabData.index = history.index + 1;
browser.parentNode.__SS_data = tabData;
}
else {
tabData.entries[0] = { url: browser.currentURI.spec };
tabData.index = 1;
}
tabData.zoom = browser.markupDocumentViewer.textZoom;
var disallow = [];
for (let i = 0; i < CAPABILITIES.length; i++) {
if (!browser.docShell["allow" + CAPABILITIES[i]])
disallow.push(CAPABILITIES[i]);
}
if (disallow.length != 0)
tabData.disallow = disallow.join(",");
else if (tabData.disallow)
delete tabData.disallow;
if (this.xulAttributes.length != 0) {
var xulattr = Array.filter(tabbrowser.mTabs[i].attributes, function(aAttr) {
return (this.xulAttributes.indexOf(aAttr.name) > -1);
}, this).map(function(aAttr) {
return aAttr.name + "=" + encodeURI(aAttr.value);
});
tabData.xultab = xulattr.join(" ");
}
if (tabbrowser.mTabs[i].__SS_extdata)
tabData.extData = tabbrowser.mTabs[i].__SS_extdata;
else if (tabData.extData)
delete tabData.extData;
tabs.push(tabData);
if (browser == tabbrowser.selectedBrowser) {
this._windows[aWindow.__SSi].selected = i + 1;
}
/**
* Collect data related to a single tab
* @param aTab
* tabbrowser tab
* @returns object
*/
_collectTabData: function sss_collectTabData(aTab) {
var tabData = { entries: [], index: 0 };
var browser = aTab.linkedBrowser;
if (!browser || !browser.currentURI)
// can happen when calling this function right after .addTab()
return tabData;
else if (browser.parentNode.__SS_data && browser.parentNode.__SS_data._tab)
// use the data to be restored when the tab hasn't been completely loaded
return browser.parentNode.__SS_data;
var history = null;
try {
history = browser.sessionHistory;
}
catch (ex) { } // this could happen if we catch a tab during (de)initialization
if (history && browser.parentNode.__SS_data &&
browser.parentNode.__SS_data.entries[history.index]) {
tabData = browser.parentNode.__SS_data;
tabData.index = history.index + 1;
}
else if (history && history.count > 0) {
for (var j = 0; j < history.count; j++)
tabData.entries.push(this._serializeHistoryEntry(history.getEntryAtIndex(j, false)));
tabData.index = history.index + 1;
browser.parentNode.__SS_data = tabData;
}
else {
tabData.entries[0] = { url: browser.currentURI.spec };
tabData.index = 1;
}
tabData.zoom = browser.markupDocumentViewer.textZoom;
var disallow = [];
for (var i = 0; i < CAPABILITIES.length; i++)
if (!browser.docShell["allow" + CAPABILITIES[i]])
disallow.push(CAPABILITIES[i]);
if (disallow.length > 0)
tabData.disallow = disallow.join(",");
else if (tabData.disallow)
delete tabData.disallow;
if (this.xulAttributes.length > 0) {
var xulattr = Array.filter(aTab.attributes, function(aAttr) {
return this.xulAttributes.indexOf(aAttr.name) > -1;
}, this).map(function(aAttr) {
return aAttr.name + "=" + encodeURI(aAttr.value);
});
tabData.xultab = xulattr.join(" ");
}
if (aTab.__SS_extdata)
tabData.extData = aTab.__SS_extdata;
else if (tabData.extData)
delete tabData.extData;
return tabData;
},
/**
@ -1019,64 +1018,91 @@ SessionStoreService.prototype = {
},
/**
* go through all frames and store the current scroll positions
* go through all tabs and store the current scroll positions
* and innerHTML content of WYSIWYG editors
* @param aWindow
* Window reference
*/
_updateTextAndScrollData: function sss_updateTextAndScrollData(aWindow) {
var _this = this;
function updateRecursively(aContent, aData) {
for (var i = 0; i < aContent.frames.length; i++) {
if (aData.children && aData.children[i]) {
updateRecursively(aContent.frames[i], aData.children[i]);
}
}
// designMode is undefined e.g. for XUL documents (as about:config)
var isHTTPS = _this._getURIFromString((aContent.parent || aContent).
document.location.href).schemeIs("https");
if ((aContent.document.designMode || "") == "on" && _this._checkPrivacyLevel(isHTTPS)) {
if (aData.innerHTML == undefined) {
// we get no "input" events from iframes - listen for keypress here
aContent.addEventListener("keypress", function(aEvent) { _this.saveStateDelayed(aWindow, 3000); }, true);
}
aData.innerHTML = aContent.document.body.innerHTML;
}
aData.scroll = aContent.scrollX + "," + aContent.scrollY;
}
Array.forEach(aWindow.getBrowser().browsers, function(aBrowser, aIx) {
var browsers = aWindow.getBrowser().browsers;
for (var i = 0; i < browsers.length; i++) {
try {
var tabData = this._windows[aWindow.__SSi].tabs[aIx];
var tabData = this._windows[aWindow.__SSi].tabs[i];
if (tabData.entries.length == 0 ||
aBrowser.parentNode.__SS_data && aBrowser.parentNode.__SS_data._tab)
return; // ignore incompletely initialized tabs
var text = [];
if (aBrowser.parentNode.__SS_text && this._checkPrivacyLevel(aBrowser.currentURI.schemeIs("https"))) {
for (var ix = aBrowser.parentNode.__SS_text.length - 1; ix >= 0; ix--) {
var data = aBrowser.parentNode.__SS_text[ix];
if (!data.cache) {
// update the text element's value before adding it to the data structure
data.cache = encodeURI(data.element.value);
}
text.push(data.id + "=" + data.cache);
}
}
if (aBrowser.currentURI.spec == "about:config") {
text = ["#textbox=" + encodeURI(aBrowser.contentDocument.getElementById("textbox").wrappedJSObject.value)];
}
if (text.length != 0)
tabData.text = text.join(" ");
else if (tabData.text)
delete tabData.text;
updateRecursively(aBrowser.contentWindow, tabData.entries[tabData.index - 1]);
browsers[i].parentNode.__SS_data && browsers[i].parentNode.__SS_data._tab)
continue; // ignore incompletely initialized tabs
this._updateTextAndScrollDataForTab(aWindow, browsers[i], tabData);
}
catch (ex) { debug(ex); } // get as much data as possible, ignore failures (might succeed the next time)
}, this);
}
},
/**
* go through all frames and store the current scroll positions
* and innerHTML content of WYSIWYG editors
* @param aWindow
* Window reference
* @param aBrowser
* single browser reference
* @param aTabData
* tabData object to add the information to
*/
_updateTextAndScrollDataForTab:
function sss_updateTextAndScrollDataForTab(aWindow, aBrowser, aTabData) {
var text = [];
if (aBrowser.parentNode.__SS_text &&
this._checkPrivacyLevel(aBrowser.currentURI.schemeIs("https"))) {
for (var ix = aBrowser.parentNode.__SS_text.length - 1; ix >= 0; ix--) {
var data = aBrowser.parentNode.__SS_text[ix];
if (!data.cache)
// update the text element's value before adding it to the data structure
data.cache = encodeURI(data.element.value);
text.push(data.id + "=" + data.cache);
}
}
if (aBrowser.currentURI.spec == "about:config")
text = ["#textbox=" + encodeURI(aBrowser.contentDocument.getElementById("textbox").
wrappedJSObject.value)];
if (text.length > 0)
aTabData.text = text.join(" ");
else if (aTabData.text)
delete aTabData.text;
this._updateTextAndScrollDataForFrame(aWindow, aBrowser.contentWindow,
aTabData.entries[aTabData.index - 1]);
},
/**
* go through all subframes and store the current scroll positions
* and innerHTML content of WYSIWYG editors
* @param aWindow
* Window reference
* @param aContent
* frame reference
* @param aData
* part of a tabData object to add the information to
*/
_updateTextAndScrollDataForFrame:
function sss_updateTextAndScrollDataForFrame(aWindow, aContent, aData) {
for (var i = 0; i < aContent.frames.length; i++) {
if (aData.children && aData.children[i])
this._updateTextAndScrollDataForFrame(aWindow, aContent.frames[i], aData.children[i]);
}
// designMode is undefined e.g. for XUL documents (as about:config)
var isHTTPS = this._getURIFromString((aContent.parent || aContent).
document.location.href).schemeIs("https");
if ((aContent.document.designMode || "") == "on" && this._checkPrivacyLevel(isHTTPS)) {
if (aData.innerHTML === undefined) {
// we get no "input" events from iframes - listen for keypress here
var _this = this;
aContent.addEventListener("keypress", function(aEvent) {
_this.saveStateDelayed(aWindow, 3000); }, true);
}
aData.innerHTML = aContent.document.body.innerHTML;
}
aData.scroll = aContent.scrollX + "," + aContent.scrollY;
},
/**
* store all hosts for a URL
* @param aWindow