Commit backout of 42c8cd0e1a65

This commit is contained in:
Chris Pearce 2010-08-18 13:59:10 +12:00
commit 1ab92508c3
15 changed files with 45 additions and 800 deletions

View File

@ -1812,6 +1812,7 @@ nsIAtom** const kDefaultAllowedAttributes [] = {
&nsGkAtoms::alt,
&nsGkAtoms::autocomplete,
#ifdef MOZ_MEDIA
&nsGkAtoms::autobuffer,
&nsGkAtoms::autoplay,
#endif
&nsGkAtoms::axis,
@ -1871,7 +1872,6 @@ nsIAtom** const kDefaultAllowedAttributes [] = {
&nsGkAtoms::pointSize,
#ifdef MOZ_MEDIA
&nsGkAtoms::poster,
&nsGkAtoms::preload,
#endif
&nsGkAtoms::prompt,
&nsGkAtoms::readonly,

View File

@ -120,6 +120,9 @@ GK_ATOM(attribute, "attribute")
GK_ATOM(attributeSet, "attribute-set")
GK_ATOM(aural, "aural")
GK_ATOM(_auto, "auto")
#ifdef MOZ_MEDIA
GK_ATOM(autobuffer, "autobuffer")
#endif
GK_ATOM(autocheck, "autocheck")
GK_ATOM(autocomplete, "autocomplete")
GK_ATOM(autofocus, "autofocus")
@ -761,9 +764,6 @@ GK_ATOM(preceding, "preceding")
GK_ATOM(precedingSibling, "preceding-sibling")
GK_ATOM(predicate, "predicate")
GK_ATOM(prefix, "prefix")
#ifdef MOZ_MEDIA
GK_ATOM(preload, "preload")
#endif
GK_ATOM(preserve, "preserve")
GK_ATOM(preserveSpace, "preserve-space")
GK_ATOM(preventdefault, "preventdefault")

View File

@ -430,51 +430,6 @@ protected:
* Called asynchronously to release a self-reference to this element.
*/
void DoRemoveSelfReference();
/**
* Possible values of the 'preload' attribute.
*/
enum PreloadAttrValue {
PRELOAD_ATTR_EMPTY, // set to ""
PRELOAD_ATTR_NONE, // set to "none"
PRELOAD_ATTR_METADATA, // set to "metadata"
PRELOAD_ATTR_AUTO // set to "auto"
};
/**
* The preloading action to perform. These dictate how we react to the
* preload attribute. See mPreloadAction.
*/
enum PreloadAction {
PRELOAD_UNDEFINED = 0, // not determined - used only for initialization
PRELOAD_NONE = 1, // do not preload
PRELOAD_METADATA = 2, // preload only the metadata (and first frame)
PRELOAD_ENOUGH = 3 // preload enough data to allow uninterrupted
// playback
};
/**
* Suspends the load of resource at aURI, so that it can be resumed later
* by ResumeLoad(). This is called when we have a media with a 'preload'
* attribute value of 'none', during the resource selection algorithm.
*/
void SuspendLoad(nsIURI* aURI);
/**
* Resumes a previously suspended load (suspended by SuspendLoad(uri)).
* Will continue running the resource selection algorithm.
* Sets mPreloadAction to aAction.
*/
void ResumeLoad(PreloadAction aAction);
/**
* Handle a change to the preload attribute. Should be called whenever the
* value (or presence) of the preload attribute changes. The change in
* attribute value may cause a change in the mPreloadAction of this
* element. If there is a change then this method will initiate any
* behaviour that is necessary to implement the action.
*/
void UpdatePreloadAction();
nsRefPtr<nsMediaDecoder> mDecoder;
@ -527,23 +482,10 @@ protected:
// Current audio volume
float mVolume;
// If we're loading a preload:none media, we'll record the URI we're
// attempting to load in mPreloadURI, and delay loading the resource until
// the user initiates a load by either playing the resource, or explicitly
// loading it.
nsCOMPtr<nsIURI> mPreloadURI;
// Stores the current preload action for this element. Initially set to
// PRELOAD_UNDEFINED, its value is changed by calling
// UpdatePreloadAction().
PreloadAction mPreloadAction;
// Size of the media. Updated by the decoder on the main thread if
// it changes. Defaults to a width and height of -1 if not set.
nsIntSize mMediaSize;
nsRefPtr<gfxASurface> mPrintSurface;
// If true then we have begun downloading the media content.
// Set to false when completed, or not yet started.
PRPackedBool mBegun;
@ -609,13 +551,11 @@ protected:
PRPackedBool mIsRunningSelectResource;
// PR_TRUE if we suspended the decoder because we were paused,
// preloading metadata is enabled, autoplay was not enabled, and we loaded
// the first frame.
// autobuffer and autoplay were not set, and we loaded the first frame.
PRPackedBool mSuspendedAfterFirstFrame;
// PR_TRUE if we are allowed to suspend the decoder because we were paused,
// preloading metdata was enabled, autoplay was not enabled, and we loaded
// the first frame.
// autobuffer and autoplay were not set, and we loaded the first frame.
PRPackedBool mAllowSuspendAfterFirstFrame;
// PR_TRUE if we've played or completed a seek. We use this to determine
@ -631,11 +571,7 @@ protected:
// down.
PRPackedBool mShuttingDown;
// PR_TRUE if we've suspended a load in the resource selection algorithm
// due to loading a preload:none media. When PR_TRUE, the resource we'll
// load when the user initiates either playback or an explicit load is
// stored in mPreloadURI.
PRPackedBool mLoadIsSuspended;
nsRefPtr<gfxASurface> mPrintSurface;
};
#endif

View File

@ -120,10 +120,9 @@ nsHTMLAudioElement::Initialize(nsISupports* aOwner, JSContext* aContext,
JSObject *aObj, PRUint32 argc, jsval *argv)
{
// Audio elements created using "new Audio(...)" should have
// 'preload' set to 'auto' (since the script must intend to
// play the audio)
nsresult rv = SetAttr(kNameSpaceID_None, nsGkAtoms::preload,
NS_LITERAL_STRING("auto"), PR_TRUE);
// 'autobuffer' set (since the script must intend to play the audio)
nsresult rv = SetAttr(kNameSpaceID_None, nsGkAtoms::autobuffer,
NS_LITERAL_STRING("autobuffer"), PR_TRUE);
if (NS_FAILED(rv))
return rv;

View File

@ -398,7 +398,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
NS_IMPL_URI_ATTR(nsHTMLMediaElement, Src, src)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Controls, controls)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
NS_IMPL_STRING_ATTR(nsHTMLMediaElement, Preload, preload)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autobuffer, autobuffer)
/* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */
NS_IMETHODIMP nsHTMLMediaElement::GetMozAutoplayEnabled(PRBool *aAutoplayEnabled)
@ -610,13 +610,6 @@ void nsHTMLMediaElement::SelectResource()
if (NS_SUCCEEDED(rv)) {
LOG(PR_LOG_DEBUG, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get()));
mIsLoadingFromSrcAttribute = PR_TRUE;
if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad(uri);
return;
}
rv = LoadResource(uri);
if (NS_SUCCEEDED(rv))
return;
@ -654,13 +647,6 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad(uri);
return;
}
rv = LoadResource(uri);
if (NS_SUCCEEDED(rv))
return;
@ -670,110 +656,6 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
NS_NOTREACHED("Execution should not reach here!");
}
void nsHTMLMediaElement::SuspendLoad(nsIURI* aURI)
{
mLoadIsSuspended = PR_TRUE;
mPreloadURI = aURI;
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
DispatchAsyncProgressEvent(NS_LITERAL_STRING("suspend"));
ChangeDelayLoadStatus(PR_FALSE);
}
void nsHTMLMediaElement::ResumeLoad(PreloadAction aAction)
{
NS_ASSERTION(mLoadIsSuspended, "Can only resume preload if halted for one");
nsCOMPtr<nsIURI> uri = mPreloadURI;
mLoadIsSuspended = PR_FALSE;
mPreloadURI = nsnull;
mPreloadAction = aAction;
ChangeDelayLoadStatus(PR_TRUE);
if (mIsLoadingFromSrcAttribute) {
// We were loading from the element's src attribute.
if (NS_FAILED(LoadResource(uri))) {
NoSupportedMediaSourceError();
}
} else {
// We were loading from a child <source> element. Try to resume the
// load of that child, and if that fails, try the next child.
if (NS_FAILED(LoadResource(uri))) {
LoadFromSourceChildren();
}
}
}
static PRBool IsAutoplayEnabled()
{
return nsContentUtils::GetBoolPref("media.autoplay.enabled");
}
void nsHTMLMediaElement::UpdatePreloadAction()
{
PreloadAction nextAction = PRELOAD_UNDEFINED;
// If autoplay is set, we should always preload data, as we'll need it
// to play.
if (IsAutoplayEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) {
nextAction = nsHTMLMediaElement::PRELOAD_ENOUGH;
} else {
// Find the appropriate preload action by looking at the attribute.
const nsAttrValue* val = mAttrsAndChildren.GetAttr(nsGkAtoms::preload,
kNameSpaceID_None);
if (!val) {
// Attribute is not set. The default is to load metadata.
nextAction = nsHTMLMediaElement::PRELOAD_METADATA;
} else if (val->Type() == nsAttrValue::eEnum) {
PreloadAttrValue attr = static_cast<PreloadAttrValue>(val->GetEnumValue());
if (attr == nsHTMLMediaElement::PRELOAD_ATTR_EMPTY ||
attr == nsHTMLMediaElement::PRELOAD_ATTR_AUTO)
{
nextAction = nsHTMLMediaElement::PRELOAD_ENOUGH;
} else if (attr == nsHTMLMediaElement::PRELOAD_ATTR_METADATA) {
nextAction = nsHTMLMediaElement::PRELOAD_METADATA;
} else if (attr == nsHTMLMediaElement::PRELOAD_ATTR_NONE) {
nextAction = nsHTMLMediaElement::PRELOAD_NONE;
}
} else {
// There was a value, but it wasn't an enumerated value.
// Use the suggested "missing value default" of "metadata".
nextAction = nsHTMLMediaElement::PRELOAD_METADATA;
}
}
if ((mBegun || mIsRunningSelectResource) && nextAction < mPreloadAction) {
// We've started a load or are already downloading, and the preload was
// changed to a state where we buffer less. We don't support this case,
// so don't change the preload behaviour.
return;
}
PRBool wasPreloadNone = mPreloadAction == PRELOAD_NONE;
mPreloadAction = nextAction;
if (nextAction == nsHTMLMediaElement::PRELOAD_ENOUGH) {
if (mLoadIsSuspended) {
// Our load was previouly suspended due to the media having preload
// value "none". The preload value has changed to preload:auto, so
// resume the load.
ResumeLoad(PRELOAD_ENOUGH);
} else {
// Preload as much of the video as we can, i.e. don't suspend after
// the first frame.
StopSuspendingAfterFirstFrame();
}
} else if (nextAction == nsHTMLMediaElement::PRELOAD_METADATA) {
// Ensure that the video can be suspended after first frame.
mAllowSuspendAfterFirstFrame = PR_TRUE;
if (mLoadIsSuspended) {
// Our load was previouly suspended due to the media having preload
// value "none". The preload value has changed to preload:metadata, so
// resume the load. We'll pause the load again after we've read the
// metadata.
ResumeLoad(PRELOAD_METADATA);
}
}
return;
}
nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
{
NS_ASSERTION(mDelayingLoadEvent,
@ -1112,9 +994,7 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
mAllowSuspendAfterFirstFrame(PR_TRUE),
mHasPlayedOrSeeked(PR_FALSE),
mHasSelfReference(PR_FALSE),
mShuttingDown(PR_FALSE),
mPreloadAction(PRELOAD_UNDEFINED),
mLoadIsSuspended(PR_FALSE)
mShuttingDown(PR_FALSE)
{
#ifdef PR_LOGGING
if (!gMediaElementLog) {
@ -1179,8 +1059,6 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
nsresult rv = Load();
NS_ENSURE_SUCCESS(rv, rv);
} else if (mLoadIsSuspended) {
ResumeLoad(PRELOAD_ENOUGH);
} else if (mDecoder) {
if (mDecoder->IsEnded()) {
SetCurrentTime(0);
@ -1221,15 +1099,6 @@ PRBool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
const nsAString& aValue,
nsAttrValue& aResult)
{
// Mappings from 'preload' attribute strings to an enumeration.
static const nsAttrValue::EnumTable kPreloadTable[] = {
{ "", nsHTMLMediaElement::PRELOAD_ATTR_EMPTY },
{ "none", nsHTMLMediaElement::PRELOAD_ATTR_NONE },
{ "metadata", nsHTMLMediaElement::PRELOAD_ATTR_METADATA },
{ "auto", nsHTMLMediaElement::PRELOAD_ATTR_AUTO },
{ 0 }
};
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::src) {
static const char* kWhitespace = " \n\r\t\b";
@ -1245,9 +1114,6 @@ PRBool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
else if (ParseImageAttribute(aAttribute, aValue, aResult)) {
return PR_TRUE;
}
else if (aAttribute == nsGkAtoms::preload) {
return aResult.ParseEnumValue(aValue, kPreloadTable, PR_FALSE);
}
}
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
@ -1261,8 +1127,6 @@ nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsresult rv =
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
aNotify);
if (NS_FAILED(rv))
return rv;
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
if (aName == nsGkAtoms::src) {
if (mLoadWaitStatus == WAITING_FOR_SRC_OR_SOURCE) {
@ -1279,9 +1143,8 @@ nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
}
// This attribute can affect AddRemoveSelfReference
AddRemoveSelfReference();
UpdatePreloadAction();
} else if (aName == nsGkAtoms::preload) {
UpdatePreloadAction();
} else if (aName == nsGkAtoms::autobuffer) {
StopSuspendingAfterFirstFrame();
}
}
@ -1292,21 +1155,23 @@ nsresult nsHTMLMediaElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
PRBool aNotify)
{
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttr, aNotify);
if (NS_FAILED(rv))
return rv;
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
if (aAttr == nsGkAtoms::autoplay) {
// This attribute can affect AddRemoveSelfReference
AddRemoveSelfReference();
UpdatePreloadAction();
} else if (aAttr == nsGkAtoms::preload) {
UpdatePreloadAction();
}
// We perhaps should stop loading if 'autobuffer' is being removed,
// and we're buffering only because of 'autobuffer', but why bother?
}
return rv;
}
static PRBool IsAutoplayEnabled()
{
return nsContentUtils::GetBoolPref("media.autoplay.enabled");
}
nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
@ -1315,9 +1180,6 @@ nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aPar
mIsBindingToTree = PR_TRUE;
mAutoplayEnabled =
IsAutoplayEnabled() && (!aDocument || !aDocument->IsStaticDocument());
// The preload action depends on the value of the autoplay attribute.
// It's value may have changed, so update it.
UpdatePreloadAction();
}
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument,
aParent,
@ -1779,7 +1641,7 @@ void nsHTMLMediaElement::FirstFrameLoaded(PRBool aResourceFullyLoaded)
if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
!aResourceFullyLoaded &&
!HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
mPreloadAction == nsHTMLMediaElement::PRELOAD_METADATA) {
!HasAttr(kNameSpaceID_None, nsGkAtoms::autobuffer)) {
mSuspendedAfterFirstFrame = PR_TRUE;
mDecoder->Suspend();
}
@ -2082,7 +1944,6 @@ nsresult nsHTMLMediaElement::DoneAddingChildren(PRBool aHaveNotified)
if (!mIsDoneAddingChildren) {
mIsDoneAddingChildren = PR_TRUE;
UpdatePreloadAction();
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
QueueSelectResourceTask();
}

