mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1191491 - Do not dispatch an audio-playback notification when swapping browsers; r=smaug (dacb2ff694) - Bug 1192252 - Add a helper RAII class for managing the cleanup in nsFrameLoader::SwapWithOtherLoader; r=smaug (362488db65)
This commit is contained in:
@@ -782,6 +782,7 @@ nsDocShell::nsDocShell()
|
||||
, mUseRemoteTabs(false)
|
||||
, mDeviceSizeIsPageSize(false)
|
||||
, mWindowDraggingAllowed(false)
|
||||
, mInFrameSwap(false)
|
||||
, mCanExecuteScripts(false)
|
||||
, mFiredUnloadEvent(false)
|
||||
, mEODForCurrentDocument(false)
|
||||
@@ -14243,3 +14244,16 @@ nsDocShell::GetPaymentRequestId(nsAString& aPaymentRequestId)
|
||||
aPaymentRequestId = GetInheritedPaymentRequestId();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocShell::InFrameSwap()
|
||||
{
|
||||
nsRefPtr<nsDocShell> shell = this;
|
||||
do {
|
||||
if (shell->mInFrameSwap) {
|
||||
return true;
|
||||
}
|
||||
shell = shell->GetParentDocshell();
|
||||
} while (shell);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -262,6 +262,12 @@ public:
|
||||
// is no longer applied
|
||||
void NotifyAsyncPanZoomStopped();
|
||||
|
||||
void SetInFrameSwap(bool aInSwap)
|
||||
{
|
||||
mInFrameSwap = aInSwap;
|
||||
}
|
||||
bool InFrameSwap();
|
||||
|
||||
private:
|
||||
// An observed docshell wrapper is created when recording markers is enabled.
|
||||
mozilla::UniquePtr<mozilla::ObservedDocShell> mObserved;
|
||||
@@ -910,6 +916,7 @@ protected:
|
||||
bool mUseRemoteTabs;
|
||||
bool mDeviceSizeIsPageSize;
|
||||
bool mWindowDraggingAllowed;
|
||||
bool mInFrameSwap;
|
||||
|
||||
// Because scriptability depends on the mAllowJavascript values of our
|
||||
// ancestors, we cache the effective scriptability and recompute it when
|
||||
|
||||
+58
-24
@@ -939,6 +939,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,
|
||||
@@ -975,8 +1029,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> ourDocshell = GetExistingDocShell();
|
||||
nsCOMPtr<nsIDocShell> otherDocshell = aOther->GetExistingDocShell();
|
||||
nsRefPtr<nsDocShell> ourDocshell = static_cast<nsDocShell*>(GetExistingDocShell());
|
||||
nsRefPtr<nsDocShell> otherDocshell = static_cast<nsDocShell*>(aOther->GetExistingDocShell());
|
||||
if (!ourDocshell || !otherDocshell) {
|
||||
// How odd
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
@@ -1107,39 +1161,23 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
if (mInSwap || aOther->mInSwap) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
mInSwap = aOther->mInSwap = 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) {
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, true);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsSubDocumentFrame* ourFrameFrame = do_QueryFrame(ourFrame);
|
||||
if (!ourFrameFrame) {
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, true);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// OK. First begin to swap the docshells in the two nsIFrames
|
||||
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
nsContentUtils::FirePageShowEvent(ourDocshell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(otherDocshell, otherEventTarget, true);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1242,10 +1280,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;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ class nsSubDocumentFrame;
|
||||
class nsView;
|
||||
class nsIInProcessContentFrameMessageManager;
|
||||
class AutoResetInShow;
|
||||
class AutoResetInFrameSwap;
|
||||
class nsITabParent;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsIDocShellTreeOwner;
|
||||
@@ -58,6 +59,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;
|
||||
|
||||
@@ -102,6 +102,7 @@ static PRLogModuleInfo* gMediaElementEventsLog;
|
||||
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#include "nsDocShell.h"
|
||||
|
||||
#include "mozilla/EventStateManager.h"
|
||||
|
||||
@@ -4016,7 +4017,14 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
|
||||
if (pauseElement && mAudioChannelAgent) {
|
||||
// If the element is being paused since we are navigating away from the
|
||||
// document, notify the audio channel agent.
|
||||
NotifyAudioChannelAgent(false);
|
||||
// Be careful to ignore this event during a docshell frame swap.
|
||||
auto docShell = static_cast<nsDocShell*>(OwnerDoc()->GetDocShell());
|
||||
if (!docShell) {
|
||||
return;
|
||||
}
|
||||
if (!docShell->InFrameSwap()) {
|
||||
NotifyAudioChannelAgent(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2429,11 +2429,18 @@ TabChild::RecvSwappedWithOtherRemoteLoader()
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<nsDocShell> docShell = static_cast<nsDocShell*>(ourDocShell.get());
|
||||
|
||||
nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
|
||||
|
||||
docShell->SetInFrameSwap(true);
|
||||
|
||||
nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, false);
|
||||
nsContentUtils::FirePageHideEvent(ourDocShell, ourEventTarget);
|
||||
nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, true);
|
||||
|
||||
docShell->SetInFrameSwap(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user