Bug 792665. Stop allowing HTMLMediaElement.src = mediaStream, and support HTMLMediaElement.mozSrcObject = mediaStream instead. r=cpearce,jesup

--HG--
extra : rebase_source : 1986b88dc293939055b12ec7065c37dae394af8c
This commit is contained in:
Robert O'Callahan 2012-09-24 15:47:30 +12:00
parent e711b93859
commit 029e4c3706
9 changed files with 83 additions and 33 deletions

View File

@ -11,6 +11,7 @@
#include "nsIDocument.h"
#include "jsfriendapi.h"
#include "nsContentUtils.h"
#include "nsJSUtils.h"
using namespace mozilla::dom;
@ -93,9 +94,18 @@ nsHTMLAudioElement::Initialize(nsISupports* aOwner, JSContext* aContext,
return NS_OK;
}
// The only (optional) argument is the src of the audio (which can
// be a URL string or a MediaStream object)
return SetSrc(aContext, argv[0]);
// The only (optional) argument is the url of the audio
JSString* jsstr = JS_ValueToString(aContext, argv[0]);
if (!jsstr)
return NS_ERROR_FAILURE;
nsDependentJSString str;
if (!str.init(aContext, jsstr))
return NS_ERROR_FAILURE;
// The only (optional) argument is the src of the audio (which must
// be a URL string), used to initialize the 'src' attribute.
return SetSrc(str);
}
NS_IMETHODIMP

View File

@ -429,6 +429,8 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHTMLMediaElement)
NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
// nsIDOMHTMLMediaElement
NS_IMPL_URI_ATTR(nsHTMLMediaElement, Src, src)
NS_IMPL_STRING_ATTR(nsHTMLMediaElement, Crossorigin, crossorigin)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Controls, controls)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Loop, loop)
@ -436,47 +438,38 @@ NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, DefaultMuted, muted)
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, Preload, preload, NULL)
NS_IMETHODIMP
nsHTMLMediaElement::GetSrc(JSContext* aCtx, jsval *aParams)
nsHTMLMediaElement::GetMozSrcObject(JSContext* aCtx, jsval *aParams)
{
if (mSrcAttrStream) {
NS_ASSERTION(mSrcAttrStream->GetStream(), "MediaStream should have been set up properly");
return nsContentUtils::WrapNative(aCtx, JS_GetGlobalForScopeChain(aCtx),
mSrcAttrStream, aParams);
}
nsAutoString str;
nsresult rv = GetURIAttr(nsGkAtoms::src, nullptr, str);
NS_ENSURE_SUCCESS(rv, rv);
if (!xpc::StringToJsval(aCtx, str, aParams)) {
return NS_ERROR_FAILURE;
}
*aParams = JSVAL_NULL;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLMediaElement::SetSrc(JSContext* aCtx, const jsval & aParams)
nsHTMLMediaElement::SetMozSrcObject(JSContext* aCtx, const jsval & aParams)
{
if (aParams.isNull()) {
mSrcAttrStream = nullptr;
Load();
return NS_OK;
}
if (aParams.isObject()) {
nsCOMPtr<nsIDOMMediaStream> stream;
stream = do_QueryInterface(nsContentUtils::XPConnect()->
GetNativeOfWrapper(aCtx, JSVAL_TO_OBJECT(aParams)));
if (stream) {
mSrcAttrStream = static_cast<nsDOMMediaStream*>(stream.get());
UnsetAttr(kNameSpaceID_None, nsGkAtoms::src, true);
Load();
return NS_OK;
}
}
mSrcAttrStream = nullptr;
JSString* jsStr = JS_ValueToString(aCtx, aParams);
if (!jsStr)
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
nsDependentJSString str;
if (!str.init(aCtx, jsStr))
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
// Will trigger Load()
return SetAttrHelper(nsGkAtoms::src, str);
// Should we store unsupported values on the element's attribute anyway?
// Let's not.
return NS_OK;
}
/* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */
@ -1851,8 +1844,6 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
return NS_OK;
}
NS_IMPL_STRING_ATTR(nsHTMLMediaElement, Crossorigin, crossorigin)
bool nsHTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,