View File

@ -91,6 +91,7 @@ _TEST_FILES = \
test_access_control.html \
test_audio1.html \
test_audio2.html \
test_autobuffer.html \
test_autoplay.html \
test_buffered.html \
test_bug448534.html \
@ -146,7 +147,7 @@ _TEST_FILES = \
# Bug 492821:
# test_videoDocumentTitle.html
# Bug 493692:
# test_preload_suspend.html
# test_autobuffer2.html
# Disabled since we don't play Wave files standalone, for now
# test_audioDocumentTitle.html

View File

@ -16,7 +16,7 @@ for (var i = 0; i < gAudioTests.length; ++i) {
if (!a1.canPlayType(test.type))
continue;
is(a1.getAttribute("preload"), "auto", "preload:auto automatically set");
is(a1.getAttribute("autobuffer"), "autobuffer", "Autobuffer automatically set");
is(a1.src, "", "Src set?");
}
</script>

View File

@ -17,7 +17,7 @@ for (var i = 0; i < gAudioTests.length; ++i) {
continue;
var a1 = new Audio(test.name);
is(a1.getAttribute("preload"), "auto", "Preload automatically set to auto");
is(a1.getAttribute("autobuffer"), "autobuffer", "Autobuffer automatically set");
is(a1.src.match("/[^/]+$"), "/" + test.name, "src OK");
}
</script>

