Bug 1300461 - UpdateIndex on LOAD_NORMAL_REPLACE, ReplaceEntry at requestedIndex when available. r=smaug

--HG--
extra : rebase_source : 9bb3c7488a1785ee5c4106b8e024555f31b3220c
This commit is contained in:
Samael Wang 2016-09-30 11:55:10 +08:00
Родитель b2629e2eec
Коммит 104fe2c997
7 изменённых файлов: 127 добавлений и 8 удалений

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

@ -11691,9 +11691,12 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
AddURIVisit(aURI, referrer, previousURI, previousFlags, responseStatus);
}
// If this was a history load or a refresh,
// update the index in SH.
if (rootSH && (mLoadType & (LOAD_CMD_HISTORY | LOAD_CMD_RELOAD))) {
// If this was a history load or a refresh, or it was a history load but
// later changed to LOAD_NORMAL_REPLACE due to redirection, update the index
// in session history.
if (rootSH &&
((mLoadType & (LOAD_CMD_HISTORY | LOAD_CMD_RELOAD)) ||
mLoadType == LOAD_NORMAL_REPLACE)) {
nsCOMPtr<nsISHistoryInternal> shInternal(do_QueryInterface(rootSH));
if (shInternal) {
rootSH->GetIndex(&mPreviousTransIndex);
@ -12329,9 +12332,14 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
// This is the root docshell
bool addToSHistory = !LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY);
if (!addToSHistory) {
// Replace current entry in session history.
// Replace current entry in session history; If the requested index is
// valid, it indicates the loading was triggered by a history load, and
// we should replace the entry at requested index instead.
int32_t index = 0;
mSessionHistory->GetIndex(&index);
mSessionHistory->GetRequestedIndex(&index);
if (index == -1) {
mSessionHistory->GetIndex(&index);
}
nsCOMPtr<nsISHistoryInternal> shPrivate =
do_QueryInterface(mSessionHistory);
// Replace the current entry with the new entry

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

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Bug 1300461</title>
</head>
<body onload="test();">
<script>
/**
* Bug 1300461 identifies that if a history entry was not bfcached, and
* a http redirection happens when navigating to that entry, the history
* index would mess up.
*
* The test case emulates the circumstance by the following steps
* 1) Navigate to file_bug1300461_back.html which is not bf-cachable.
* 2) In file_bug1300461_back.html, replace its own history state to
* file_bug1300461_redirect.html.
* 3) Back, and then forward. Since the document is not in bfcache, it
* tries to load file_bug1300461_redirect.html directly.
* 4) file_bug1300461_redirect.html redirects UA to
* file_bug1300461_back.html through HTTP 301 header.
*
* We verify the history index, canGoBack, canGoForward, etc. keep correct
* in this process.
*/
let Ci = SpecialPowers.Ci;
let webNav = SpecialPowers.wrap(window)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation);
let shistory = webNav.sessionHistory;
let testSteps = [
function() {
opener.is(shistory.count, 1, 'check history length');
opener.is(shistory.index, 0, 'check history index');
opener.ok(!webNav.canGoForward, 'check canGoForward');
setTimeout(() => window.location = 'file_bug1300461_back.html', 0);
},
function() {
opener.is(shistory.count, 2, 'check history length');
opener.is(shistory.index, 0, 'check history index');
opener.ok(webNav.canGoForward, 'check canGoForward');
window.history.forward();
opener.is(shistory.requestedIndex, 1, 'check requestedIndex');
},
function() {
opener.is(shistory.count, 2, 'check history length');
opener.is(shistory.index, 0, 'check history index');
opener.ok(webNav.canGoForward, 'check canGoForward');
opener.info('file_bug1300461.html tests finished');
opener.nextTest();
window.close();
}
];
function test() {
if (opener) {
opener.info('file_bug1300461.html test ' + opener.testCount);
testSteps[opener.testCount++]();
}
}
</script>
</body>
</html>

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

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Bug 1300461</title>
</head>
<!-- The empty unload handler is to prevent bfcache. -->
<body onload="test();" onunload="">
<script>
let Ci = SpecialPowers.Ci;
let webNav = SpecialPowers.wrap(window)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation);
let shistory = webNav.sessionHistory;
function test() {
if (opener) {
opener.info("file_bug1300461_back.html");
opener.is(shistory.count, 2, 'check history length');
opener.is(shistory.index, 1, 'check history index');
opener.is(shistory.requestedIndex, -1, 'check requestedIndex');
opener.ok(webNav.canGoBack, 'check canGoBack');
if (opener.testCount == 1) {
opener.info('replaceState to redirect.html');
window.history.replaceState({}, '', 'file_bug1300461_redirect.html');
}
window.history.back();
}
}
</script>
</body>
</html>

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

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Bug 1300461</title>
</head>
<body>
Redirect to file_bug1300461_back.html.
</body>
</html>

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

@ -0,0 +1,2 @@
HTTP 301 Moved Permanently
Location: file_bug1300461_back.html

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

@ -32,7 +32,11 @@ support-files =
file_triggeringprincipal_iframe_iframe_window_open_frame_a.html
file_triggeringprincipal_iframe_iframe_window_open_frame_b.html
file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html
file_bug1300461.html
file_bug1300461_redirect.html
file_bug1300461_redirect.html^headers^
file_bug1300461_back.html
[test_bug13871.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet' || toolkit == 'android' #RANDOM # Bug 1136180 disabled on B2G Desktop and Mulet for intermittent failures
[test_bug270414.html]

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

@ -30,7 +30,8 @@ var testFiles =
"file_fragment_handling_during_load.html",
"file_nested_frames.html",
"file_shiftReload_and_pushState.html",
"file_scrollRestoration.html"
"file_scrollRestoration.html",
"file_bug1300461.html"
];
var testCount = 0; // Used by the test files.
@ -42,7 +43,7 @@ function nextTest_() {
if (testFiles.length) {
testCount = 0;
testWindow = window.open(testFiles.shift(), "", "width=300,height=300");
testWindow.onunload = function () { } //XXX
testWindow.onunload = function () { } // to prevent bfcache
} else {
SimpleTest.finish();
}