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']
}
];