View File

@ -18,8 +18,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=479863
<video id='v1' onerror="event.stopPropagation();"></video><audio id='a1' onerror="ev
ent.stopPropagation();"></audio>
<video id='v2' onerror="event.stopPropagation();" preload="auto"></video><audio id='a2' on
error="event.stopPropagation();" preload="auto"></audio>
<video id='v2' onerror="event.stopPropagation();" autobuffer></video><audio id='a2' on
error="event.stopPropagation();" autobuffer></audio>
<pre id="test">
<script type="application/javascript">
@ -27,19 +27,17 @@ var v1 = document.getElementById('v1');
var a1 = document.getElementById('a1');
var v2 = document.getElementById('v2');
var a2 = document.getElementById('a2');
is(v1.getAttribute("preload"), undefined, "video preload via getAttribute should be undefined by default");
is(a1.getAttribute("preload"), undefined, "video preload via getAttribute should be undefined by default");
is(v1.preload, "", "v1.preload should be undefined by default");
is(a1.preload, "", "a1.preload should be undefined by default");
is(v2.preload, "auto", "v2.preload should be auto");
is(a2.preload, "auto", "a2.preload should be auto");
ok(!v1.autobuffer, "v1.autobuffer should be false by default");
ok(!a1.autobuffer, "v1.autobuffer should be false by default");
ok(v2.autobuffer, "v2.autobuffer should be true");
ok(a2.autobuffer, "v2.autobuffer should be true");
v1.preload = "auto";
a1.preload = "auto";
is(v1.preload, "auto", "video.preload should be auto");
is(a1.preload, "auto", "audio.preload should be auto");
is(v1.getAttribute("preload"), "auto", "video preload attribute should be auto");
is(a1.getAttribute("preload"), "auto", "video preload attribute should be auto");
v1.autobuffer = true;
a1.autobuffer = true;
ok(v1.autobuffer, "video.autobuffer not true");
ok(a1.autobuffer, "audio.autobuffer not true");
is(v1.getAttribute("autobuffer"), "", "video autobuffer attribute not set");
is(a1.getAttribute("autobuffer"), "", "video autobuffer attribute not set");
</script>
</pre>

