зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1750174 - Auto-refreshing pages reposition themselves to the top upon refresh. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D137383
This commit is contained in:
Родитель
4755c564c2
Коммит
f1ed7fa59e
|
@ -3499,13 +3499,21 @@ bool BrowsingContext::IsPopupAllowed() {
|
||||||
/* static */
|
/* static */
|
||||||
bool BrowsingContext::ShouldAddEntryForRefresh(
|
bool BrowsingContext::ShouldAddEntryForRefresh(
|
||||||
nsIURI* aCurrentURI, const SessionHistoryInfo& aInfo) {
|
nsIURI* aCurrentURI, const SessionHistoryInfo& aInfo) {
|
||||||
if (aInfo.GetPostData()) {
|
return ShouldAddEntryForRefresh(aCurrentURI, aInfo.GetURI(),
|
||||||
|
aInfo.GetPostData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
bool BrowsingContext::ShouldAddEntryForRefresh(nsIURI* aCurrentURI,
|
||||||
|
nsIURI* aNewURI,
|
||||||
|
bool aHasPostData) {
|
||||||
|
if (aHasPostData) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equalsURI = false;
|
bool equalsURI = false;
|
||||||
if (aCurrentURI) {
|
if (aCurrentURI) {
|
||||||
aCurrentURI->Equals(aInfo.GetURI(), &equalsURI);
|
aCurrentURI->Equals(aNewURI, &equalsURI);
|
||||||
}
|
}
|
||||||
return !equalsURI;
|
return !equalsURI;
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,6 +908,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||||
|
|
||||||
static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI,
|
static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI,
|
||||||
const SessionHistoryInfo& aInfo);
|
const SessionHistoryInfo& aInfo);
|
||||||
|
static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI, nsIURI* aNewURI,
|
||||||
|
bool aHasPostData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Attach(bool aFromIPC, ContentParent* aOriginProcess);
|
void Attach(bool aFromIPC, ContentParent* aOriginProcess);
|
||||||
|
|
|
@ -535,6 +535,11 @@ CanonicalBrowsingContext::CreateLoadingSessionHistoryEntryForLoad(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Unused << SetHistoryEntryCount(entry->BCHistoryLength());
|
Unused << SetHistoryEntryCount(entry->BCHistoryLength());
|
||||||
|
} else if (aLoadState->LoadType() == LOAD_REFRESH &&
|
||||||
|
!ShouldAddEntryForRefresh(aLoadState->URI(),
|
||||||
|
aLoadState->PostDataStream()) &&
|
||||||
|
mActiveEntry) {
|
||||||
|
entry = mActiveEntry;
|
||||||
} else {
|
} else {
|
||||||
entry = new SessionHistoryEntry(aLoadState, aChannel);
|
entry = new SessionHistoryEntry(aLoadState, aChannel);
|
||||||
if (IsTop()) {
|
if (IsTop()) {
|
||||||
|
|
|
@ -464,9 +464,13 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||||
void RemovePendingDiscard();
|
void RemovePendingDiscard();
|
||||||
|
|
||||||
bool ShouldAddEntryForRefresh(const SessionHistoryEntry* aEntry) {
|
bool ShouldAddEntryForRefresh(const SessionHistoryEntry* aEntry) {
|
||||||
|
return ShouldAddEntryForRefresh(aEntry->Info().GetURI(),
|
||||||
|
aEntry->Info().GetPostData());
|
||||||
|
}
|
||||||
|
bool ShouldAddEntryForRefresh(nsIURI* aNewURI, bool aHasPostData) {
|
||||||
nsCOMPtr<nsIURI> currentURI = GetCurrentURI();
|
nsCOMPtr<nsIURI> currentURI = GetCurrentURI();
|
||||||
return BrowsingContext::ShouldAddEntryForRefresh(currentURI,
|
return BrowsingContext::ShouldAddEntryForRefresh(currentURI, aNewURI,
|
||||||
aEntry->Info());
|
aHasPostData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX(farre): Store a ContentParent pointer here rather than mProcessId?
|
// XXX(farre): Store a ContentParent pointer here rather than mProcessId?
|
||||||
|
|
|
@ -13,10 +13,10 @@ function handleRequest(request, response) {
|
||||||
// index == 0 First load, returns first meta refresh
|
// index == 0 First load, returns first meta refresh
|
||||||
// index == 1 Second load, caused by first meta refresh, returns second meta refresh
|
// index == 1 Second load, caused by first meta refresh, returns second meta refresh
|
||||||
// index == 2 Third load, caused by second meta refresh, doesn't return a meta refresh
|
// index == 2 Third load, caused by second meta refresh, doesn't return a meta refresh
|
||||||
|
let query = new URLSearchParams(request.queryString);
|
||||||
if (index < 2) {
|
if (index < 2) {
|
||||||
let query = new URLSearchParams(request.queryString);
|
|
||||||
refresh = query.get("seconds");
|
refresh = query.get("seconds");
|
||||||
if (query.get("crossorigin") == "true") {
|
if (query.get("crossOrigin") == "true") {
|
||||||
const hosts = ["example.org", "example.com"];
|
const hosts = ["example.org", "example.com"];
|
||||||
|
|
||||||
let url = `${request.scheme}://${hosts[index]}${request.path}?${request.queryString}`;
|
let url = `${request.scheme}://${hosts[index]}${request.path}?${request.queryString}`;
|
||||||
|
@ -24,6 +24,10 @@ function handleRequest(request, response) {
|
||||||
}
|
}
|
||||||
refresh = `<meta http-equiv="Refresh" content="${refresh}">`;
|
refresh = `<meta http-equiv="Refresh" content="${refresh}">`;
|
||||||
}
|
}
|
||||||
|
// We want to scroll for the first load, and check that the meta refreshes keep the same
|
||||||
|
// scroll position.
|
||||||
|
let scroll = index == 0 ? `scrollTo(0, ${query.get("scrollTo")});` : "";
|
||||||
|
|
||||||
setState("index", String(index + 1));
|
setState("index", String(index + 1));
|
||||||
|
|
||||||
response.write(
|
response.write(
|
||||||
|
@ -35,10 +39,12 @@ function handleRequest(request, response) {
|
||||||
${refresh}
|
${refresh}
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener("pageshow", () => {
|
window.addEventListener("pageshow", () => {
|
||||||
|
${scroll}
|
||||||
window.top.opener.postMessage({
|
window.top.opener.postMessage({
|
||||||
commandType: "pageShow",
|
commandType: "pageShow",
|
||||||
commandData: {
|
commandData: {
|
||||||
inputValue: document.getElementById("input").value,
|
inputValue: document.getElementById("input").value,
|
||||||
|
scrollPosition: window.scrollY,
|
||||||
},
|
},
|
||||||
}, "*");
|
}, "*");
|
||||||
});
|
});
|
||||||
|
@ -62,6 +68,9 @@ function handleRequest(request, response) {
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<input type="text" id="input" value="initial"></input>
|
<input type="text" id="input" value="initial"></input>
|
||||||
|
<div style='height: 9000px;'></div>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>`
|
</html>`
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,8 +16,32 @@
|
||||||
|
|
||||||
const SJS = new URL("file_bug1742865.sjs", location.href);
|
const SJS = new URL("file_bug1742865.sjs", location.href);
|
||||||
const SJS_OUTER = new URL("file_bug1742865_outer.sjs", location.href);
|
const SJS_OUTER = new URL("file_bug1742865_outer.sjs", location.href);
|
||||||
|
const SCROLL = 500;
|
||||||
|
|
||||||
|
let tolerance;
|
||||||
|
function setup() {
|
||||||
|
return SpecialPowers.spawn(window.top, [], () => {
|
||||||
|
return SpecialPowers.getDOMWindowUtils(content.window).getResolution();
|
||||||
|
}).then(resolution => {
|
||||||
|
// Allow a half pixel difference if the top document's resolution is lower
|
||||||
|
// than 1.0 because the scroll position is aligned with screen pixels
|
||||||
|
// instead of CSS pixels.
|
||||||
|
tolerance = resolution < 1.0 ? 0.5 : 0.0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkScrollPosition(scrollPosition, shouldKeepScrollPosition) {
|
||||||
|
isfuzzy(scrollPosition, shouldKeepScrollPosition ? SCROLL : 0, tolerance,
|
||||||
|
`Scroll position ${shouldKeepScrollPosition ? "should" : "shouldn't"} be maintained for meta refresh`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWindowAndCheckRefresh(url, params, shouldAddToHistory, shouldKeepScrollPosition) {
|
||||||
|
info(`Running test for ${JSON.stringify(params)}`);
|
||||||
|
|
||||||
|
url = new URL(url);
|
||||||
|
Object.entries(params).forEach(([k, v]) => { url.searchParams.append(k, v) });
|
||||||
|
url.searchParams.append("scrollTo", SCROLL);
|
||||||
|
|
||||||
function openWindowAndCheckRefresh(url, shouldAddToHistory) {
|
|
||||||
let resetURL = new URL(SJS);
|
let resetURL = new URL(SJS);
|
||||||
resetURL.search = "?reset";
|
resetURL.search = "?reset";
|
||||||
return fetch(resetURL).then(() => {
|
return fetch(resetURL).then(() => {
|
||||||
|
@ -41,14 +65,18 @@
|
||||||
|
|
||||||
is(commandType, "pageShow", "Unknown command type");
|
is(commandType, "pageShow", "Unknown command type");
|
||||||
|
|
||||||
let { inputValue } = commandData;
|
let { inputValue, scrollPosition } = commandData;
|
||||||
|
|
||||||
switch (++count) {
|
switch (++count) {
|
||||||
// file_bug1742865.sjs causes 3 loads:
|
// file_bug1742865.sjs causes 3 loads:
|
||||||
// * first load, returns first meta refresh
|
// * first load, returns first meta refresh
|
||||||
// * second load, caused by first meta refresh, returns second meta refresh
|
// * second load, caused by first meta refresh, returns second meta refresh
|
||||||
// * third load, caused by second meta refresh, doesn't return a meta refresh
|
// * third load, caused by second meta refresh, doesn't return a meta refresh
|
||||||
|
case 2:
|
||||||
|
checkScrollPosition(scrollPosition, shouldKeepScrollPosition);
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
checkScrollPosition(scrollPosition, shouldKeepScrollPosition);
|
||||||
win.postMessage("changeInputValue", "*");
|
win.postMessage("changeInputValue", "*");
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -56,6 +84,7 @@
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
is(inputValue, "1234", "Entries for auto-refresh should be attached to session history");
|
is(inputValue, "1234", "Entries for auto-refresh should be attached to session history");
|
||||||
|
checkScrollPosition(scrollPosition, shouldKeepScrollPosition);
|
||||||
removeEventListener("message", listener);
|
removeEventListener("message", listener);
|
||||||
win.close();
|
win.close();
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -67,36 +96,35 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doTest(seconds, crossOrigin, shouldAddToHistory) {
|
function doTest(seconds, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition) {
|
||||||
let url = new URL(SJS);
|
let params = {
|
||||||
url.searchParams.append("seconds", seconds);
|
seconds,
|
||||||
url.searchParams.append("crossorigin", crossOrigin);
|
crossOrigin,
|
||||||
|
};
|
||||||
|
|
||||||
let urlOuter = new URL(SJS_OUTER);
|
return openWindowAndCheckRefresh(SJS, params, shouldAddToHistory, shouldKeepScrollPosition).then(() =>
|
||||||
urlOuter.searchParams.append("seconds", seconds);
|
openWindowAndCheckRefresh(SJS_OUTER, params, shouldAddToHistory, shouldKeepScrollPosition)
|
||||||
urlOuter.searchParams.append("crossorigin", crossOrigin);
|
|
||||||
|
|
||||||
return openWindowAndCheckRefresh(url, shouldAddToHistory).then(() =>
|
|
||||||
openWindowAndCheckRefresh(urlOuter, shouldAddToHistory)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function runTest() {
|
async function runTest() {
|
||||||
const FAST = Math.min(1, REFRESH_REDIRECT_TIMER);
|
const FAST = Math.min(1, REFRESH_REDIRECT_TIMER);
|
||||||
const SLOW = REFRESH_REDIRECT_TIMER + 1;
|
const SLOW = REFRESH_REDIRECT_TIMER + 1;
|
||||||
let tests = [
|
let tests = [
|
||||||
// [ time, crossOrigin, shouldAddToHistory ]
|
// [ time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition ]
|
||||||
[ FAST, false, false ],
|
[ FAST, false, false, true ],
|
||||||
[ FAST, true, false ],
|
[ FAST, true, false, false ],
|
||||||
[ SLOW, false, false ],
|
[ SLOW, false, false, true ],
|
||||||
[ SLOW, true, true ],
|
[ SLOW, true, true, false ],
|
||||||
];
|
];
|
||||||
|
|
||||||
let test = Promise.resolve();
|
await setup();
|
||||||
for (let [ time, crossOrigin, shouldAddToHistory ] of tests) {
|
|
||||||
test = test.then(() => doTest(time, crossOrigin, shouldAddToHistory));
|
for (let [ time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition ] of tests) {
|
||||||
|
await doTest(time, crossOrigin, shouldAddToHistory, shouldKeepScrollPosition);
|
||||||
}
|
}
|
||||||
test.then(() => SimpleTest.finish());
|
|
||||||
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче