diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 182183fc7e8..33d13c38b1f 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -540,7 +540,7 @@ void HTMLMediaElement::SetMozSrcObject(DOMMediaStream* aValue) { mSrcAttrStream = aValue; - Load(); + DoLoad(); } /* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */ @@ -784,8 +784,21 @@ void HTMLMediaElement::QueueSelectResourceTask() /* void load (); */ NS_IMETHODIMP HTMLMediaElement::Load() { - if (mIsRunningLoadMethod) + if (mIsRunningLoadMethod) { return NS_OK; + } + + mIsDoingExplicitLoad = true; + DoLoad(); + + return NS_OK; +} + +void HTMLMediaElement::DoLoad() +{ + if (mIsRunningLoadMethod) { + return; + } SetPlayedOrSeeked(false); mIsRunningLoadMethod = true; @@ -794,8 +807,6 @@ NS_IMETHODIMP HTMLMediaElement::Load() QueueSelectResourceTask(); ResetState(); mIsRunningLoadMethod = false; - - return NS_OK; } void HTMLMediaElement::ResetState() @@ -828,6 +839,7 @@ void HTMLMediaElement::SelectResourceWrapper() SelectResource(); mIsRunningSelectResource = false; mHaveQueuedSelectResource = false; + mIsDoingExplicitLoad = false; } void HTMLMediaElement::SelectResource() @@ -1108,7 +1120,12 @@ void HTMLMediaElement::UpdatePreloadAction() } } + if (nextAction == HTMLMediaElement::PRELOAD_NONE && mIsDoingExplicitLoad) { + nextAction = HTMLMediaElement::PRELOAD_METADATA; + } + mPreloadAction = nextAction; + if (nextAction == HTMLMediaElement::PRELOAD_ENOUGH) { if (mSuspendedForPreloadNone) { // Our load was previouly suspended due to the media having preload @@ -1649,10 +1666,7 @@ HTMLMediaElement::Pause(ErrorResult& aRv) { if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) { LOG(LogLevel::Debug, ("Loading due to Pause()")); - aRv = Load(); - if (aRv.Failed()) { - return; - } + DoLoad(); } else if (mDecoder) { mDecoder->Pause(); } @@ -2054,6 +2068,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNo mEventDeliveryPaused(false), mWaitingFired(false), mIsRunningLoadMethod(false), + mIsDoingExplicitLoad(false), mIsLoadingFromSourceChildren(false), mDelayingLoadEvent(false), mIsRunningSelectResource(false), @@ -2191,10 +2206,7 @@ HTMLMediaElement::Play(ErrorResult& aRv) SetPlayedOrSeeked(true); if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) { - aRv = Load(); - if (aRv.Failed()) { - return; - } + DoLoad(); } if (mSuspendedForPreloadNone) { ResumeLoad(PRELOAD_ENOUGH); @@ -2476,7 +2488,7 @@ nsresult HTMLMediaElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, if (NS_FAILED(rv)) return rv; if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) { - Load(); + DoLoad(); } if (aNotify && aNameSpaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::autoplay) { diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index 397afb8bbdd..c873334d30d 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -893,6 +893,13 @@ protected: // playback }; + /** + * The guts of Load(). Load() acts as a wrapper around this which sets + * mIsDoingExplicitLoad to true so that when script calls 'load()' + * preload-none will be automatically upgraded to preload-metadata. + */ + void DoLoad(); + /** * Suspends the load of mLoadingSrc, so that it can be resumed later * by ResumeLoad(). This is called when we have a media with a 'preload' @@ -1283,6 +1290,10 @@ protected: // True if we're running the "load()" method. bool mIsRunningLoadMethod; + // True if we're running or waiting to run queued tasks due to an explicit + // call to "load()". + bool mIsDoingExplicitLoad; + // True if we're loading the resource from the child source elements. bool mIsLoadingFromSourceChildren; diff --git a/dom/media/test/test_load.html b/dom/media/test/test_load.html index 16df4b3100f..f300ea57b1b 100644 --- a/dom/media/test/test_load.html +++ b/dom/media/test/test_load.html @@ -161,6 +161,18 @@ var gTests = [ document.body.appendChild(gMedia); }, expectedEvents: ['loadstart', 'source_error', 'source_error'] + }, { + // Test 6: (Bug 1165203) preload="none" then followed by an explicit + // call to load() should load metadata + create: + function(src, type) { + gMedia.preload = "none"; + gMedia.src = src; + document.body.appendChild(gMedia); + addSource(src, type); + gMedia.load(); + }, + expectedEvents: ['emptied', 'ratechange', 'loadstart', 'durationchange', 'loadedmetadata', 'loadeddata'] } ];