View File

@ -18,7 +18,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=479863
</div>
<video id='v1' onerror="event.stopPropagation()"></video>
<video id='v2' onerror="event.stopPropagation()" preload="auto"></video>
<video id='v2' onerror="event.stopPropagation()" autobuffer></video>
<video id='v3' onerror="event.stopPropagation()" autoplay></video>
<video id='v4' onerror="event.stopPropagation()"></video>
<video id='v5' onerror="event.stopPropagation()"></video>
@ -26,8 +26,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=479863
<pre id="test">
<script type="application/javascript">
function is() {}
var suspendCount = {};
var expectedSuspendCount = {v1:2, v2:1, v3:1, v4:2, v5:2, v6:2};
var totalSuspendCount = 0;
@ -60,7 +58,7 @@ function suspended(event) {
return;
if (event.target.id == "v1") {
event.target.preload = "auto";
event.target.autobuffer = true;
} else if (event.target.id == "v4") {
event.target.play();
} else if (event.target.id == "v5") {

View File

@ -54,7 +54,7 @@ for (var i=0; i<gSeekTests.length; ++i) {
v._name = test.name;
v._seeked = false;
v._finished = false;
v.preload = "auto";
v.autobuffer = true;
v.addEventListener("loadedmetadata", start, false);
v.addEventListener("canplaythrough", canPlayThrough, false);
v.addEventListener("seeking", startSeeking, false);

View File

@ -52,7 +52,7 @@ var gMedia = null;
function createMedia(tag) {
gMedia = document.createElement(tag);
gMedia.setAttribute("preload", "auto");
gMedia.setAttribute("autobuffer", "true");
for (var i=0; i<gEventTypes.length; i++) {
gMedia.addEventListener(gEventTypes[i], listener, false);
}

View File

@ -1,548 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=548523
-->
<head>
<title>Test for Bug 548523</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="manifest.js"></script>
<script type="text/javascript" src="use_large_cache.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=548523">Mozilla Bug 548523</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<!-- <button onClick="SimpleTest.finish();">Finish</button> -->
<div>Tests complete: <span id="log" style="font-size: small;"></span></div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 548523 **/
var videos = [];
var test = getPlayableVideo(gSeekTests);
var bogusSrc = "bogus.duh";
var bogusType = "video/bogus";
var gotLoadEvent = false;
var finished = false;
addLoadEvent(function() {gotLoadEvent=true;});
function log(m) {
var l = document.getElementById("log");
l.innerHTML += m;
}
function maybeFinish(n) {
log(n + ",");
setTimeout(
function() {
if (!finished && AllFinished(videos)) {
finished = true;
is(gotLoadEvent, true, "Should not have delayed the load event indefinitely");
SimpleTest.finish();
}
}, 0);
}
function filename(uri) {
return uri.substr(uri.lastIndexOf("/")+1);
}
// Every test must have a setup(v) function, and must set _finished field on target v to
// true when test is complete.
var tests = [
{
// 1. Add preload:none video with src to document. Load should halt at NETWORK_IDLE and HAVE_NOTHING,
// after receiving a suspend event. Should not receive loaded events until after we call load().
// Note the suspend event is explictly sent by our "stop the load" code, but other tests can't rely
// on it for the preload:metadata case, as there can be multiple suspend events when loading metadata.
suspend:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(1) Must get loadstart.");
is(v._gotLoadedMetaData, false, "(1) Must not get loadedmetadata.");
is(v.readyState, v.HAVE_NOTHING, "(1) ReadyState must be HAVE_NOTHING");
is(v.networkState, v.NETWORK_IDLE, "(1) NetworkState must be NETWORK_IDLE");
v._finished = true;
maybeFinish(1);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("suspend", this.suspend, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none.
},
},
{
// 2. Add preload:metadata video with src to document. Should halt with NETWORK_IDLE, HAVE_CURRENT_DATA
// after suspend event and after loadedmetadata.
loadeddata:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(2) Must get loadstart.");
is(v._gotLoadedMetaData, true, "(2) Must get loadedmetadata.");
ok(v.readyState >= v.HAVE_CURRENT_DATA, "(2) ReadyState must be >= HAVE_CURRENT_DATA");
is(v.networkState, v.NETWORK_IDLE, "(2) NetworkState must be NETWORK_IDLE");
v._finished = true;
maybeFinish(2);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "metadata";
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadeddata", this.loadeddata, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load, which will be halted after
// metadata due to preload:metadata.
},
},
{
// 3. Add preload:auto to document. Should receive canplaythrough eventually.
canplaythrough:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(3) Must get loadstart.");
is(v._gotLoadedMetaData, true, "(3) Must get loadedmetadata.");
v._finished = true;
maybeFinish(3);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "auto";
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("canplaythrough", this.canplaythrough, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
},
},
{
// 4. Add preload:none video to document. Call play(), should load then play through.
suspend:
function(e) {
var v = e.target;
if (v._gotSuspend)
return; // We can receive multiple suspend events, like the one after download completes.
v._gotSuspend = true;
is(v._gotLoadStart, true, "(4) Must get loadstart.");
is(v._gotLoadedMetaData, false, "(4) Must not get loadedmetadata.");
is(v.readyState, v.HAVE_NOTHING, "(4) ReadyState must be HAVE_NOTHING");
is(v.networkState, v.NETWORK_IDLE, "(4) NetworkState must be NETWORK_IDLE");
v.play(); // Should load and play through.
},
ended:
function(e) {
ok(true, "(4) Got playback ended");
e.target._finished = true;
maybeFinish(4);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._gotSuspend = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("suspend", this.suspend, false);
v.addEventListener("ended", this.ended, false);
v.src = test.name;
document.body.appendChild(v);
},
},
{
// 5. preload:none video without resource, add to document, will implicitly start a
// preload:none load. Add a src, it shouldn't load.
suspend:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(5) Must get loadstart.");
is(v._gotLoadedMetaData, false, "(5) Must not get loadedmetadata.");
is(v.readyState, v.HAVE_NOTHING, "(5) ReadyState must be HAVE_NOTHING");
is(v.networkState, v.NETWORK_IDLE, "(5) NetworkState must be NETWORK_IDLE");
v._finished = true;
maybeFinish(5);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("suspend", this.suspend, false);
document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource.
v.src = test.name; // Load should start, and halt at preload:none.
},
},
{
// 6. preload:none video without resource, add to document, will implicitly start a
// preload:none load. Add a source, it shouldn't load.
suspend:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(6) Must get loadstart.");
is(v._gotLoadedMetaData, false, "(6) Must not get loadedmetadata.");
is(v.readyState, v.HAVE_NOTHING, "(6) ReadyState must be HAVE_NOTHING");
is(v.networkState, v.NETWORK_IDLE, "(6) NetworkState must be NETWORK_IDLE");
v._finished = true;
maybeFinish(6);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("suspend", this.suspend, false);
document.body.appendChild(v); // Causes implicit load, which will be halted due to no resource.
var s = document.createElement("source");
s.src = test.name;
s.type = test.type;
v.appendChild(s); // Load should start, and halt at preload:none.
},
},
{
// 7. create a preload:none document with multiple sources, the first of which is invalid.
// Add to document, then play. It should load and play through the second source.
suspend:
function(e) {
var v = e.target;
if (v._gotSuspend)
return; // We can receive multiple suspend events, like the one after download completes.
v._gotSuspend = true;
is(v._gotLoadStart, true, "(7) Must get loadstart.");
is(v._gotLoadedMetaData, false, "(7) Must not get loadedmetadata.");
is(v.readyState, v.HAVE_NOTHING, "(7) ReadyState must be HAVE_NOTHING");
is(v.networkState, v.NETWORK_IDLE, "(7) NetworkState must be NETWORK_IDLE");
v.play(); // Should load and play through.
},
ended:
function(e) {
ok(true, "(7) Got playback ended");
e.target._finished = true;
maybeFinish(7);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("suspend", this.suspend, false);
v.addEventListener("ended", this.ended, false);
var s1 = document.createElement("source");
s1.src = "not-a-real-file.404"
s1.type = test.type;
v.appendChild(s1);
var s2 = document.createElement("source");
s2.src = test.name;
s2.type = test.type;
v.appendChild(s2);
document.body.appendChild(v); // Causes implicit load, which will be halt at preload:none on the second resource.
},
},
{
// 8. Change preload value from none to metadata should cause metadata to be loaded.
loadeddata:
function(e) {
var v = e.target;
is(v._gotLoadedMetaData, true, "(8) Must get loadedmetadata.");
ok(v.readyState >= v.HAVE_CURRENT_DATA, "(8) ReadyState must be >= HAVE_CURRENT_DATA on suspend.");
is(v.networkState, v.NETWORK_IDLE, "(8) NetworkState must be NETWORK_IDLE when load is halted");
v._finished = true;
maybeFinish(8);
},
setup:
function(v) {
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadstart", function(e){v.preload = "metadata";}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadeddata", this.loadeddata, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
},
},
{
// 9. Change preload value from metadata to auto should cause entire media to be loaded.
canplaythrough:
function(e) {
var v = e.target;
if (v._finished)
return;
is(v._gotLoadStart, true, "(9) Must get loadstart.");
is(v._gotLoadedMetaData, true, "(9) Must get loadedmetadata.");
v._finished = true;
maybeFinish(9);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "metadata";
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadeddata", function(){v.preload = "auto"}, false);
v.addEventListener("canplaythrough", this.canplaythrough, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
},
},
{
// 10. Change preload value from none to auto should cause entire media to be loaded.
canplaythrough:
function(e) {
var v = e.target;
is(v._gotLoadedMetaData, true, "(10) Must get loadedmetadata.");
v._finished = true;
maybeFinish(10);
},
setup:
function(v) {
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadstart", function(e){v.preload = "auto";}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("canplaythrough", this.canplaythrough, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
},
},
{
// 11. Change preload value from none to metadata should cause metadata to load.
loadeddata:
function(e) {
var v = e.target;
is(v._gotLoadedMetaData, true, "(11) Must get loadedmetadata.");
ok(v.readyState >= v.HAVE_CURRENT_DATA, "(11) ReadyState must be >= HAVE_CURRENT_DATA.");
is(v.networkState, v.NETWORK_IDLE, "(11) NetworkState must be NETWORK_IDLE.");
v._finished = true;
maybeFinish(11);
},
setup:
function(v) {
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.addEventListener("loadstart", function(e){v.preload = "metadata";}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadeddata", this.loadeddata, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
},
},
{
// 12. Change preload value from auto to metadata after load started,
// should still do full load, should not halt after metadata only.
canplaythrough:
function(e) {
var v = e.target;
is(v._gotLoadedMetaData, true, "(12) Must get loadedmetadata.");
is(v._gotLoadStart, true, "(12) Must get loadstart.");
v._finished = true;
maybeFinish(12);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "auto";
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("canplaythrough", this.canplaythrough, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
v.preload = "metadata";
},
},
{
// 13. Change preload value from metadata to none after load started,
// should still load up to metadata, should not halt immediately.
loadeddata:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(13) Must get loadstart.");
is(v._gotLoadedMetaData, true, "(13) Must get loadedmetadata.");
ok(v.readyState >= v.HAVE_CURRENT_DATA, "(13) ReadyState must be >= HAVE_CURRENT_DATA.");
is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE.");
v._finished = true;
maybeFinish(13);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "metadata";
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadeddata", this.loadeddata, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
v.preload = "none";
},
},
{
// 14. Add preload:metadata video with src to document. Play(), should play through.
loadeddata:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(14) Must get loadstart.");
is(v._gotLoadedMetaData, true, "(14) Must get loadedmetadata.");
ok(v.readyState >= v.HAVE_CURRENT_DATA, "(14) ReadyState must be >= HAVE_CURRENT_DATA");
is(v.networkState, v.NETWORK_IDLE, "(14) NetworkState must be NETWORK_IDLE");
v.play();
},
ended:
function(e) {
ok(true, "(14) Got playback ended");
e.target._finished = true;
maybeFinish(14);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "metadata";
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("ended", this.ended, false);
v.addEventListener("loadeddata", this.loadeddata, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load, which will be halted after
// metadata due to preload:metadata.
},
},
{
// 15. Autoplay should override preload:none.
ended:
function(e) {
ok(true, "(15) Got playback ended.");
e.target._finished = true;
maybeFinish(15);
},
setup:
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v._finished = false;
v.preload = "none";
v.autoplay = true;
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("ended", this.ended, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
},
},
{
// 16. Autoplay should override preload:metadata.
ended:
function(e) {
ok(true, "(16) Got playback ended.");
e.target._finished = true;
maybeFinish(16);
},
setup:
function(v) {
v._finished = false;
v.preload = "metadata";
v.autoplay = true;
v.addEventListener("ended", this.ended, false);
v.src = test.name;
document.body.appendChild(v); // Causes implicit load.
},
},
{
// 17. On a preload:none video, adding autoplay should disable preload none, i.e. don't break autoplay!
ended:
function(e) {
ok(true, "(17) Got playback ended.");
e.target._finished = true;
maybeFinish(17);
},
setup:
function(v) {
v.addEventListener("ended", this.ended, false);
v._finished = false;
v.preload = "none";
document.body.appendChild(v); // Causes implicit load, which will be halted due to preload:none.
v.autoplay = true;
v.src = test.name;
},
},
];
if (test) {
for (var i=0; i<tests.length; i++) {
var t = tests[i];
var v = document.createElement("video");
videos.push(v);
t.setup(v);
}
}
if (test && videos.length == 0) {
todo(false, "No types or tests supported");
} else {
SimpleTest.waitForExplicitFinish();
}
</script>
</pre>
</body>
</html>

View File

@ -7,7 +7,7 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<audio preload="auto" id="a"></audio>
<audio autobuffer id="a"></audio>
<iframe id="f"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">

View File

@ -57,7 +57,7 @@
#endif
%}
[scriptable, uuid(925c46e0-3795-11df-9879-0800200c9a66)]
[scriptable, uuid(b6c9f51d-237c-44d1-842d-996f4d62c843)]
interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
{
// error state
@ -72,7 +72,6 @@ interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
const unsigned short NETWORK_LOADED = 3;
const unsigned short NETWORK_NO_SOURCE = 4;
readonly attribute unsigned short networkState;
attribute DomString preload;
readonly attribute nsIDOMHTMLTimeRanges buffered;
void load();
DOMString canPlayType(in DOMString type);
@ -93,6 +92,7 @@ interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
readonly attribute boolean ended;
readonly attribute boolean mozAutoplayEnabled;
attribute boolean autoplay;
attribute boolean autobuffer;
void play();
void pause();