mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 1143720 - Remove support for old FormData, PageStyle, and ScrollPosition formats r=smacleod
This commit is contained in:
parent
bf0b600f80
commit
dead09af67
@ -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 || "");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -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|.
|
||||
|
@ -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"}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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(() => {
|
||||
|
@ -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(() => {
|
||||
|
@ -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()";
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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({
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user