Bug 1143720 - Remove support for old FormData, PageStyle, and ScrollPosition formats r=smacleod

This commit is contained in:
Tim Taubert 2015-03-16 17:17:43 +01:00
parent bf0b600f80
commit dead09af67
12 changed files with 42 additions and 187 deletions

View File

@ -279,42 +279,6 @@ ContentRestoreInternal.prototype = {
});
},
/**
* Accumulates a list of frames that need to be restored for the given browser
* element. A frame is only restored if its current URL matches the one saved
* in the session data. Each frame to be restored is returned along with its
* associated session data.
*
* @param browser the browser being restored
* @return an array of [frame, data] pairs
*/
getFramesToRestore: function (content, data) {
function hasExpectedURL(aDocument, aURL) {
return !aURL || aURL.replace(/#.*/, "") == aDocument.location.href.replace(/#.*/, "");
}
let frameList = [];
function enumerateFrame(content, data) {
// Skip the frame if the user has navigated away before loading finished.
if (!hasExpectedURL(content.document, data.url)) {
return;
}
frameList.push([content, data]);
for (let i = 0; i < content.frames.length; i++) {
if (data.children && data.children[i]) {
enumerateFrame(content.frames[i], data.children[i]);
}
}
}
enumerateFrame(content, data);
return frameList;
},
/**
* Finish restoring the tab by filling in form data and setting the scroll
* position. The restore is complete when this function exits. It should be
@ -329,34 +293,12 @@ ContentRestoreInternal.prototype = {
let {entry, pageStyle, formdata, scrollPositions} = this._restoringDocument;
this._restoringDocument = null;
let window = this.docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
let frameList = this.getFramesToRestore(window, entry);
// Support the old pageStyle format.
if (typeof(pageStyle) === "string") {
PageStyle.restore(this.docShell, frameList, pageStyle);
} else {
PageStyle.restoreTree(this.docShell, pageStyle);
}
let window = this.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
PageStyle.restoreTree(this.docShell, pageStyle);
FormData.restoreTree(window, formdata);
ScrollPosition.restoreTree(window, scrollPositions);
// We need to support the old form and scroll data for a while at least.
for (let [frame, data] of frameList) {
if (data.hasOwnProperty("formdata") || data.hasOwnProperty("innerHTML")) {
let formdata = data.formdata || {};
formdata.url = data.url;
if (data.hasOwnProperty("innerHTML")) {
formdata.innerHTML = data.innerHTML;
}
FormData.restore(frame, formdata);
}
ScrollPosition.restore(frame, data.scroll || "");
}
},
/**

View File

@ -16,10 +16,6 @@ this.PageStyle = Object.freeze({
return PageStyleInternal.collect(docShell, frameTree);
},
restore: function (docShell, frameList, pageStyle) {
PageStyleInternal.restore(docShell, frameList, pageStyle);
},
restoreTree: function (docShell, data) {
PageStyleInternal.restoreTree(docShell, data);
}
@ -55,29 +51,6 @@ let PageStyleInternal = {
return result && Object.keys(result).length ? result : null;
},
/**
* Restore the selected style sheet of all the frames in frameList
* to match |pageStyle|.
* @param docShell the root docshell of all the frames
* @param frameList a list of [frame, data] pairs, where frame is a
* DOM window and data is the session restore data associated with
* it.
* @param pageStyle the title of the style sheet to apply
*/
restore: function (docShell, frameList, pageStyle) {
let disabled = pageStyle == NO_STYLE;
let markupDocumentViewer =
docShell.contentViewer;
markupDocumentViewer.authorStyleDisabled = disabled;
for (let [frame, data] of frameList) {
Array.forEach(frame.document.styleSheets, function(aSS) {
aSS.disabled = aSS.title && aSS.title != pageStyle;
});
}
},
/**
* Restores pageStyle data for the current frame hierarchy starting at the
* |docShell's| current DOMWindow using the given pageStyle |data|.

View File

@ -19,14 +19,14 @@
// 3c. Check that formdata doesn't require JSON.parse
const CRASH_STATE = {windows: [{tabs: [{entries: [{url: "about:mozilla" }]}]}]};
const STATE = {entries: [createEntry(CRASH_STATE)]};
const STATE2 = {entries: [createEntry({windows: [{tabs: [STATE]}]})]};
const STATE3 = {entries: [createEntry(JSON.stringify(CRASH_STATE))]};
const STATE = createEntries(CRASH_STATE);
const STATE2 = createEntries({windows: [{tabs: [STATE]}]});
const STATE3 = createEntries(JSON.stringify(CRASH_STATE));
function createEntry(sessionData) {
function createEntries(sessionData) {
return {
url: "about:sessionrestore",
formdata: {id: {sessionData: sessionData}}
entries: [{url: "about:sessionrestore"}],
formdata: {id: {sessionData: sessionData}, url: "about:sessionrestore"}
};
}

View File

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let oldState = {
let sessionData = {
windows: [{
tabs: [
{ entries: [{ url: "about:mozilla" }], hidden: true },
@ -10,11 +10,9 @@ function test() {
]
}]
};
let pageData = {
url: "about:sessionrestore",
formdata: { id: { "sessionData": oldState } }
};
let state = { windows: [{ tabs: [{ entries: [pageData] }] }] };
let url = "about:sessionrestore";
let formdata = {id: {sessionData}, url};
let state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] };
waitForExplicitFinish();

View File

@ -61,7 +61,9 @@ function testTabRestoreData(aFormData, aExpectedValue, aCallback) {
let testURL =
getRootDirectory(gTestPath) + "browser_662743_sample.html";
let tab = gBrowser.addTab(testURL);
let tabState = { entries: [{ url: testURL, formdata: aFormData}] };
aFormData.url = testURL;
let tabState = { entries: [{ url: testURL, }], formdata: aFormData };
promiseBrowserLoaded(tab.linkedBrowser).then(() => {
promiseTabState(tab, tabState).then(() => {

View File

@ -1,8 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let url = "data:text/html;charset=utf-8,<input%20id='foo'>";
let tabState = {
entries: [{url: "data:text/html;charset=utf-8,<input%20id='foo'>", formdata: { id: { "foo": "bar" } } }]
entries: [{ url }], formdata: { id: { "foo": "bar" }, url }
};
function test() {
@ -24,8 +25,7 @@ function test() {
ss.setTabState(tab, JSON.stringify(tabState));
is(browser.__SS_restoreState, TAB_STATE_NEEDS_RESTORE, "tab needs restoring");
let state = JSON.parse(ss.getTabState(tab));
let formdata = state.entries[0].formdata;
let {formdata} = JSON.parse(ss.getTabState(tab));
is(formdata && formdata.id["foo"], "bar", "tab state's formdata is valid");
promiseTabRestored(tab).then(() => {

View File

@ -7,9 +7,10 @@ const CRASH_SHENTRY = {url: "about:mozilla"};
const CRASH_TAB = {entries: [CRASH_SHENTRY]};
const CRASH_STATE = {windows: [{tabs: [CRASH_TAB]}]};
const TAB_FORMDATA = {id: {sessionData: CRASH_STATE}};
const TAB_SHENTRY = {url: "about:sessionrestore", formdata: TAB_FORMDATA};
const TAB_STATE = {entries: [TAB_SHENTRY]};
const TAB_URL = "about:sessionrestore";
const TAB_FORMDATA = {url: TAB_URL, id: {sessionData: CRASH_STATE}};
const TAB_SHENTRY = {url: TAB_URL};
const TAB_STATE = {entries: [TAB_SHENTRY], formdata: TAB_FORMDATA};
const FRAME_SCRIPT = "data:," +
"content.document.getElementById('errorTryAgain').click()";

View File

@ -58,54 +58,6 @@ add_task(function test_formdata() {
Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
});
/**
* This test ensures that we maintain backwards compatibility with the form
* data format used pre Fx 29.
*/
add_task(function test_old_format() {
const URL = "data:text/html;charset=utf-8,<input%20id=input>";
const VALUE = "value-" + Math.random();
// Create a tab with an iframe containing an input field.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Check that the form value is restored.
let state = {entries: [{url: URL, formdata: {id: {input: VALUE}}}]};
yield promiseTabState(tab, state);
is((yield getInputValue(browser, "input")), VALUE, "form data restored");
// Cleanup.
gBrowser.removeTab(tab);
});
/**
* This test ensures that we maintain backwards compatibility with the form
* data form used pre Fx 29, esp. the .innerHTML property for editable docs.
*/
add_task(function test_old_format_inner_html() {
const URL = "data:text/html;charset=utf-8,<h1>mozilla</h1>" +
"<script>document.designMode='on'</script>";
const VALUE = "<h1>value-" + Math.random() + "</h1>";
// Create a tab with an iframe containing an input field.
let tab = gBrowser.addTab(URL);
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Restore the tab state.
let state = {entries: [{url: URL, innerHTML: VALUE}]};
yield promiseTabState(tab, state);
// Check that the innerHTML value was restored.
let html = yield getInnerHTML(browser);
is(html, VALUE, "editable document has been restored correctly");
// Cleanup.
gBrowser.removeTab(tab);
});
/**
* This test ensures that a malicious website can't trick us into restoring
* form data into a wrong website and that we always check the stored URL

View File

@ -71,7 +71,9 @@ function testTabRestoreData(aFormData, aExpectedValue, aCallback) {
let URL = ROOT + "browser_formdata_format_sample.html";
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
let tabState = { entries: [{ url: URL, formdata: aFormData}] };
aFormData.url = URL;
let tabState = { entries: [{ url: URL }], formdata: aFormData };
Task.spawn(function () {
yield promiseBrowserLoaded(tab.linkedBrowser);

View File

@ -102,30 +102,6 @@ add_task(function test_scroll_nested() {
gBrowser.removeTab(tab2);
});
/**
* This test ensures that by moving scroll positions out of tabData.entries[]
* we still support the old scroll data format stored per shistory entry.
*/
add_task(function test_scroll_old_format() {
const TAB_STATE = { entries: [{url: URL, scroll: SCROLL_STR}] };
// Add a blank tab.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
yield promiseBrowserLoaded(browser);
// Apply the tab state with the old format.
yield promiseTabState(tab, TAB_STATE);
// Check that the scroll positions has been applied.
let scroll = yield sendMessage(browser, "ss-test:getScrollPosition");
is(JSON.stringify(scroll), JSON.stringify({x: SCROLL_X, y: SCROLL_Y}),
"scroll position has been restored correctly");
// Cleanup.
gBrowser.removeTab(tab);
});
function checkScroll(tab, expected, msg) {
let browser = tab.linkedBrowser;
TabState.flush(browser);

View File

@ -86,10 +86,6 @@ this.FormData = Object.freeze({
return FormDataInternal.collect(frame);
},
restore: function (frame, data) {
FormDataInternal.restore(frame, data);
},
restoreTree: function (root, data) {
FormDataInternal.restoreTree(root, data);
}

View File

@ -9,12 +9,25 @@ this.EXPORTED_SYMBOLS = ["ScrollPosition"];
const Ci = Components.interfaces;
/**
* It provides methods to collect and restore scroll positions for single
* frames and frame trees.
* It provides methods to collect scroll positions from single frames and to
* restore scroll positions for frame trees.
*
* This is a child process module.
*/
this.ScrollPosition = Object.freeze({
collect(frame) {
return ScrollPositionInternal.collect(frame);
},
restoreTree(root, data) {
ScrollPositionInternal.restoreTree(root, data);
}
});
/**
* This module's internal API.
*/
let ScrollPositionInternal = {
/**
* Collects scroll position data for any given |frame| in the frame hierarchy.
*
@ -87,4 +100,4 @@ this.ScrollPosition = Object.freeze({
}
});
}
});
};