diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 9e0a50629e01..9fc46fb7c0a8 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -9565,7 +9565,6 @@ nsDocument::OnPageHide(bool aPersisted, mVisible = false; UpdateVisibilityState(); - EnumerateExternalResources(NotifyPageHide, &aPersisted); EnumerateActivityObservers(NotifyActivityChanged, nullptr); diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index b59474997f1b..b764e3d03edd 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -21,6 +21,7 @@ #include "TimeRanges.h" #include "nsGenericHTMLElement.h" #include "nsAttrValueInlines.h" +#include "nsDocShellLoadTypes.h" #include "nsPresContext.h" #include "nsIClassOfService.h" #include "nsIPresShell.h" @@ -3845,6 +3846,105 @@ private: NS_IMPL_ISUPPORTS(HTMLMediaElement::ShutdownObserver, nsIObserver) +class HTMLMediaElement::ForceReloadListener : public nsIWebProgressListener + , public nsSupportsWeakReference +{ +public: + NS_DECL_ISUPPORTS + + void Subscribe(HTMLMediaElement* aPtr, nsIWebProgress* aWebProgress) + { + MOZ_DIAGNOSTIC_ASSERT(!mWeak); + MOZ_DIAGNOSTIC_ASSERT(aWebProgress); + mWeak = aPtr; + aWebProgress->AddProgressListener(this, + nsIWebProgress::NOTIFY_STATE_NETWORK); + } + void Unsubscribe(nsIWebProgress* aWebProgress) + { + MOZ_DIAGNOSTIC_ASSERT(mWeak); + mWeak = nullptr; + if (aWebProgress) { + aWebProgress->RemoveProgressListener(this); + } + } + + NS_IMETHODIMP OnStateChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aProgressStateFlags, + nsresult aStatus) override + { + MOZ_DIAGNOSTIC_ASSERT(mWeak); + if ((aProgressStateFlags & STATE_IS_NETWORK) && + (aProgressStateFlags & STATE_START)) { + // Query the LoadType to see if it's a ctrl+F5. + nsCOMPtr shell(do_QueryInterface(aWebProgress)); + if (shell) { + uint32_t loadType; + shell->GetLoadType(&loadType); + if (LOAD_RELOAD_BYPASS_PROXY_AND_CACHE == loadType && mWeak->mDecoder) { + mWeak->ShutdownDecoder(); + } + } + } + return NS_OK; + } + + NS_IMETHODIMP + OnProgressChange(nsIWebProgress* aProgress, + nsIRequest* aRequest, + int32_t aCurSelfProgress, + int32_t aMaxSelfProgress, + int32_t aCurTotalProgress, + int32_t aMaxTotalProgress) override + { + NS_NOTREACHED("notification excluded in AddProgressListener(...)"); + return NS_OK; + } + + NS_IMETHODIMP + OnLocationChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsIURI* aLocation, + uint32_t aFlags) override + { + NS_NOTREACHED("notification excluded in AddProgressListener(...)"); + return NS_OK; + } + + NS_IMETHODIMP + OnStatusChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsresult aStatus, + const char16_t* aMessage) override + { + NS_NOTREACHED("notification excluded in AddProgressListener(...)"); + return NS_OK; + } + + NS_IMETHODIMP + OnSecurityChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + uint32_t aState) override + { + NS_NOTREACHED("notification excluded in AddProgressListener(...)"); + return NS_OK; + } + +protected: + virtual ~ForceReloadListener() + { + MOZ_DIAGNOSTIC_ASSERT(!mWeak); + } + +private: + HTMLMediaElement* mWeak = nullptr; +}; + +NS_IMPL_ISUPPORTS(HTMLMediaElement::ForceReloadListener, + nsIWebProgressListener, + nsISupportsWeakReference) + HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNodeInfo) : nsGenericHTMLElement(aNodeInfo), mMainThreadEventTarget(OwnerDoc()->EventTargetFor(TaskCategory::Other)), @@ -3928,14 +4028,33 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNo mWatchManager.Watch(mReadyState, &HTMLMediaElement::UpdateReadyStateInternal); mShutdownObserver->Subscribe(this); + nsIDocShell* docShell = OwnerDoc()->GetDocShell(); + if (docShell) { + nsCOMPtr root; + docShell->GetSameTypeRootTreeItem(getter_AddRefs(root)); + nsCOMPtr webProgress = do_GetInterface(root); + if (webProgress) { + mForceReloadListener = new ForceReloadListener(); + mForceReloadListener->Subscribe(this, webProgress); + } + } } HTMLMediaElement::~HTMLMediaElement() { NS_ASSERTION(!mHasSelfReference, "How can we be destroyed if we're still holding a self reference?"); - mShutdownObserver->Unsubscribe(); + nsIDocShell* docShell = OwnerDoc()->GetDocShell(); + nsCOMPtr webProgress; + if (docShell) { + nsCOMPtr root; + docShell->GetSameTypeRootTreeItem(getter_AddRefs(root)); + webProgress = do_GetInterface(root); + } + if (mForceReloadListener) { + mForceReloadListener->Unsubscribe(webProgress); + } if (mVideoFrameContainer) { mVideoFrameContainer->ForgetElement(); diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index 87ac5d76ee43..12f6bf56e199 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -810,6 +810,7 @@ protected: class StreamListener; class StreamSizeListener; class ShutdownObserver; + class ForceReloadListener; MediaDecoderOwner::NextFrameStatus NextFrameStatus(); @@ -1391,6 +1392,7 @@ protected: RefPtr mSelectedVideoStreamTrack; const RefPtr mShutdownObserver; + RefPtr mForceReloadListener; // Holds a reference to the MediaSource, if any, referenced by the src // attribute on the media element.