Bug 464398 - Stop HTML media elements from firing events in bfcache - r=roc a=blocking2.0

This commit is contained in:
Chris Double 2010-09-10 16:20:10 +12:00
Родитель 826171e87a
Коммит 3e62b1ddaf
2 изменённых файлов: 30 добавлений и 1 удалений

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

@ -191,6 +191,9 @@ public:
PRUint32 aFrameBufferLength, PRUint32 aFrameBufferLength,
PRUint64 aTime); PRUint64 aTime);
// Dispatch events that were raised while in the bfcache
nsresult DispatchPendingMediaEvents();
// Called by the decoder when some data has been downloaded or // Called by the decoder when some data has been downloaded or
// buffering/seeking has ended. aNextFrameAvailable is true when // buffering/seeking has ended. aNextFrameAvailable is true when
// the data for the next frame is available. This method will // the data for the next frame is available. This method will
@ -532,6 +535,10 @@ protected:
// we're bound to when loading starts. // we're bound to when loading starts.
nsCOMPtr<nsIDocument> mLoadBlockedDoc; nsCOMPtr<nsIDocument> mLoadBlockedDoc;
// Contains names of events that have been raised while in the bfcache.
// These events get re-dispatched when the bfcache is exited.
nsTArray<nsString> mPendingEvents;
// Media loading flags. See: // Media loading flags. See:
// http://www.whatwg.org/specs/web-apps/current-work/#video) // http://www.whatwg.org/specs/web-apps/current-work/#video)
nsMediaNetworkState mNetworkState; nsMediaNetworkState mNetworkState;

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

@ -59,8 +59,8 @@
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsIThreadInternal.h" #include "nsIThreadInternal.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsFrameManager.h"
#include "nsFrameManager.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "jsapi.h" #include "jsapi.h"
@ -2245,6 +2245,13 @@ nsresult nsHTMLMediaElement::DispatchEvent(const nsAString& aName)
LOG_EVENT(PR_LOG_DEBUG, ("%p Dispatching event %s", this, LOG_EVENT(PR_LOG_DEBUG, ("%p Dispatching event %s", this,
NS_ConvertUTF16toUTF8(aName).get())); NS_ConvertUTF16toUTF8(aName).get()));
// Save events that occur while in the bfcache. These will be dispatched
// if the page comes out of the bfcache.
if (mPausedForInactiveDocument) {
mPendingEvents.AppendElement(aName);
return NS_OK;
}
return nsContentUtils::DispatchTrustedEvent(GetOwnerDoc(), return nsContentUtils::DispatchTrustedEvent(GetOwnerDoc(),
static_cast<nsIContent*>(this), static_cast<nsIContent*>(this),
aName, aName,
@ -2262,6 +2269,20 @@ nsresult nsHTMLMediaElement::DispatchAsyncEvent(const nsAString& aName)
return NS_OK; return NS_OK;
} }
nsresult nsHTMLMediaElement::DispatchPendingMediaEvents()
{
NS_ASSERTION(!mPausedForInactiveDocument,
"Must not be in bfcache when dispatching pending media events");
PRUint32 count = mPendingEvents.Length();
for (PRUint32 i = 0; i < count; ++i) {
DispatchAsyncEvent(mPendingEvents[i]);
}
mPendingEvents.Clear();
return NS_OK;
}
PRBool nsHTMLMediaElement::IsPotentiallyPlaying() const PRBool nsHTMLMediaElement::IsPotentiallyPlaying() const
{ {
// TODO: // TODO:
@ -2312,6 +2333,7 @@ void nsHTMLMediaElement::NotifyOwnerDocumentActivityChanged()
mDecoder->Suspend(); mDecoder->Suspend();
} else { } else {
mDecoder->Resume(PR_FALSE); mDecoder->Resume(PR_FALSE);
DispatchPendingMediaEvents();
if (!mPaused && !mDecoder->IsEnded()) { if (!mPaused && !mDecoder->IsEnded()) {
mDecoder->Play(); mDecoder->Play();
} }