On Feb 7, 2007, at 11:05 PM, Charles McCathieNevile wrote:
On Tue, 06 Feb 2007 17:39:31 +0530, Maciej Stachowiak
<[EMAIL PROTECTED]> wrote:
On Feb 5, 2007, at 10:19 PM, Charles McCathieNevile wrote:
The progress and uploadprogress events are optional events that can
be fired by
(for an example) a user agent in the middle of an XmlHttpRequest
(XHR)
transaction. The start and end of that transaction (whether
successfully or in
some error condition) are, in this example, predefined parts of XHR.
The use case I presented was a reusable progress display control that
can connect to any possible event target that is a source of progress
events. Do you deny the validity of this use case, or do you have a
proposed alternate design that satisfies it?
OK, I think I understand better what your use case is now. I don't
deny that it
is a valid possible use case, and as you noted I don't think the
current draft
satisfies it.
My concern with it is that it requires more complexity in progress
events, and
encourages a design that does not work for backwards compatibility.
An alternative approach (the one I have been assuming) is that if
you have
controls for specific things that may fire progress, and they use a
standard bit
of rendering, you can attach the progress-based enhancements to any
of them.
If we supported your use case, do you have an idea for how to write
a set of
controls that also work as far as possible with existing user
agents, or are you
suggesting we should simply ignore those?
Many likely progress targets already will fire one of "load", "error"
or "abort", so those shouldn't be a concern with respect to
backwards compatibility. Thus, the only new points of concern are
"progress" (already in the spec, just a question of when it fires)
and "loadstart". Unfortunately, there is no existing way to tell when
a load starts in most progress targets. To make something backwards
compatible you would need an out-of-band way to tell the control when
you do something that may start a load. I think it would be
unfortunate to lock that design in, however. It may be possible to
special case this for some possible progress event targets such as XHR.
I think firing at defined times will be no more likely to result in
code that does not fall back gracefully than leaving this completely
undefined. And including load/error/abort in the spec will encourage
authors to make use of those backwards-compatible events as well.
As for upload, all of these are brand new, there's no real
possibility of a back-compatible design here. But having an
uploadstart event will at least let you determine if your
implementation supports upload progress at a fairly early state.
It may never fire.
If it's valid for the event to never fire, or to fire arbitrarily in
the middle of the load but not at the start or end, that makes it
much harder to use effectively in a way that works across
implementations. If one implementation sends start and end progress
events, and another doesn't, it is highly likely that code only
tested in one will fail in the other. I think interoperability is
more important than ease of implementing the spec in limited-resource
browsers.
Representing an actual implementor of browsers in highly constrained
environments I disagree that it is not important to support their
requirements.
I also note that code developed for an implementation that does not
always send
progress events is likely to work in one that does, so the
interoperability
issue you allude to only arises if ignorant developers only test in
implementations that happen to fire all possible events. (I don't
discount that
possibliity, however).
Experience shows that thoughtful developers will test in many
implementations, although if the implementations have very different
behavior they may get confused and write code that breaks when one
implementation changes to be more like another. And many developers
will only test in one or perhaps two implementations. This includes
even large web service companies, where many new services at launch
are very broken in Safari and Opera, and sometimes even in Firefox.
Even when developers initially test in many implementations, their
ongoing testing may be in only one.
In conclusion, I think it's better to have a spec with well-defined
requirements, and have browsers choose to either implement it or not,
than to have something very loose. That way, at least there are only
two possible behaviors.
If you want to be compatible with the web, you can trap the
start and end of an existing load. Since you have no progress
information and
don't know how long it will take, set up an indeterminate activity
indicator
like a spinning wheel or barber pole. If a progress event fires,
and provides
information you can use to determine more accurately the progress,
then you can
change the state of your indicator to reflect the new information
(as you would
anyway, no?). If you never get one, you can silently vanish, flash
your bar full
first, put a statement that you got an object of foo size (which
you determine
by measuring it) or whatever else makes you happy.
Given the EventTarget interface, how do you measure the size of the
relevant object? Or for that matter, how do you measure the size in
bytes of the contents of an <img> element, or a parsed DOM document
in a frame, or the contents of an <svg:image>, or the contents of an
<object> tag handled by a plugin, even if you know the exact kind of
object you are dealing with?
You can't, I suspect. How important is this?
Well, pretty important if one of your progress indicators is a size
in bytes which remains onscreen after the load completes. And this is
a common feature of many user interfaces.
Note, a possible alternate design for this is to require load/abort/
error events to implement the ProgressEvent interface and tell you
the amount loaded and the total loaded, this would eliminate the need
for the "last" progress event to be fired, but is likely to be
somewhat less author-friendly.
I also don't understand why you are so insistent on using 0 length to
indicate indeterminate length rather than having a separate boolean
attribute for this with a clear name. In-band signalling is generally
considered poor API design. Even if this approach were not unworkable
it would lead to less clear user code [if (event.total != 0) vs if
(event.totalIsKnown) or the like].
I'm not desperately attached to it. (Although for ECMAscript, our
most common
target, can you not write
if (event.total)
anyway? I realise this is not portable across other languages
though, and
recognise that this might not be ideal.
I think the extra boolean would be more clear.
On Thu, 01 Feb 2007 08:18:45 +0530, Maciej Stachowiak
<[EMAIL PROTECTED]> wrote:
...
2) You can't combine "loadstart" with "progress" [0,?,?]
because: You
want to start showing feedback the moment loading starts, even
if no
server response has yet told you what the content length will
be, or
whether it is determinate, but you want to show the total or
reflect
that it is unknown the moment that is the case.
When loading starts you almost certainly don't know the total. If
we outlaw
progress events for zero-length transfers, you get it as [0,0] and
it is clear
you still don't know the total. Alternatively you may get [0,X] and
can set up
the determinate version before you start. But why would you rely on
this anyway?
I think you misunderstood my point, which was that you want to
display the total as soon as it is know (or certain to be unknown) at
the first progress event. This progress event may be 0 bytes in
length, or more, but will probably be sent as soon as the
implementation receives the http header or similar.
True. But if we disallow a progress event for [0,0,true] (to use
your syntax as
I understand it) then if you get a progress event for [0,0] you
know it is an
unknown transfer size, and if you get [0,X] you know it is just the
first
progress event fired when nothing has moved yet.
But in that case, when you get a "load" event, you won't know whether
you just loaded an empty resource in an implementation that supports
"progress", or a resource of whatever size in an implementation that
does not.
I am quite certain that
you can't build one which can be attached to any plausible progress
event target.
Indeed. However you can build a standard extension for dealing with
progress
events, that can be attached to a standard UI control that would be
attached to
any plausible source of progress events but where those events may
not be fired.
I'm not sure what this means.
Anyway, I wil raise an issue, since I think we have a fundamental
difference in
the most important use cases.
Consider also the XHR upload case, there is no obvious way to get the
total size of what you uploaded if it is a serialized DOM document
for instance. You could serialize it in what you hope is the same was
as XHR would do it, but this is not certain to be correct, and it is
quite expensive to do an extra serialization just to get the length
of the string. Plus, even then, you don't know the length of the
contents sent
It seems much simpler to have an obviously complete set of progress
events than to play tricks with what you might be able to do with
fewer in some cases. What is the case against completeness?
minimalism
I agree this is a worthy goal in general, however, minimalism cannot
apply until you have achieved completeness. In this case, progress UI
is the primary purpose for progress events, so they should make sure
to support it.
Even for an API that provides a theoretically complete set of
functionality, sometimes author-friendliness calls for more than the
very absolute minimum.
(and a desire to discourage developing things that are not
compatible with
existing user agents).
I think we need to think of this in terms of making graceful fallback
possible, rather than trying to push towards it. Any such
encouragement should be in the form of authoring guidelines in the
spec, rather than limiting the API itself.
Regards,
Maciej