Re: Media elements may never load, may load the wrong source, etc

On Sat, 06 Jun 2009 02:56:26 +0200, Ian Hickson <ian@hixie.ch> wrote:

> On Wed, 6 May 2009, Philip Jägenstedt wrote:
>> >
>> > I agree that we want predictable behaviour. I've added predictable
>> > behaviour, but in the example above the first src="" value is the one
>> > that is used, not the one after it is changed. Each change of src=""
>> > requires a new invokation of load().
>> >
>> > The same kind of thing can happen if a <source> is inserted then
>> > removed. While preventing any kind of weirdness here is nigh on
>> > impossible (if someone adds then removes then changes the attributes,
>> > keeping track of which src="" we're supposed to load would be a
>> > nightmare), I have at least made it so that the browser will wait til
>> > any scripts have stopped fiddling before trying to apply the next
>> > <source> element.
>>
>> This is an improvement in predictability, but implementing it turns out
>> to be unnecessarily painful... Manipulating src should pin down the
>> resource immediately (resolving the URL, as later we must know the "the
>> absolute URL that would have resulted"). Manipulating <source> should
>> however effectively wait until the current script has finished before
>> running the search loop.
>
> More than that, it has to wait until the 'loadstart' event has fired.

Not really, loadstart (step 3) is after the async boundary part so the
event is just queued and the algorithm continues at step 4.

>> It would be much easier if one could always wait with checking
>> src/source until the running script has finished. This makes for less
>> special cases and less state to remember across the sync/async boundary.
>
> The problem is that the behaviour with <source> is highly volatile. We
> can't remove this volatility for <source> easily, but we _can_ remove it
> for src="".
>
> If we don't use the first value for src="", then we end up in a weird
> position where you can't predict which value of src="" will be used if,
> e.g., there is a setInterval() script running that keeps changing it,
> because the tasks scheduled by the setInterval() script and the tasks
> scheduled by the resource selection algorithm are from different task
> sources and thus don't have a defined order.

This is not a problem in actual implementation as the async part is simply
run once the script triggering the resource selection algorithm has
finished. Other implementations are possible *per spec*, but it would be  
asking for cross-browser compatibility bugs to wait any longer as it would  
cause the same unpredictable behavior with <source> elements (if a  
playable <source> element is added and later removed in a timeout).

>> A curious side-effect of the current assymetry is that changing xml:base
>> or <base> after src="" (even immediately in the same script) should have
>> no effect, but the same isn't true of <source> elements. Of course I'm
>> biased as I don't want to implement the spec as written, but wouldn't
>> consistent behavior here be better?
>
> Yes, but not at the price of making src="" less predictable, IMHO.

I disagree about predictability, as per above.

>> Unless there's a compelling case for pinning down src on first change,
>> I'd strongly prefer if the "let src equal the first value that was
>> assigned" part was revoked and that any tasks that could change the
>> outcome of the asynchronous part of the algorithm are allowed to
>> complete before step 3 (i.e. let the current script finish, using
>> whatever terminology).
>
> What should we do if someone, in one task, sets the src="", then removes
> it, then inserts a <source>, then removes it?

Since we also suggest getting rid of NETWORK_NO_SOURCE, the whole resource  
selection algorithm would be slightly different, something like:

1. While the media element has neither a src attribute nor any source  
element children, wait.

2. Before the task that set the src attribute or inserted the source  
element has a chance to complete, set the media element's  
delaying-the-load-event flag to true (this delays the load event), and set  
its networkState to NETWORK_LOADING. Wait for the task that set the src  
attribute or inserted the source element to complete.

It then continues approximately the same from there, except that the
the later waiting steps return to step 1. In this way, adding/removing  
@src/<source> has the net effect of nothing and maybe an error event.

At least I would prefer this rather simpler algorithm where @src/<source>  
are treated equally for the most part. In terms of understanding and  
implementating the algorithm it is simple. If the spec has trouble  
defining such behavior then I would regard that as a spec problem  
primarily.

> With almost everything else in HTML, setting the src="" immediately locks
> in what is loaded.

Also, setting it again immediately changes what is loaded, which isn't the  
case with a media element with networkState > NETWORK_EMPTY. No matter how  
it is spec'ed it you'll get behavior inconsistent with something else, I  
just think it's best to make the media element internally consistent.

> I don't particularly like the way that <source> is defined right now, but
> I can't see another way to do it given that we're dealing with a weird
> situation where the script might be slowly building a whole DOM in the
> common case, and so we really do have to wait for the script to finish.  
> So
> <source> is basically forced to be unpredictable. But it seems that we
> should at least try to keep this problem to <source> and not src="" also.

Well, for now we'll wait to see what happens with NETWORK_NO_SOURCE. We  
probably won't implement the locking of @src unless the spec stays the  
same, other browsers implement it that way and we end up being  
incompatible.

-- 
Philip Jägenstedt
Core Developer
Opera Software

Received on Wednesday, 10 June 2009 08:10:03 UTC