diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index f3292d8ae6da..845f2aff4ec0 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -535,6 +535,7 @@ BrowsingContext::BrowsingContext(WindowContext* aParentWindow, mUseRemoteTabs(false), mUseRemoteSubframes(false), mCreatedDynamically(false), + mIsInBFCache(false), mChildOffset(0) { MOZ_RELEASE_ASSERT(!mParentWindow || mParentWindow->Group() == mGroup); MOZ_RELEASE_ASSERT(mBrowsingContextId != 0); @@ -2745,6 +2746,11 @@ void BrowsingContext::DidSet(FieldIndex) { MOZ_DIAGNOSTIC_ASSERT(IsTop()); const bool isInBFCache = GetIsInBFCache(); + if (!isInBFCache) { + PreOrderWalk( + [&](BrowsingContext* aContext) { aContext->mIsInBFCache = false; }); + } + PreOrderWalk([&](BrowsingContext* aContext) { nsCOMPtr shell = aContext->GetDocShell(); if (shell) { @@ -2752,6 +2758,11 @@ void BrowsingContext::DidSet(FieldIndex) { ->FirePageHideShowNonRecursive(!isInBFCache); } }); + + if (isInBFCache) { + PreOrderWalk( + [&](BrowsingContext* aContext) { aContext->mIsInBFCache = true; }); + } } void BrowsingContext::SetCustomPlatform(const nsAString& aPlatform, diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index ba3cceb7c9d6..e6ec4174d767 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -197,6 +197,7 @@ enum class ExplicitActiveStatus : uint8_t { /* The number of entries added to the session history because of this \ * browsing context. */ \ FIELD(HistoryEntryCount, uint32_t) \ + /* Don't use the getter of the field, but IsInBFCache() method */ \ FIELD(IsInBFCache, bool) \ FIELD(HasRestoreData, bool) \ FIELD(SessionStoreEpoch, uint32_t) @@ -849,6 +850,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { void FlushSessionStore(); + bool IsInBFCache() const { return mIsInBFCache; } + protected: virtual ~BrowsingContext(); BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup, @@ -1178,6 +1181,11 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { // True if this BrowsingContext is for a frame that was added dynamically. bool mCreatedDynamically : 1; + // Set to true if the browsing context is in the bfcache and pagehide has been + // dispatched. When coming out from the bfcache, the value is set to false + // before dispatching pageshow. + bool mIsInBFCache : 1; + // The original offset of this context in its container. This property is -1 // if this BrowsingContext is for a frame that was added dynamically. int32_t mChildOffset; diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 7c711ed246f4..a4536cef3185 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -6824,15 +6824,14 @@ bool Document::RemoveFromBFCacheSync() { if (XRE_IsContentProcess()) { if (BrowsingContext* bc = GetBrowsingContext()) { - BrowsingContext* top = bc->Top(); - if (top->GetIsInBFCache()) { + if (bc->IsInBFCache()) { ContentChild* cc = ContentChild::GetSingleton(); // IPC is asynchronous but the caller is supposed to check the return // value. The reason for 'Sync' in the method name is that the old // implementation may run scripts. There is Async variant in // the old session history implementation for the cases where // synchronous operation isn't safe. - cc->SendRemoveFromBFCache(top); + cc->SendRemoveFromBFCache(bc->Top()); removed = true; } } diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index bc33534d7711..e7b70d7595d6 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -2758,6 +2758,10 @@ bool nsPIDOMWindowInner::HasOpenWebSockets() const { } bool nsPIDOMWindowInner::IsCurrentInnerWindow() const { + if (mBrowsingContext && mBrowsingContext->IsInBFCache()) { + return false; + } + if (!mBrowsingContext || mBrowsingContext->IsDiscarded()) { // If our BrowsingContext has been discarded, we consider ourselves // still-current if we were current at the time it was discarded. diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini index fa42e3d02256..f20878358e85 100644 --- a/dom/workers/test/mochitest.ini +++ b/dom/workers/test/mochitest.ini @@ -155,7 +155,6 @@ tags = mcb [test_multi_sharedWorker.html] [test_multi_sharedWorker_lifetimes_nobfcache.html] [test_multi_sharedWorker_lifetimes_bfcache.html] -skip-if = fission # bug 1667955 [test_navigator.html] support-files = test_navigator.js diff --git a/dom/workers/test/test_multi_sharedWorker_lifetimes_bfcache.html b/dom/workers/test/test_multi_sharedWorker_lifetimes_bfcache.html index 3eea34641729..1feb07aeaf59 100644 --- a/dom/workers/test/test_multi_sharedWorker_lifetimes_bfcache.html +++ b/dom/workers/test/test_multi_sharedWorker_lifetimes_bfcache.html @@ -115,8 +115,14 @@ let sendToGenerator = testGenerator.next.bind(testGenerator); + function runTest() { + // If Fission is disabled, the pref is no-op. + SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => { + testGenerator.next(); + }); + } - +