From f1ed7fa59ebfb770d78d2f34f3960a03905077c2 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Wed, 2 Feb 2022 13:22:30 +0000 Subject: [PATCH] Bug 1750174 - Auto-refreshing pages reposition themselves to the top upon refresh. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D137383 --- docshell/base/BrowsingContext.cpp | 12 +++- docshell/base/BrowsingContext.h | 2 + docshell/base/CanonicalBrowsingContext.cpp | 5 ++ docshell/base/CanonicalBrowsingContext.h | 8 ++- docshell/test/mochitest/file_bug1742865.sjs | 13 +++- docshell/test/mochitest/test_bug1742865.html | 72 ++++++++++++++------ 6 files changed, 84 insertions(+), 28 deletions(-) diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index b6f80119de73..fc442dd60f04 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -3499,13 +3499,21 @@ bool BrowsingContext::IsPopupAllowed() { /* static */ bool BrowsingContext::ShouldAddEntryForRefresh( 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; } bool equalsURI = false; if (aCurrentURI) { - aCurrentURI->Equals(aInfo.GetURI(), &equalsURI); + aCurrentURI->Equals(aNewURI, &equalsURI); } return !equalsURI; } diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index 6fbf4a05d05e..ef047d445116 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -908,6 +908,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI, const SessionHistoryInfo& aInfo); + static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI, nsIURI* aNewURI, + bool aHasPostData); private: void Attach(bool aFromIPC, ContentParent* aOriginProcess); diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index 5c4a99f397f6..9d98d6efdcf0 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -535,6 +535,11 @@ CanonicalBrowsingContext::CreateLoadingSessionHistoryEntryForLoad( return nullptr; } Unused << SetHistoryEntryCount(entry->BCHistoryLength()); + } else if (aLoadState->LoadType() == LOAD_REFRESH && + !ShouldAddEntryForRefresh(aLoadState->URI(), + aLoadState->PostDataStream()) && + mActiveEntry) { + entry = mActiveEntry; } else { entry = new SessionHistoryEntry(aLoadState, aChannel); if (IsTop()) { diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index 3522ced00788..dbda72f598e3 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -464,9 +464,13 @@ class CanonicalBrowsingContext final : public BrowsingContext { void RemovePendingDiscard(); bool ShouldAddEntryForRefresh(const SessionHistoryEntry* aEntry) { + return ShouldAddEntryForRefresh(aEntry->Info().GetURI(), + aEntry->Info().GetPostData()); + } + bool ShouldAddEntryForRefresh(nsIURI* aNewURI, bool aHasPostData) { nsCOMPtr currentURI = GetCurrentURI(); - return BrowsingContext::ShouldAddEntryForRefresh(currentURI, - aEntry->Info()); + return BrowsingContext::ShouldAddEntryForRefresh(currentURI, aNewURI, + aHasPostData); } // XXX(farre): Store a ContentParent pointer here rather than mProcessId? diff --git a/docshell/test/mochitest/file_bug1742865.sjs b/docshell/test/mochitest/file_bug1742865.sjs index 514427bfd83e..950c30ecd289 100644 --- a/docshell/test/mochitest/file_bug1742865.sjs +++ b/docshell/test/mochitest/file_bug1742865.sjs @@ -13,10 +13,10 @@ function handleRequest(request, response) { // index == 0 First load, returns first 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 + let query = new URLSearchParams(request.queryString); if (index < 2) { - let query = new URLSearchParams(request.queryString); refresh = query.get("seconds"); - if (query.get("crossorigin") == "true") { + if (query.get("crossOrigin") == "true") { const hosts = ["example.org", "example.com"]; let url = `${request.scheme}://${hosts[index]}${request.path}?${request.queryString}`; @@ -24,6 +24,10 @@ function handleRequest(request, response) { } 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)); response.write( @@ -35,10 +39,12 @@ function handleRequest(request, response) { ${refresh}