View File

@ -129,6 +129,7 @@ MOCHITEST_FILES = \
test_seekLies.html \
test_media_sniffer.html \
contentType.sjs \
test_streams_srcObject.html \
$(NULL)
$(warning test_error_in_video_document.html is disabled for intermittent failures. Bug 608634)

View File

@ -31,8 +31,8 @@ function startTest(test, token) {
v.src = test.name;
var stream = v.mozCaptureStreamUntilEnded();
is(stream.currentTime, 0, test.name + " stream initial currentTime");
vout.src = stream;
is(vout.src, stream, test.name + " set output element .src correctly");
vout.mozSrcObject = stream;
is(vout.mozSrcObject, stream, test.name + " set output element .srcObject correctly");
var checkEnded = function(test, vout, stream) { return function() {
is(stream.currentTime, vout.currentTime, test.name + " stream final currentTime");

View File

@ -17,8 +17,8 @@ SimpleTest.waitForExplicitFinish();
var v = document.getElementById('v');
var vout = document.getElementById('vout');
var vout_untilended = document.getElementById('vout_untilended');
vout.src = v.mozCaptureStream();
vout_untilended.src = v.mozCaptureStreamUntilEnded();
vout.mozSrcObject = v.mozCaptureStream();
vout_untilended.mozSrcObject = v.mozCaptureStreamUntilEnded();
function dumpEvent(event) {
dump("GOT EVENT " + event.type + " currentTime=" + event.target.currentTime +

View File

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test interactions of src and srcObject</title>
<script type="text/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>
</head>
<body onload="doTest()">
<audio id="a"></audio>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var a = document.getElementById('a');
a.src = getPlayableAudio(gSmallTests).name;
var b = new Audio();
function doTest() {
var newSrc = a.src + "?2";
b.src = newSrc;
is(b.mozSrcObject, null, "Initial srcObject is null");
var stream = a.mozCaptureStream();
b.mozSrcObject = stream;
is(b.mozSrcObject, stream, "Stream set correctly");
b.mozSrcObject = "invalid";
is(b.mozSrcObject, stream, "Stream not set to invalid value");
is(b.src, newSrc, "src attribute not affected by setting srcObject");
var step = 0;
b.addEventListener("loadedmetadata", function() {
if (step == 0) {
is(b.currentSrc, "", "currentSrc set to empty string while playing srcObject");
b.mozSrcObject = null;
is(b.mozSrcObject, null, "Stream set to null");
// The resource selection algorithm will run again and choose b.src
} else if (step == 1) {
is(b.currentSrc, b.src, "currentSrc set to src now that srcObject is null");
SimpleTest.finish();
}
++step;
});
}
</script>
</pre>
</body>
</html>

View File

@ -20,7 +20,7 @@
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(5fb3bed5-e9da-49ef-8488-ee3304db1a09)]
[scriptable, uuid(9e6cbf3e-4ae5-4a7b-a6ce-5af23572693f)]
interface nsIDOMHTMLAudioElement : nsIDOMHTMLMediaElement
{
// Setup the audio stream for writing

View File

@ -27,14 +27,15 @@ interface nsIDOMMediaStream;
#endif
%}
[scriptable, uuid(e901c0cb-0698-4470-b057-246f64fc7e57)]
[scriptable, uuid(f49b0fea-dc13-47bd-b43e-606044280741)]
interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
{
// error state
readonly attribute nsIDOMMediaError error;
// network state
[implicit_jscontext] attribute jsval src;
attribute DOMString src;
[implicit_jscontext] attribute jsval mozSrcObject;
readonly attribute DOMString currentSrc;
attribute DOMString crossorigin;
const unsigned short NETWORK_EMPTY = 0;

View File

@ -16,7 +16,7 @@
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(e277b2e8-074e-4c8d-a401-f327b5d477e3)]
[scriptable, uuid(1fb777fd-952a-4666-bb26-0b32acaf674d)]
interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
{
attribute long width;