Bug 1766131 - Always synchronize layout history state on the previous page when restoring a page from BFCache. r=smaug

This fixes docshell/test/chrome/bug321671_window.xhtml running with SHIP.

Differential Revision: https://phabricator.services.mozilla.com/D144517
This commit is contained in:
Peter Van der Beken 2022-04-28 09:54:36 +00:00
Родитель a83575a014
Коммит 1d54b66900
6 изменённых файлов: 75 добавлений и 21 удалений

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

@ -33,6 +33,7 @@
#include "mozilla/StaticPrefs_docshell.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/Telemetry.h"
#include "nsILayoutHistoryState.h"
#include "nsIPrintSettings.h"
#include "nsIPrintSettingsService.h"
#include "nsISupports.h"
@ -2241,6 +2242,33 @@ void CanonicalBrowsingContext::HistoryCommitIndexAndLength(
});
}
void CanonicalBrowsingContext::SynchronizeLayoutHistoryState() {
if (mActiveEntry) {
if (IsInProcess()) {
nsIDocShell* docShell = GetDocShell();
if (docShell) {
docShell->PersistLayoutHistoryState();
nsCOMPtr<nsILayoutHistoryState> state;
docShell->GetLayoutHistoryState(getter_AddRefs(state));
if (state) {
mActiveEntry->SetLayoutHistoryState(state);
}
}
} else if (ContentParent* cp = GetContentParent()) {
cp->SendGetLayoutHistoryState(this)->Then(
GetCurrentSerialEventTarget(), __func__,
[activeEntry =
mActiveEntry](const RefPtr<nsILayoutHistoryState>& aState) {
if (aState) {
activeEntry->SetLayoutHistoryState(aState);
}
},
[]() {});
}
}
}
void CanonicalBrowsingContext::ResetScalingZoom() {
// This currently only ever gets called in the parent process, and we
// pass the message on to the WindowGlobalChild for the rootmost browsing

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

@ -284,6 +284,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void HistoryCommitIndexAndLength();
void SynchronizeLayoutHistoryState();
void ResetScalingZoom();
void SetContainerFeaturePolicy(FeaturePolicy* aContainerFeaturePolicy);

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

@ -1244,9 +1244,15 @@ static void FinishRestore(CanonicalBrowsingContext* aBrowsingContext,
// nsFrameLoader in the current SessionHistoryEntry.
RefPtr<SessionHistoryEntry> currentSHEntry =
aBrowsingContext->GetActiveSessionHistoryEntry();
if (aCanSave && currentSHEntry) {
currentSHEntry->SetFrameLoader(currentFrameLoader);
Unused << aBrowsingContext->SetIsInBFCache(true);
if (currentSHEntry) {
// Update layout history state now, before we change the IsInBFCache flag
// and the active session history entry.
aBrowsingContext->SynchronizeLayoutHistoryState();
if (aCanSave) {
currentSHEntry->SetFrameLoader(currentFrameLoader);
Unused << aBrowsingContext->SetIsInBFCache(true);
}
}
if (aBrowsingContext->IsActive()) {
@ -1279,10 +1285,6 @@ static void FinishRestore(CanonicalBrowsingContext* aBrowsingContext,
// The old page can't be stored in the bfcache,
// destroy the nsFrameLoader.
if (!aCanSave && currentFrameLoader) {
// Since destroying the browsing context may need to update layout
// history state, the browsing context needs to have still access to the
// correct entry.
aBrowsingContext->SetActiveSessionHistoryEntry(currentSHEntry);
currentFrameLoader->Destroy();
}

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

@ -127,6 +127,7 @@
#include "nsHttpHandler.h"
#include "nsIConsoleService.h"
#include "nsIInputStreamChannel.h"
#include "nsILayoutHistoryState.h"
#include "nsILoadGroup.h"
#include "nsIOpenWindowInfo.h"
#include "nsISimpleEnumerator.h"
@ -4452,6 +4453,20 @@ mozilla::ipc::IPCResult ContentChild::RecvHistoryCommitIndexAndLength(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvGetLayoutHistoryState(
const MaybeDiscarded<BrowsingContext>& aContext,
GetLayoutHistoryStateResolver&& aResolver) {
nsCOMPtr<nsILayoutHistoryState> state;
nsIDocShell* docShell;
if (!aContext.IsNullOrDiscarded() &&
(docShell = aContext.get()->GetDocShell())) {
docShell->PersistLayoutHistoryState();
docShell->GetLayoutHistoryState(getter_AddRefs(state));
}
aResolver(state);
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvDispatchLocationChangeEvent(
const MaybeDiscarded<BrowsingContext>& aContext) {
if (!aContext.IsNullOrDiscarded() && aContext.get()->GetDocShell()) {

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

@ -803,6 +803,10 @@ class ContentChild final : public PContentChild,
const MaybeDiscarded<BrowsingContext>& aContext, const uint32_t& aIndex,
const uint32_t& aLength, const nsID& aChangeID);
mozilla::ipc::IPCResult RecvGetLayoutHistoryState(
const MaybeDiscarded<BrowsingContext>& aContext,
GetLayoutHistoryStateResolver&& aResolver);
mozilla::ipc::IPCResult RecvDispatchLocationChangeEvent(
const MaybeDiscarded<BrowsingContext>& aContext);

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

@ -1016,24 +1016,27 @@ child:
uint32_t aIndex, uint32_t aLength,
nsID aChangeID);
async DispatchLocationChangeEvent(MaybeDiscardedBrowsingContext aContext);
async GetLayoutHistoryState(MaybeDiscardedBrowsingContext aContext)
returns (nsILayoutHistoryState aState);
// Dispatches a "beforeunload" event to each in-process content window in the
// subtree beginning at `aStartingAt`, and returns the result as documented in
// the `PermitUnloadResult` enum.
async DispatchBeforeUnloadToSubtree(MaybeDiscardedBrowsingContext aStartingAt)
returns (PermitUnloadResult result);
async DispatchLocationChangeEvent(MaybeDiscardedBrowsingContext aContext);
// Update the cached list of codec supported in the given process.
async UpdateMediaCodecsSupported(RemoteDecodeIn aLocation, MediaCodecsSupported aSupported);
// Dispatches a "beforeunload" event to each in-process content window in the
// subtree beginning at `aStartingAt`, and returns the result as documented in
// the `PermitUnloadResult` enum.
async DispatchBeforeUnloadToSubtree(MaybeDiscardedBrowsingContext aStartingAt)
returns (PermitUnloadResult result);
// Send the list of the supported mimetypes in the given process. GeckoView-specific
async DecoderSupportedMimeTypes(nsCString[] supportedTypes);
// Update the cached list of codec supported in the given process.
async UpdateMediaCodecsSupported(RemoteDecodeIn aLocation, MediaCodecsSupported aSupported);
// Used to initialize the global variable in content processes with the
// latched value in the parent process. See dom/LocalStorageCommon.h for more
// details.
async InitNextGenLocalStorageEnabled(bool enabled);
// Send the list of the supported mimetypes in the given process. GeckoView-specific
async DecoderSupportedMimeTypes(nsCString[] supportedTypes);
// Used to initialize the global variable in content processes with the
// latched value in the parent process. See dom/LocalStorageCommon.h for more
// details.
async InitNextGenLocalStorageEnabled(bool enabled);
async PRemotePrintJob();