зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1192252 - Add a helper RAII class for managing the cleanup in nsFrameLoader::SwapWithOtherLoader; r=smaug
This commit is contained in:
Родитель
4db099dbd2
Коммит
51c93c7eea
|
@ -951,6 +951,60 @@ nsFrameLoader::SwapWithOtherRemoteLoader(nsFrameLoader* aOther,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS AutoResetInFrameSwap final
|
||||
{
|
||||
public:
|
||||
AutoResetInFrameSwap(nsFrameLoader* aThisFrameLoader,
|
||||
nsFrameLoader* aOtherFrameLoader,
|
||||
nsDocShell* aThisDocShell,
|
||||
nsDocShell* aOtherDocShell,
|
||||
EventTarget* aThisEventTarget,
|
||||
EventTarget* aOtherEventTarget
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mThisFrameLoader(aThisFrameLoader)
|
||||
, mOtherFrameLoader(aOtherFrameLoader)
|
||||
, mThisDocShell(aThisDocShell)
|
||||
, mOtherDocShell(aOtherDocShell)
|
||||
, mThisEventTarget(aThisEventTarget)
|
||||
, mOtherEventTarget(aOtherEventTarget)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
mThisFrameLoader->mInSwap = true;
|
||||
mOtherFrameLoader->mInSwap = true;
|
||||
mThisDocShell->SetInFrameSwap(true);
|
||||
mOtherDocShell->SetInFrameSwap(true);
|
||||
|
||||
// Fire pageshow events on still-loading pages, and then fire pagehide
|
||||
// events. Note that we do NOT fire these in the normal way, but just fire
|
||||
// them on the chrome event handlers.
|
||||
nsContentUtils::FirePageShowEvent(mThisDocShell, mThisEventTarget, false);
|
||||
nsContentUtils::FirePageShowEvent(mOtherDocShell, mOtherEventTarget, false);
|
||||
nsContentUtils::FirePageHideEvent(mThisDocShell, mThisEventTarget);
|
||||
nsContentUtils::FirePageHideEvent(mOtherDocShell, mOtherEventTarget);
|
||||
}
|
||||
|
||||
~AutoResetInFrameSwap()
|
||||
{
|
||||
nsContentUtils::FirePageShowEvent(mThisDocShell, mThisEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(mOtherDocShell, mOtherEventTarget, true);
|
||||
|
||||
mThisFrameLoader->mInSwap = false;
|
||||
mOtherFrameLoader->mInSwap = false;
|
||||
mThisDocShell->SetInFrameSwap(false);
|
||||
mOtherDocShell->SetInFrameSwap(false);
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsFrameLoader> mThisFrameLoader;
|
||||
nsRefPtr<nsFrameLoader> mOtherFrameLoader;
|
||||
nsRefPtr<nsDocShell> mThisDocShell;
|
||||
nsRefPtr<nsDocShell> mOtherDocShell;
|
||||
nsCOMPtr<EventTarget> mThisEventTarget;
|
||||
nsCOMPtr<EventTarget> mOtherEventTarget;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
nsRefPtr<nsFrameLoader>& aFirstToSwap,
|
||||
|
@ -1119,47 +1173,23 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
if (mInSwap || aOther->mInSwap) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
mInSwap = aOther->mInSwap = true;
|
||||
ourDocshell->SetInFrameSwap(true);
|
||||
otherDocshell->SetInFrameSwap(true);
|
||||
AutoResetInFrameSwap autoFrameSwap(this, aOther, ourDocshell, otherDocshell,
|
||||
ourEventTarget, otherEventTarget);
|
||||
|
||||
// Fire pageshow events on still-loading pages, and then fire pagehide
|
||||
// events. Note that we do NOT fire these in the normal way, but just fire
|
||||
// them on the chrome event handlers.
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, false);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, false);
|
||||
nsContentUtils::FirePageHideEvent(ourDocshell, ourEventTarget);
|
||||
nsContentUtils::FirePageHideEvent(otherDocshell, otherEventTarget);
|
||||
|
||||
nsIFrame* ourFrame = ourContent->GetPrimaryFrame();
|
||||
nsIFrame* otherFrame = otherContent->GetPrimaryFrame();
|
||||
if (!ourFrame || !otherFrame) {
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, true);
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
ourDocshell->SetInFrameSwap(false);
|
||||
otherDocshell->SetInFrameSwap(false);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsSubDocumentFrame* ourFrameFrame = do_QueryFrame(ourFrame);
|
||||
if (!ourFrameFrame) {
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, true);
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
ourDocshell->SetInFrameSwap(false);
|
||||
otherDocshell->SetInFrameSwap(false);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// OK. First begin to swap the docshells in the two nsIFrames
|
||||
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, true);
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
ourDocshell->SetInFrameSwap(false);
|
||||
otherDocshell->SetInFrameSwap(false);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1262,12 +1292,6 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
ourParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
otherParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, true);
|
||||
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
ourDocshell->SetInFrameSwap(false);
|
||||
otherDocshell->SetInFrameSwap(false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class nsSubDocumentFrame;
|
|||
class nsView;
|
||||
class nsIInProcessContentFrameMessageManager;
|
||||
class AutoResetInShow;
|
||||
class AutoResetInFrameSwap;
|
||||
class nsITabParent;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsIDocShellTreeOwner;
|
||||
|
@ -59,6 +60,7 @@ class nsFrameLoader final : public nsIFrameLoader,
|
|||
public mozilla::dom::ipc::MessageManagerCallback
|
||||
{
|
||||
friend class AutoResetInShow;
|
||||
friend class AutoResetInFrameSwap;
|
||||
typedef mozilla::dom::PBrowserParent PBrowserParent;
|
||||
typedef mozilla::dom::TabParent TabParent;
|
||||
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
|
||||
|
|
Загрузка…
Ссылка в новой задаче