Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-11-02 Thread Eric U
On Mon, Oct 3, 2011 at 6:13 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Mon, Oct 3, 2011 at 5:57 PM, Glenn Maynard gl...@zewt.org wrote:
 On Mon, Oct 3, 2011 at 8:10 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. Make loadend not fire in case a new load is started from
 onabort/onload/onerror. Thus loadend and loadstart isn't always
 paired up. Though there is always a loadend fired after every
 loadstart.
 2. Make FileReader/FileWriter/FileSaver not behave like XHR. This also

 leaves the problem unsolved for XHR.

 Are there other options I'm missing?

 Or do both, improving XHR as much as backwards-compatibility allows and
 don't try to match other APIs to it exactly.  I'd much prefer weirdness be
 isolated to XHR than be perpetuated through every PE-based API.

 So what exactly are you proposing we do for XHR and for FileReader/FileWriter?

 I'm still not convinced that it's better for authors to require them
 to use setTimeout to start a new load as opposed to let them restart
 the new load from within an event and cancel all following events. I
 agree that this introduces some inconsistency, but it only does so
 when authors explicitly reuses a FileReader/XHR/FileWriter for
 multiple requests.

 And it only weakens the invariant, not removes it. So instead of

 * There's exactly one 'loadend' event for each 'loadstart' event.

 we'll have

 * There's always a 'loadend' event fired after each 'loadstart' event.
 However there might be other 'loadstart' events fired in between.

I'm for this.  It lets FileReader and FileWriter match XHR, avoids [in
the odd case] long strings of stacked-up loadend events, and users can
avoid all the issues either by creating a new FileReader or by
wrapping nested calls in timers if they care.  I believe Jonas is in
favor of this as well.

Can we put this one to bed?

 Eric



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-11-02 Thread Jonas Sicking
On Wed, Nov 2, 2011 at 9:56 AM, Eric U er...@google.com wrote:
 On Mon, Oct 3, 2011 at 6:13 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Mon, Oct 3, 2011 at 5:57 PM, Glenn Maynard gl...@zewt.org wrote:
 On Mon, Oct 3, 2011 at 8:10 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. Make loadend not fire in case a new load is started from
 onabort/onload/onerror. Thus loadend and loadstart isn't always
 paired up. Though there is always a loadend fired after every
 loadstart.
 2. Make FileReader/FileWriter/FileSaver not behave like XHR. This also

 leaves the problem unsolved for XHR.

 Are there other options I'm missing?

 Or do both, improving XHR as much as backwards-compatibility allows and
 don't try to match other APIs to it exactly.  I'd much prefer weirdness be
 isolated to XHR than be perpetuated through every PE-based API.

 So what exactly are you proposing we do for XHR and for 
 FileReader/FileWriter?

 I'm still not convinced that it's better for authors to require them
 to use setTimeout to start a new load as opposed to let them restart
 the new load from within an event and cancel all following events. I
 agree that this introduces some inconsistency, but it only does so
 when authors explicitly reuses a FileReader/XHR/FileWriter for
 multiple requests.

 And it only weakens the invariant, not removes it. So instead of

 * There's exactly one 'loadend' event for each 'loadstart' event.

 we'll have

 * There's always a 'loadend' event fired after each 'loadstart' event.
 However there might be other 'loadstart' events fired in between.

 I'm for this.  It lets FileReader and FileWriter match XHR, avoids [in
 the odd case] long strings of stacked-up loadend events, and users can
 avoid all the issues either by creating a new FileReader or by
 wrapping nested calls in timers if they care.  I believe Jonas is in
 favor of this as well.

 Can we put this one to bed?

So the proposal here is to allow new loads to be started from within
abort/error/load event handlers, and for loadend to *not* fire if a
new load has already started by the time the abort/error/load event is
done firing. And the goal is that XMLHttpRequest, FileReader and
FileWriter all behave this way. Is this correct?

If so, I agree that this sounds like a good solution.

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-11-02 Thread Eric U
On Wed, Nov 2, 2011 at 3:56 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Wed, Nov 2, 2011 at 9:56 AM, Eric U er...@google.com wrote:
 On Mon, Oct 3, 2011 at 6:13 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Mon, Oct 3, 2011 at 5:57 PM, Glenn Maynard gl...@zewt.org wrote:
 On Mon, Oct 3, 2011 at 8:10 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. Make loadend not fire in case a new load is started from
 onabort/onload/onerror. Thus loadend and loadstart isn't always
 paired up. Though there is always a loadend fired after every
 loadstart.
 2. Make FileReader/FileWriter/FileSaver not behave like XHR. This also

 leaves the problem unsolved for XHR.

 Are there other options I'm missing?

 Or do both, improving XHR as much as backwards-compatibility allows and
 don't try to match other APIs to it exactly.  I'd much prefer weirdness be
 isolated to XHR than be perpetuated through every PE-based API.

 So what exactly are you proposing we do for XHR and for 
 FileReader/FileWriter?

 I'm still not convinced that it's better for authors to require them
 to use setTimeout to start a new load as opposed to let them restart
 the new load from within an event and cancel all following events. I
 agree that this introduces some inconsistency, but it only does so
 when authors explicitly reuses a FileReader/XHR/FileWriter for
 multiple requests.

 And it only weakens the invariant, not removes it. So instead of

 * There's exactly one 'loadend' event for each 'loadstart' event.

 we'll have

 * There's always a 'loadend' event fired after each 'loadstart' event.
 However there might be other 'loadstart' events fired in between.

 I'm for this.  It lets FileReader and FileWriter match XHR, avoids [in
 the odd case] long strings of stacked-up loadend events, and users can
 avoid all the issues either by creating a new FileReader or by
 wrapping nested calls in timers if they care.  I believe Jonas is in
 favor of this as well.

 Can we put this one to bed?

 So the proposal here is to allow new loads to be started from within
 abort/error/load event handlers, and for loadend to *not* fire if a
 new load has already started by the time the abort/error/load event is
 done firing. And the goal is that XMLHttpRequest, FileReader and
 FileWriter all behave this way. Is this correct?

I think I may have missed something important.  XHR2 specs just this
behavior w.r.t. abort [another open will stop the abort's loadend] but
/doesn't/ spec that for error or load.  That is, an open() in onerror
or onload does not appear to cancel the pending loadend.  Anne, can
you comment on why?

 If so, I agree that this sounds like a good solution.

 / Jonas




Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-03 Thread Arun Ranganathan

On 9/30/11 11:14 AM, Anne van Kesteren wrote:

On Thu, 29 Sep 2011 23:17:21 +0200, Eric U er...@google.com wrote:

I think that works; #2 will be especially important.
However, if I read this right, we *don't* have the invariant that a
loadstart will always have a loadend.
Now that Anne's explained XHR2's model, it seems that an open can
cancel the loadend that an abort would have sent.  So the invariants
need to be a bit more complex.


Well lets not accept as XHR2 as set-in-stone.

We could also change XHR2 to not cancel abort() when invoking open(). 
Then you get scenarios such as:


  abort()
  - abort event that invokes open()
 - readystatechange event
  - loadend event
  - abort event on XHRUpload
  - loadend event on XHRUpload

Instead of everything after the readystatechange event not happening. 
We could also introduce a flag and make it impossible to call open() 
from an event handler.


Maybe the simplest is the above. You can call open() from event 
handlers, but events will still be dispatched (and readyState will 
have changed). This is somewhat ugly, but then you should probably not 
invoke open() from event handlers anyway.



This gives us the desirable invariant that a loadstart will always have 
a loadend, which I think simplifies this model.  It seems useful to 
proceed with this in FileAPI.


-- A*











Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-03 Thread Jonas Sicking
On Fri, Sep 30, 2011 at 8:14 AM, Anne van Kesteren ann...@opera.com wrote:
 On Thu, 29 Sep 2011 23:17:21 +0200, Eric U er...@google.com wrote:

 I think that works; #2 will be especially important.
 However, if I read this right, we *don't* have the invariant that a
 loadstart will always have a loadend.
 Now that Anne's explained XHR2's model, it seems that an open can
 cancel the loadend that an abort would have sent.  So the invariants
 need to be a bit more complex.

 Well lets not accept as XHR2 as set-in-stone.

 We could also change XHR2 to not cancel abort() when invoking open(). Then
 you get scenarios such as:

  abort()
  - abort event that invokes open()
     - readystatechange event
  - loadend event
  - abort event on XHRUpload
  - loadend event on XHRUpload

 Instead of everything after the readystatechange event not happening. We
 could also introduce a flag and make it impossible to call open() from an
 event handler.

 Maybe the simplest is the above. You can call open() from event handlers,
 but events will still be dispatched (and readyState will have changed). This
 is somewhat ugly, but then you should probably not invoke open() from event
 handlers anyway.

Unfortunately I suspect wanting to call open from event handlers is a
pretty common use case. Here are two use cases:

1. In case of a network error, let the onerror handler retry the request.
2. Implementing a auto-complete UI backed by data stored on the
server. Any time the user hits another character, abort the current
request and perform a new request with the newly typed value.

In the first case it makes sense to call .open/.send from the onerror
handler. In the second case it makes sense to do so from the onabort
handler.

I'm personally split on the issue. On one hand I really like the
simplicity of saying that each loadstart is always paired with a
loadend. On the other hand, I have a hard time thinking of any use
cases which *wouldn't* be helped by simply dropping the loadend
event if a new load had been started.

For example if you're implementing a progress bar, it would be very
easy to make the mistake of hiding the progress bar from loadend and
showing it in loadstart. In the two use cases above, that would
result in the progress bar not showing during the second load. I'll
leave as an exercise to the reader how to avoid such a bug ;-)

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-03 Thread Glenn Maynard
On Mon, Oct 3, 2011 at 6:00 PM, Jonas Sicking jo...@sicking.cc wrote:

 Unfortunately I suspect wanting to call open from event handlers is a
 pretty common use case. Here are two use cases:

 1. In case of a network error, let the onerror handler retry the request.

2. Implementing a auto-complete UI backed by data stored on the
 server. Any time the user hits another character, abort the current
 request and perform a new request with the newly typed value.


These can be handled trivially by wrapping in a timer.  This is a basic
platform concept, an approximation of queue a task so common in specs.

(#2 isn't actually a problem, since it's an event from a different
source--it's only recursing back into the same XHR/FileReader/etc. object
from its own events that causes ugliness.)

For example if you're implementing a progress bar, it would be very
 easy to make the mistake of hiding the progress bar from loadend and
 showing it in loadstart. In the two use cases above, that would
 result in the progress bar not showing during the second load. I'll
 leave as an exercise to the reader how to avoid such a bug ;-)


This shouldn't be a mistake--it's the natural, obvious way to use these
events.  You shouldn't have to worry about receiving two loadstarts in a
row, or two loadends in a row, or missing loadends, depending on what object
is firing the event, how its API is being used, or where your event listener
is in the event handler list.

Needing to use setTimeout in some cases is a tiny price to pay, to avoid
having to worry about that mess and keep these events straightforward and
predictable.

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-03 Thread Jonas Sicking
On Mon, Oct 3, 2011 at 4:16 PM, Glenn Maynard gl...@zewt.org wrote:
 On Mon, Oct 3, 2011 at 6:00 PM, Jonas Sicking jo...@sicking.cc wrote:

 Unfortunately I suspect wanting to call open from event handlers is a
 pretty common use case. Here are two use cases:

 1. In case of a network error, let the onerror handler retry the request.

 2. Implementing a auto-complete UI backed by data stored on the
 server. Any time the user hits another character, abort the current
 request and perform a new request with the newly typed value.

 These can be handled trivially by wrapping in a timer.  This is a basic
 platform concept, an approximation of queue a task so common in specs.

 (#2 isn't actually a problem, since it's an event from a different
 source--it's only recursing back into the same XHR/FileReader/etc. object
 from its own events that causes ugliness.)

 For example if you're implementing a progress bar, it would be very
 easy to make the mistake of hiding the progress bar from loadend and
 showing it in loadstart. In the two use cases above, that would
 result in the progress bar not showing during the second load. I'll
 leave as an exercise to the reader how to avoid such a bug ;-)

 This shouldn't be a mistake--it's the natural, obvious way to use these
 events.  You shouldn't have to worry about receiving two loadstarts in a
 row, or two loadends in a row, or missing loadends, depending on what object
 is firing the event, how its API is being used, or where your event listener
 is in the event handler list.

Exactly!

 Needing to use setTimeout in some cases is a tiny price to pay, to avoid
 having to worry about that mess and keep these events straightforward and
 predictable.

Except that we can't do that for XHR since there's already tons of
content out there. Most likely enough of that content starts a new
load from onabort/onload/onerror that we can't make that throw. Which
leaves us with the following options:

1. Make loadend not fire in case a new load is started from
onabort/onload/onerror. Thus loadend and loadstart isn't always
paired up. Though there is always a loadend fired after every
loadstart.
2. Make FileReader/FileWriter/FileSaver not behave like XHR. This also
leaves the problem unsolved for XHR.

Are there other options I'm missing?

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-03 Thread Jonas Sicking
On Mon, Oct 3, 2011 at 5:57 PM, Glenn Maynard gl...@zewt.org wrote:
 On Mon, Oct 3, 2011 at 8:10 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. Make loadend not fire in case a new load is started from
 onabort/onload/onerror. Thus loadend and loadstart isn't always
 paired up. Though there is always a loadend fired after every
 loadstart.
 2. Make FileReader/FileWriter/FileSaver not behave like XHR. This also

 leaves the problem unsolved for XHR.

 Are there other options I'm missing?

 Or do both, improving XHR as much as backwards-compatibility allows and
 don't try to match other APIs to it exactly.  I'd much prefer weirdness be
 isolated to XHR than be perpetuated through every PE-based API.

So what exactly are you proposing we do for XHR and for FileReader/FileWriter?

I'm still not convinced that it's better for authors to require them
to use setTimeout to start a new load as opposed to let them restart
the new load from within an event and cancel all following events. I
agree that this introduces some inconsistency, but it only does so
when authors explicitly reuses a FileReader/XHR/FileWriter for
multiple requests.

And it only weakens the invariant, not removes it. So instead of

* There's exactly one 'loadend' event for each 'loadstart' event.

we'll have

* There's always a 'loadend' event fired after each 'loadstart' event.
However there might be other 'loadstart' events fired in between.

/ Jonas

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-03 Thread Glenn Maynard
On Mon, Oct 3, 2011 at 9:13 PM, Jonas Sicking jo...@sicking.cc wrote:

 So what exactly are you proposing we do for XHR and for
 FileReader/FileWriter?


For APIs other than XHR, don't allow calling read* or abort during events
fired on the object from its own algorithms.  This should give the guarantee
that loadstart and loadend will always be paired and non-interleaved, and
give developers a simple rule: if you need to start a new operation from
these events, push it into a timer (queue a task).

(More precisely, no method that starts or finishes a loadstart/loadend
sequence can be called from within an algorithm that also starts or finishes
a sequence.  abort() from within onprogress is fine, for example.)

I don't have a strong opinion about what to do with XHR--my main worry is
not perpetuating ugliness into every PE API in order to mimic XHR.

And it only weakens the invariant, not removes it. So instead of

 * There's exactly one 'loadend' event for each 'loadstart' event.

 we'll have

 * There's always a 'loadend' event fired after each 'loadstart' event.
 However there might be other 'loadstart' events fired in between.


When can this happen, with the above restriction in place (speaking of eg.
FileReader, not XHR)?

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-03 Thread Jonas Sicking
On Mon, Oct 3, 2011 at 6:39 PM, Glenn Maynard gl...@zewt.org wrote:
 On Mon, Oct 3, 2011 at 9:13 PM, Jonas Sicking jo...@sicking.cc wrote:

 So what exactly are you proposing we do for XHR and for
 FileReader/FileWriter?

 For APIs other than XHR, don't allow calling read* or abort during events
 fired on the object from its own algorithms.  This should give the guarantee
 that loadstart and loadend will always be paired and non-interleaved, and
 give developers a simple rule: if you need to start a new operation from
 these events, push it into a timer (queue a task).

 (More precisely, no method that starts or finishes a loadstart/loadend
 sequence can be called from within an algorithm that also starts or finishes
 a sequence.  abort() from within onprogress is fine, for example.)

I think this is a higher cost to developers than the cost of having
loadstart always be paired up with exactly one loadend.

Note that this would mean that you also couldn't start a new load from
within the loadend event since that would cause event listeners
after yours to receive interleaved loadstart/loadend events.

The main problem here is actually the fact that loadend is fired
synchronously from read*. If we removed that constraint then we could
allow loads to start from anywhere without having to worry about
interleaved loadstart/loadend.

But it's somewhat doubtful that we can make such a big change to
FileReader given that it's been in the wild for a while :(

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-10-01 Thread Anne van Kesteren
On Fri, 30 Sep 2011 19:15:17 +0200, Arun Ranganathan a...@mozilla.com  
wrote:
Anne: I think simplifying the model like this makes sense, although  
previous discussions seemed to suggest that previous implementation  
history made these kinds of changes hard.  I'd be happy to match this in  
FileReader if that's what you're doing in XHR2.


I believe Glenn said this is what Gecko is doing now (rather than what the  
standard says).



I'm interested in hearing from Glenn, Jonas, and others, but I think  
Eric's on paternity leave so we'll have to channel him w.r.t.  
FileSaver/FileWriter :)


Yeah, getting more feedback would be nice.


--
Anne van Kesteren
http://annevankesteren.nl/



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-30 Thread Anne van Kesteren

On Thu, 29 Sep 2011 23:17:21 +0200, Eric U er...@google.com wrote:

I think that works; #2 will be especially important.
However, if I read this right, we *don't* have the invariant that a
loadstart will always have a loadend.
Now that Anne's explained XHR2's model, it seems that an open can
cancel the loadend that an abort would have sent.  So the invariants
need to be a bit more complex.


Well lets not accept as XHR2 as set-in-stone.

We could also change XHR2 to not cancel abort() when invoking open(). Then  
you get scenarios such as:


  abort()
  - abort event that invokes open()
 - readystatechange event
  - loadend event
  - abort event on XHRUpload
  - loadend event on XHRUpload

Instead of everything after the readystatechange event not happening. We  
could also introduce a flag and make it impossible to call open() from an  
event handler.


Maybe the simplest is the above. You can call open() from event handlers,  
but events will still be dispatched (and readyState will have changed).  
This is somewhat ugly, but then you should probably not invoke open() from  
event handlers anyway.



--
Anne van Kesteren
http://annevankesteren.nl/



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-29 Thread Eric U
On Thu, Sep 29, 2011 at 12:22 PM, Arun Ranganathan a...@mozilla.com wrote:

 On 9/21/11 8:07 PM, Eric U wrote:

 Update: I have made the changes to FileWriter/FileSaver's event
 sequences; they now match FileReader.
 That's not to say it won't change pending discussion, but FileWriter
 should continue to match FileReader whatever else happens.

       Eric

 Eric:

 After reading this email thread, and looking at your changes, I think I'll 
 make the following changes:

 1. Tighten requirement on onprogress such that we mandate firing *at least 
 one* progress event with a must.  Right now this is unclear as you point out, 
 not least of all because we don't mandate the user agent calling onprogress.
 2. Include a discussion of the invariants Jonas mentions [1], so that event 
 order is fleshed in the event section.
 3. Clarify exceptions to the 50ms event dispatch timeframe (notably for 
 progress events before load+loadend).

 To be clear, you've decided we're NOT going to veer from XHR2's abort/open 
 behavior (and thus what FileReader says now) in FileWriter/FileSaver right?

 Is this a good summary of changes that we should make?

 -- A*
 [1] http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/1512.html

I think that works; #2 will be especially important.
However, if I read this right, we *don't* have the invariant that a
loadstart will always have a loadend.
Now that Anne's explained XHR2's model, it seems that an open can
cancel the loadend that an abort would have sent.  So the invariants
need to be a bit more complex.

I've updated FileWriter to take most of this into account, but *not*
that last bit yet; as written, I've got Jonas's original invariants,
which would lead to the stacked up loadend events at the end.



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-29 Thread Arun Ranganathan

On 9/21/11 8:07 PM, Eric U wrote:

Update: I have made the changes to FileWriter/FileSaver's event
sequences; they now match FileReader.
That's not to say it won't change pending discussion, but FileWriter
should continue to match FileReader whatever else happens.

   Eric

Eric:

After reading this email thread, and looking at your changes, I think 
I'll make the following changes:


1. Tighten requirement on onprogress such that we mandate firing *at 
least one* progress event with a must.  Right now this is unclear as you 
point out, not least of all because we don't mandate the user agent 
calling onprogress.
2. Include a discussion of the invariants Jonas mentions [1], so that 
event order is fleshed in the event section.
3. Clarify exceptions to the 50ms event dispatch timeframe (notably for 
progress events before load+loadend).


To be clear, you've decided we're NOT going to veer from XHR2's 
abort/open behavior (and thus what FileReader says now) in 
FileWriter/FileSaver right?


Is this a good summary of changes that we should make?

-- A*
[1] http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/1512.html



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-22 Thread Anne van Kesteren

On Wed, 21 Sep 2011 20:12:17 +0200, Glenn Maynard gl...@zewt.org wrote:

Yuck.  I agree that's not a good thing to mimic for the sake of
consistency.  Anne, is this intentional, or just something XHR is just  
stuck with for compatibility?  It looks like a new problem in XHR2--this  
couldn't happen in XHR1, because there was no abort event fired before  
loadend.


The send() method can be terminated in similar fashion.

I made this change almost a year ago now. It was to prevent weird  
situations from occurring event-wise if you invoke open() from one of the  
events dispatched by e.g. send() or abort(). One of the silly things from  
XMLHttpRequest is that open() can always be invoked. This seemed like the  
simplest way of dealing with that.


I am open to suggestions however (and tests!).


--
Anne van Kesteren
http://annevankesteren.nl/



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-22 Thread Anne van Kesteren

On Thu, 22 Sep 2011 04:01:40 +0200, Glenn Maynard gl...@zewt.org wrote:
To my reading, a substep is a type of step.  The after finishing...  
sounds like it's saying not to terminate the currently-executing step;  
that is, the event dispatch isn't stopped in the middle.  Maybe steps  
vs. substeps
are precisely defined somewhere else, but either way this could probably  
be clearer.  Anne?


Your interpretation is correct. I could make it say step or substep but  
it seems people might want something else altogether.




I just tried this in FF6, and the behavior is inconsistent.  If the TCP
connection has been established, then it follows your interpretation, and
you get onloadstart, onabort, onloadstart, onloadend, onloadend [1][3].   
If the TCP connection hasn't yet been established [2][4], calling open()  
from either onabort or onloadend throws NS_ERROR_IN_PROGRESS.


But open() has to dispatch a readystatechange event. That will get  
somewhere in the middle of that, no?




With the various inconsistencies, I wonder if the spec can't actually be
changed to disallow open() during the events, following FF6--that
NS_ERROR_IN_PROGRESS is probably unintentional, but it's in a shipping
browser nonetheless.  Wishful thinking, maybe...


There is the same problem with send() but there it was not a problem  
before either because you just had readystatechange.




This sounds like a bug in the XHR spec as it doesn't fulfill the
invariants I listed.


I agree with those invariants, but they aren't normative anywhere, are  
they?


Nope.


--
Anne van Kesteren
http://annevankesteren.nl/



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-22 Thread Glenn Maynard
On Thu, Sep 22, 2011 at 5:19 AM, Anne van Kesteren ann...@opera.com wrote:

  I just tried this in FF6, and the behavior is inconsistent.  If the TCP
 connection has been established, then it follows your interpretation, and
 you get onloadstart, onabort, onloadstart, onloadend, onloadend [1][3].
  If the TCP connection hasn't yet been established [2][4], calling open()
 from either onabort or onloadend throws NS_ERROR_IN_PROGRESS.


 But open() has to dispatch a readystatechange event. That will get
 somewhere in the middle of that, no?


Sorry, I meant calling send() throws NS_ERROR_IN_PROGRESS.

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Glenn Maynard
On Tue, Sep 20, 2011 at 8:40 PM, Eric U er...@google.com wrote:

 Indeed--however, from a quick skim of XHR and XHR2, that's not what
 they do.  They let open() terminate abort(), however far along it's
 gotten.  If we did that, then an abort killed by a read might lead to
 the aborted read never getting an onloadend.  But you could still get
 the stack-busting chain of onloadstart/onabort.


Yuck.  I agree that's not a good thing to mimic for the sake of
consistency.  Anne, is this intentional, or just something XHR is just stuck
with for compatibility?  It looks like a new problem in XHR2--this couldn't
happen in XHR1, because there was no abort event fired before loadend.

If we wanted to prevent read methods from being called during abort,
 we'd probably want to do that by setting an aborting flag or mucking
 around with yet another readyState of ABORTING.


That's annoying, but it's better than the current situation, and I think
better than the XHR situation.  Receiving loadstart should guarantee the
receipt of loadend.

On Tue, Sep 20, 2011 at 7:43 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. onloadstart fires exactly once
 2. There will be one onprogress event fired when 100% progress is reached
 3. Exactly one of onabort, onload and onerror fires
 4. onloadend fires exactly once.
 6. no onprogress events fire before onloadstart
 5. no onprogress events fire after onabort/onload/onerror
 6. no onabort/onoad/onerror events fire after onloadend


7. after loadstart is fired, loadstart is not fired again until loadend has
been fired (ie. only one set of progress events can be active on an object
at one time).

More precisely: loadstart should not be fired again until the dispatch of
loadend *has completed*.  That is, you can't start a new progress sequence
from within loadend, either, because there may be other listeners on the
object that havn't yet received the loadend.

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Jonas Sicking
On Wed, Sep 21, 2011 at 11:12 AM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Sep 20, 2011 at 8:40 PM, Eric U er...@google.com wrote:

 Indeed--however, from a quick skim of XHR and XHR2, that's not what
 they do.  They let open() terminate abort(), however far along it's
 gotten.  If we did that, then an abort killed by a read might lead to
 the aborted read never getting an onloadend.  But you could still get
 the stack-busting chain of onloadstart/onabort.

 Yuck.  I agree that's not a good thing to mimic for the sake of
 consistency.  Anne, is this intentional, or just something XHR is just stuck
 with for compatibility?  It looks like a new problem in XHR2--this couldn't
 happen in XHR1, because there was no abort event fired before loadend.

 If we wanted to prevent read methods from being called during abort,
 we'd probably want to do that by setting an aborting flag or mucking
 around with yet another readyState of ABORTING.

 That's annoying, but it's better than the current situation, and I think
 better than the XHR situation.  Receiving loadstart should guarantee the
 receipt of loadend.

 On Tue, Sep 20, 2011 at 7:43 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. onloadstart fires exactly once
 2. There will be one onprogress event fired when 100% progress is reached
 3. Exactly one of onabort, onload and onerror fires
 4. onloadend fires exactly once.
 6. no onprogress events fire before onloadstart
 5. no onprogress events fire after onabort/onload/onerror
 6. no onabort/onoad/onerror events fire after onloadend

 7. after loadstart is fired, loadstart is not fired again until loadend has
 been fired (ie. only one set of progress events can be active on an object
 at one time).

 More precisely: loadstart should not be fired again until the dispatch of
 loadend *has completed*.  That is, you can't start a new progress sequence
 from within loadend, either, because there may be other listeners on the
 object that havn't yet received the loadend.

I don't think we can do that for XHR without breaking backwards compat.

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Eric U
On Wed, Sep 21, 2011 at 2:28 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Wed, Sep 21, 2011 at 11:12 AM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Sep 20, 2011 at 8:40 PM, Eric U er...@google.com wrote:

 Indeed--however, from a quick skim of XHR and XHR2, that's not what
 they do.  They let open() terminate abort(), however far along it's
 gotten.  If we did that, then an abort killed by a read might lead to
 the aborted read never getting an onloadend.  But you could still get
 the stack-busting chain of onloadstart/onabort.

 Yuck.  I agree that's not a good thing to mimic for the sake of
 consistency.  Anne, is this intentional, or just something XHR is just stuck
 with for compatibility?  It looks like a new problem in XHR2--this couldn't
 happen in XHR1, because there was no abort event fired before loadend.

 If we wanted to prevent read methods from being called during abort,
 we'd probably want to do that by setting an aborting flag or mucking
 around with yet another readyState of ABORTING.

 That's annoying, but it's better than the current situation, and I think
 better than the XHR situation.  Receiving loadstart should guarantee the
 receipt of loadend.

 On Tue, Sep 20, 2011 at 7:43 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. onloadstart fires exactly once
 2. There will be one onprogress event fired when 100% progress is reached
 3. Exactly one of onabort, onload and onerror fires
 4. onloadend fires exactly once.
 6. no onprogress events fire before onloadstart
 5. no onprogress events fire after onabort/onload/onerror
 6. no onabort/onoad/onerror events fire after onloadend

 7. after loadstart is fired, loadstart is not fired again until loadend has
 been fired (ie. only one set of progress events can be active on an object
 at one time).

 More precisely: loadstart should not be fired again until the dispatch of
 loadend *has completed*.  That is, you can't start a new progress sequence
 from within loadend, either, because there may be other listeners on the
 object that havn't yet received the loadend.

 I don't think we can do that for XHR without breaking backwards compat.

I just spent a bit more time with the XHR2 spec, and it looks like the
same looping behavior's legal there too, bouncing between
onreadystatechange and onabort, and stacking up a pending call to
onloadend for each loop.  When open terminates abort, abort completes
the step of the algorithm [here step 5], which includes a subsequent
call to onloadend.  It's not a queued task to be cancelled, as it's
all synchronous calls back and forth.

If we want the file specs to match the XHR spec, then we can just
leave this as it is in File Reader, and I'll match it in File Writer.
Recursion depth limit is up to the UA to set.  But I look forward to
hearing what Anne has to say about it before we settle on copying it.



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Jonas Sicking
On Wed, Sep 21, 2011 at 2:44 PM, Eric U er...@google.com wrote:
 On Wed, Sep 21, 2011 at 2:28 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Wed, Sep 21, 2011 at 11:12 AM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Sep 20, 2011 at 8:40 PM, Eric U er...@google.com wrote:

 Indeed--however, from a quick skim of XHR and XHR2, that's not what
 they do.  They let open() terminate abort(), however far along it's
 gotten.  If we did that, then an abort killed by a read might lead to
 the aborted read never getting an onloadend.  But you could still get
 the stack-busting chain of onloadstart/onabort.

 Yuck.  I agree that's not a good thing to mimic for the sake of
 consistency.  Anne, is this intentional, or just something XHR is just stuck
 with for compatibility?  It looks like a new problem in XHR2--this couldn't
 happen in XHR1, because there was no abort event fired before loadend.

 If we wanted to prevent read methods from being called during abort,
 we'd probably want to do that by setting an aborting flag or mucking
 around with yet another readyState of ABORTING.

 That's annoying, but it's better than the current situation, and I think
 better than the XHR situation.  Receiving loadstart should guarantee the
 receipt of loadend.

 On Tue, Sep 20, 2011 at 7:43 PM, Jonas Sicking jo...@sicking.cc wrote:

 1. onloadstart fires exactly once
 2. There will be one onprogress event fired when 100% progress is reached
 3. Exactly one of onabort, onload and onerror fires
 4. onloadend fires exactly once.
 6. no onprogress events fire before onloadstart
 5. no onprogress events fire after onabort/onload/onerror
 6. no onabort/onoad/onerror events fire after onloadend

 7. after loadstart is fired, loadstart is not fired again until loadend has
 been fired (ie. only one set of progress events can be active on an object
 at one time).

 More precisely: loadstart should not be fired again until the dispatch of
 loadend *has completed*.  That is, you can't start a new progress sequence
 from within loadend, either, because there may be other listeners on the
 object that havn't yet received the loadend.

 I don't think we can do that for XHR without breaking backwards compat.

 I just spent a bit more time with the XHR2 spec, and it looks like the
 same looping behavior's legal there too, bouncing between
 onreadystatechange and onabort, and stacking up a pending call to
 onloadend for each loop.  When open terminates abort, abort completes
 the step of the algorithm [here step 5], which includes a subsequent
 call to onloadend.  It's not a queued task to be cancelled, as it's
 all synchronous calls back and forth.

 If we want the file specs to match the XHR spec, then we can just
 leave this as it is in File Reader, and I'll match it in File Writer.
 Recursion depth limit is up to the UA to set.  But I look forward to
 hearing what Anne has to say about it before we settle on copying it.

I think we're basically limited here by over 10 years of IE code.

For what it's worth, it's fairly easy for pages to avoid the problems
here. If a page listens to the loadend event, it should do any
aborting or new-load-starting here. If it doesn't listen to loadend,
then the event order it will see will be quite sensible. I.e. if you
remove loadend from the list of events that you had, it looks quite
logical.

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Glenn Maynard
On Wed, Sep 21, 2011 at 5:44 PM, Eric U er...@google.com wrote:

 If we want the file specs to match the XHR spec, then we can just
 leave this as it is in File Reader, and I'll match it in File Writer.
 Recursion depth limit is up to the UA to set.  But I look forward to
 hearing what Anne has to say about it before we settle on copying it.


In my opinion, providing the no nesting guarantee is more useful than
being consistent with XHR, if all new APIs provide it.

This sort of thing seems obviously useful:

function showActivity(obj)
{
obj.addEventHandler(loadstart, function() { div.hidden = false; },
false);
obj.addEventHandler(loadend, function() { div.hidden = true; },
false);
}

With the currently specced behavior, this doesn't work--the div would end up
hidden when it should be shown.  You shouldn't have to care how other code
is triggering reads to do something this simple.

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Eric U
On Wed, Sep 21, 2011 at 3:09 PM, Glenn Maynard gl...@zewt.org wrote:
 On Wed, Sep 21, 2011 at 5:44 PM, Eric U er...@google.com wrote:

 If we want the file specs to match the XHR spec, then we can just
 leave this as it is in File Reader, and I'll match it in File Writer.
 Recursion depth limit is up to the UA to set.  But I look forward to
 hearing what Anne has to say about it before we settle on copying it.

 In my opinion, providing the no nesting guarantee is more useful than
 being consistent with XHR, if all new APIs provide it.

If we eliminate it entirely, then you can't ever start a new read on
the same object from the abort handler.  That seems like a reasonable
use case.

 This sort of thing seems obviously useful:

 function showActivity(obj)
 {
     obj.addEventHandler(loadstart, function() { div.hidden = false; },
 false);
     obj.addEventHandler(loadend, function() { div.hidden = true; },
 false);
 }

 With the currently specced behavior, this doesn't work--the div would end up
 hidden when it should be shown.  You shouldn't have to care how other code
 is triggering reads to do something this simple.

Adding a number-of-reads-outstanding counter isn't that much more
code.  And if you're really trying to keep things simple, you're not
aborting and then starting another read during the abort, so the above
code works in your app.



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Glenn Maynard
On Wed, Sep 21, 2011 at 6:14 PM, Eric U er...@google.com wrote:

 If we eliminate it entirely, then you can't ever start a new read on
 the same object from the abort handler.  That seems like a reasonable
 use case.


It's trivial to stuff it into a zero-second timeout to knock it out of the
event handler.  This is such a common and useful pattern that libraries have
shorthand for it, eg. Prototype's Function#defer.  I don't think that's an
onerous requirement at all; it's basically the same as specs saying queue
an event.

Adding a number-of-reads-outstanding counter isn't that much more
 code.


It's not much more code, but it's code dealing with a case that doesn't have
to exist, working around a very ugly and unobvious sequence of events, and
it's something that you really shouldn't have to worry about every single
time you use loadstart/loadend pairs.

And if you're really trying to keep things simple, you're not
 aborting and then starting another read during the abort, so the above
 code works in your app.


The above code and the code triggering the reads might not even be written
by the same people--the activity display might be a third-party component
(who very well might not have thought of this; I wouldn't have, before this
discussion).

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Eric U
On Wed, Sep 21, 2011 at 3:29 PM, Glenn Maynard gl...@zewt.org wrote:
 On Wed, Sep 21, 2011 at 6:14 PM, Eric U er...@google.com wrote:

 If we eliminate it entirely, then you can't ever start a new read on
 the same object from the abort handler.  That seems like a reasonable
 use case.

 It's trivial to stuff it into a zero-second timeout to knock it out of the
 event handler.  This is such a common and useful pattern that libraries have
 shorthand for it, eg. Prototype's Function#defer.  I don't think that's an
 onerous requirement at all; it's basically the same as specs saying queue
 an event.

While it's certainly not hard to work around, as you say, it seems
more complex and less likely to be obvious than the
counter-for-activity example, which feels like the classic push-pop
paradigm.  And expecting users to write their event handlers one way
for XHR and a different way for FileReader/FileWriter seems like
asking for trouble--you're going to get issues that only come up in
exceptional cases, and involve a fairly subtle reading of several
specs to get right.  I think we're better off going with consistency.

 Adding a number-of-reads-outstanding counter isn't that much more
 code.

 It's not much more code, but it's code dealing with a case that doesn't have
 to exist, working around a very ugly and unobvious sequence of events, and
 it's something that you really shouldn't have to worry about every single
 time you use loadstart/loadend pairs.

 And if you're really trying to keep things simple, you're not
 aborting and then starting another read during the abort, so the above
 code works in your app.

 The above code and the code triggering the reads might not even be written
 by the same people--the activity display might be a third-party component
 (who very well might not have thought of this; I wouldn't have, before this
 discussion).

 --
 Glenn Maynard





Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Glenn Maynard
On Wed, Sep 21, 2011 at 6:51 PM, Eric U er...@google.com wrote:

 While it's certainly not hard to work around, as you say, it seems
 more complex and less likely to be obvious than the
 counter-for-activity example, which feels like the classic push-pop
 paradigm.


The *need* to have counters to use loadstart/loadend at all isn't obvious,
and it's a guarantee that many (perhaps most) users won't do this.  Pulling
code out of events with a timer isn't at all complex--it's a simple, common
pattern.  I think it's much more obvious, since if you don't do it an
exception is raised (that you can search for if you don't know what to do),
instead of a subtle bug being introduced.

Also note that XHR cancels the abort method entirely if you start a new
request during onabort, which means loadend isn't fired.  Having mismatched
loadstart/loadend events seems equally ugly, and not something to try to be
consistent with even if we're stuck with it for XHR.

And expecting users to write their event handlers one way
 for XHR and a different way for FileReader/FileWriter seems like
 asking for trouble--you're going to get issues that only come up in
 exceptional cases, and involve a fairly subtle reading of several
 specs to get right.  I think we're better off going with consistency.


You can write code for XHR in the same way, if you want, punting open()
calls out of abort/loadend event handlers with a timer.  It'd be depressing
to see PE turn so ugly in an attempt to be consistent with a flawed legacy
API; better to isolate the problem as much as possible.  (Are there any
other APIs with this problem besides XHR that couldn't be fixed?)

Another way to deal with this is to make loadstart (and other parts of those
calls, the error paths in particular) async, so if you start a new read
within onabort, it won't actually start until the abort finishes.  (That's a
more invasive behavioral change, of course, and I'm not sure I'd like it
myself, but it's worth at least mentioning.)

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Glenn Maynard
On Wed, Sep 21, 2011 at 7:51 PM, Eric U er...@google.com wrote:

 Again, that's not what the XHR2 spec says.  See my summary up-thread
 about the actual behavior, and Anne can correct my interpretation if
 I'm wrong.


I don't know what you mean by again; this is the first time I've described
this behavior.

The spec says The abort() algorithm can only be terminated by invoking
open() from an event handler.  If you call open() from 5.6.2's onabort,
then step 14 of the open() algorithm terminates abort(), and step 5.6.3
never happens, thus onloadend is never fired and loadstart and loadend
events are mismatched.

 Expecting users to rewrite handlers for XHR to match a new API, where
 it's not necessary for XHR's use, seems wildly optimistic.


I don't know what you're referring to.  If it clearly doesn't work (because
it's throwing an exception), they have to change their code, and it'll be
immediately obvious that they need to do so; there's no optimism involved.

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Jonas Sicking
On Wed, Sep 21, 2011 at 5:16 PM, Glenn Maynard gl...@zewt.org wrote:
 On Wed, Sep 21, 2011 at 7:51 PM, Eric U er...@google.com wrote:

 Again, that's not what the XHR2 spec says.  See my summary up-thread
 about the actual behavior, and Anne can correct my interpretation if
 I'm wrong.

 I don't know what you mean by again; this is the first time I've described
 this behavior.

 The spec says The abort() algorithm can only be terminated by invoking
 open() from an event handler.  If you call open() from 5.6.2's onabort,
 then step 14 of the open() algorithm terminates abort(), and step 5.6.3
 never happens, thus onloadend is never fired and loadstart and loadend
 events are mismatched.

This sounds like a bug in the XHR spec as it doesn't fulfill the
invariants I listed.

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-21 Thread Glenn Maynard
On Wed, Sep 21, 2011 at 8:32 PM, Eric U er...@google.com wrote:

 5.6.3 is a substep, not a step; all of 5's substeps are referred
 to as such in step 5: Otherwise run these substeps:.  However, I
 believe we were actually discussing 5.5, loadend on the XHR itself.
 Either way, the below applies to both.

 Regarding what happens on abort:

 This algorithm can be terminated by invoking the open() method. When
 it is terminated the user agent must terminate the algorithm after
 finishing the step it is on.

 I read that as saying that if you call open while in onabort [5.4], it
 completes step 5, including all of substep 5.6, including 5.5 and
 5.6.3.  Do you think I'm mistaken?  I haven't run any test cases.


To my reading, a substep is a type of step.  The after finishing... sounds
like it's saying not to terminate the currently-executing step; that is, the
event dispatch isn't stopped in the middle.  Maybe steps vs. substeps
are precisely defined somewhere else, but either way this could probably be
clearer.  Anne?

I just tried this in FF6, and the behavior is inconsistent.  If the TCP
connection has been established, then it follows your interpretation, and
you get onloadstart, onabort, onloadstart, onloadend, onloadend [1][3].  If
the TCP connection hasn't yet been established [2][4], calling open() from
either onabort or onloadend throws NS_ERROR_IN_PROGRESS.

Chrome 14 is also inconsistent.  If the TCP connection has been established
[1][3], and it's still waiting for the HTTP response, abort() seems to do
nothing.  If the connection hasn't yet been established [2], abort() does
work, and open() can be called.  onloadend is unimplemented, so the above
question is untestable [4].

(IE9 doesn't implement any of these events.)

With the various inconsistencies, I wonder if the spec can't actually be
changed to disallow open() during the events, following FF6--that
NS_ERROR_IN_PROGRESS is probably unintentional, but it's in a shipping
browser nonetheless.  Wishful thinking, maybe...

Tests:
[1] 
https://zewt.org/~glenn/test-open-during-onabort.html#http/https://zewt.org/%7Eglenn/test-open-during-onabort.html#timeout/loadend
onaborthttps://zewt.org/%7Eglenn/test-open-during-onabort.html#timeout/loadend(HTTP
timeout)
[2] 
https://zewt.org/~glenn/test-open-during-onabort.html#tcp/onaborthttps://zewt.org/%7Eglenn/test-open-during-onabort.html#timeout/loadend(TCP
timeout)
[3] 
https://zewt.org/~glenn/test-open-during-onabort.html#http/onloadendhttps://zewt.org/%7Eglenn/test-open-during-onabort.html#timeout/loadend
[4] 
https://zewt.org/~glenn/test-open-during-onabort.html#tcp/onloadendhttps://zewt.org/%7Eglenn/test-open-during-onabort.html#timeout/loadend

My point was that if it doesn't throw an exception in XHR, they won't
 write their XHR handlers that way.  And so they haven't, and have
 legacy code.  And when they add FileWriter handlers, they'll copy the
 XHR code, and it will work most of the time, because an abort is an
 exceptional case, and then it will fail in the field.


It's exceptional, but not obscure--this couldn't go unnoticed through basic
testing, since it fails with an exception.  (If people don't test their
abort code path *at all*, it isn't going to work regardless of what we
do--the goal should be to make things reliably testable, not to allow people
to deploy code without testing anything.)  I think the bugs resulting from
out-of-order loadstart/loadend messages would be very easy to miss through
regular testing, more annoying to have to work around, and more likely to be
triggered by code written by another party (eg. the activity-monitor case).

On Wed, Sep 21, 2011 at 8:34 PM, Jonas Sicking jo...@sicking.cc wrote:

  The spec says The abort() algorithm can only be terminated by invoking
  open() from an event handler.  If you call open() from 5.6.2's onabort,
  then step 14 of the open() algorithm terminates abort(), and step 5.6.3
  never happens, thus onloadend is never fired and loadstart and loadend
  events are mismatched.

 This sounds like a bug in the XHR spec as it doesn't fulfill the
 invariants I listed.


I agree with those invariants, but they aren't normative anywhere, are they?

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-20 Thread Eric U
On Mon, May 23, 2011 at 6:19 PM, Arun Ranganathan a...@mozilla.com wrote:
 On 5/23/11 6:14 PM, Arun Ranganathan wrote:

 On 5/23/11 1:20 PM, Kyle Huey wrote:

 To close the loop a bit here, Firefox 6 will make the change to
 FileReader.abort()'s throwing behavior agreed upon here.
 (https://bugzilla.mozilla.org/show_bug.cgi?id=657964)

 We have not changed the timing of the events, which are still dispatched
 synchronously.

 The editor's draft presently does nothing when readyState is EMPTY, but if
 readyState is DONE it is specified to set result to null and fire events
 (but flush any pending tasks that are queued).

 http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

 Also note that we're NOT firing *both* error and abort; we should only fire
 abort, and *not* error.

 I should change the spec. to throw.  Eric, you might change the spec. (and
 Chrome) to NOT fire error and abort events :)

 Sorry, to be a bit clearer: I'm talking about Eric changing
 http://dev.w3.org/2009/dap/file-system/file-writer.html#widl-FileSaver-abort-void
 to match http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

 -- A*




Sorry about the long delay here--a big release and a new baby absorbed
a lot of my time.  I'm going through the abort sequence right now, and
it turns out that there are a number of places in various algorithms
in FileWriter that should match FileReader more closely than they do.
However, there a couple of edge cases I'm unsure about.

1) Do you expect there to be an event called progress that indicates a
complete read, before the load event?
user agents MUST return at least one such result while processing
this read method, with the last returned value at completion of the
read -- Does that mean during onprogress, or would during onloadend
be sufficient?  What if the whole blob is read in a single backend
operation--could there be no calls to onprogress at all?

[Side note--the phrasing there is odd.  You say that useragents MUST
return, but the app's not required to call for the value, and it
can't return it if not asked.  Did you want to require the useragent
to make at least one onprogress call?]

2) The load and loadend events are queued When the data from the blob
has been completely read into memory.  If the user agent fires an
onprogress indicating all the data's been loaded, and the app calls
abort in that event handler, should those queued events be fired or
not?  If there are any tasks from the object's FileReader task source
in one of the task queues, then remove those tasks. makes it look
like no, but I wanted to make sure.  If #1 above is no or not
necessarily, then this might not ever come up anyway.

Thanks,

Eric



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-20 Thread Eric U
On Tue, Sep 20, 2011 at 3:36 PM, Eric U er...@google.com wrote:
 On Mon, May 23, 2011 at 6:19 PM, Arun Ranganathan a...@mozilla.com wrote:
 On 5/23/11 6:14 PM, Arun Ranganathan wrote:

 On 5/23/11 1:20 PM, Kyle Huey wrote:

 To close the loop a bit here, Firefox 6 will make the change to
 FileReader.abort()'s throwing behavior agreed upon here.
 (https://bugzilla.mozilla.org/show_bug.cgi?id=657964)

 We have not changed the timing of the events, which are still dispatched
 synchronously.

 The editor's draft presently does nothing when readyState is EMPTY, but if
 readyState is DONE it is specified to set result to null and fire events
 (but flush any pending tasks that are queued).

 http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

 Also note that we're NOT firing *both* error and abort; we should only fire
 abort, and *not* error.

 I should change the spec. to throw.  Eric, you might change the spec. (and
 Chrome) to NOT fire error and abort events :)

 Sorry, to be a bit clearer: I'm talking about Eric changing
 http://dev.w3.org/2009/dap/file-system/file-writer.html#widl-FileSaver-abort-void
 to match http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

 -- A*




 Sorry about the long delay here--a big release and a new baby absorbed
 a lot of my time.  I'm going through the abort sequence right now, and
 it turns out that there are a number of places in various algorithms
 in FileWriter that should match FileReader more closely than they do.
 However, there a couple of edge cases I'm unsure about.

 1) Do you expect there to be an event called progress that indicates a
 complete read, before the load event?

On further reflection, another requirement prevents this in some
cases.  If you've made a non-terminal progress event less than 50ms
before completion, you're not permitted to make another at completion,
so I think you'd go straight to load and loadend.  However, if the
entire load took place in a single underlying operation that took less
than 50ms, do you have your choice of whether or not to fire
onprogress once before onload?

 user agents MUST return at least one such result while processing
 this read method, with the last returned value at completion of the
 read -- Does that mean during onprogress, or would during onloadend
 be sufficient?  What if the whole blob is read in a single backend
 operation--could there be no calls to onprogress at all?

 [Side note--the phrasing there is odd.  You say that useragents MUST
 return, but the app's not required to call for the value, and it
 can't return it if not asked.  Did you want to require the useragent
 to make at least one onprogress call?]

 2) The load and loadend events are queued When the data from the blob
 has been completely read into memory.  If the user agent fires an
 onprogress indicating all the data's been loaded, and the app calls
 abort in that event handler, should those queued events be fired or
 not?  If there are any tasks from the object's FileReader task source
 in one of the task queues, then remove those tasks. makes it look
 like no, but I wanted to make sure.  If #1 above is no or not
 necessarily, then this might not ever come up anyway.

 Thanks,

    Eric




Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-20 Thread Eric U
On Tue, Sep 20, 2011 at 4:43 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Tue, Sep 20, 2011 at 4:28 PM, Eric U er...@google.com wrote:
 On Tue, Sep 20, 2011 at 3:36 PM, Eric U er...@google.com wrote:
 On Mon, May 23, 2011 at 6:19 PM, Arun Ranganathan a...@mozilla.com wrote:
 On 5/23/11 6:14 PM, Arun Ranganathan wrote:

 On 5/23/11 1:20 PM, Kyle Huey wrote:

 To close the loop a bit here, Firefox 6 will make the change to
 FileReader.abort()'s throwing behavior agreed upon here.
 (https://bugzilla.mozilla.org/show_bug.cgi?id=657964)

 We have not changed the timing of the events, which are still dispatched
 synchronously.

 The editor's draft presently does nothing when readyState is EMPTY, but if
 readyState is DONE it is specified to set result to null and fire events
 (but flush any pending tasks that are queued).

 http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

 Also note that we're NOT firing *both* error and abort; we should only fire
 abort, and *not* error.

 I should change the spec. to throw.  Eric, you might change the spec. (and
 Chrome) to NOT fire error and abort events :)

 Sorry, to be a bit clearer: I'm talking about Eric changing
 http://dev.w3.org/2009/dap/file-system/file-writer.html#widl-FileSaver-abort-void
 to match http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

 -- A*




 Sorry about the long delay here--a big release and a new baby absorbed
 a lot of my time.  I'm going through the abort sequence right now, and
 it turns out that there are a number of places in various algorithms
 in FileWriter that should match FileReader more closely than they do.
 However, there a couple of edge cases I'm unsure about.

 1) Do you expect there to be an event called progress that indicates a
 complete read, before the load event?

 On further reflection, another requirement prevents this in some
 cases.  If you've made a non-terminal progress event less than 50ms
 before completion, you're not permitted to make another at completion,
 so I think you'd go straight to load and loadend.  However, if the
 entire load took place in a single underlying operation that took less
 than 50ms, do you have your choice of whether or not to fire
 onprogress once before onload?

 This is a spec-bug. We need to make an exception from the 50ms rule
 for the last onprogress event.

 From the webpage point of view, the following invariants should hold
 for each load:

 1. onloadstart fires exactly once
 2. There will be one onprogress event fired when 100% progress is reached
 3. Exactly one of onabort, onload and onerror fires
 4. onloadend fires exactly once.
 6. no onprogress events fire before onloadstart
 5. no onprogress events fire after onabort/onload/onerror
 6. no onabort/onoad/onerror events fire after onloadend

 The reason for 2 is so that the page always renders a complete
 progress bar if it only does progressbar updates from the onprogress
 event.

 Hope that makes sense?

It makes sense, and in general I like it.  But the sequence can get
more complicated [specifically, nested] if you have multiple read
calls, which is the kind of annoyance that brought me to send the
email.

I have a read running, and at some point I abort it--it could be in
onprogress or elsewhere.  In onabort I start another read.  In
onloadstart I abort again.  Repeat as many times as you like, then let
a read complete.  I believe we've specced that the event sequence
should look like this:

loadstart
[progress]*
--[events from here to XXX happen synchronously, with no queueing]
abort
loadstart
abort
loadstart
abort
loadstart
loadend
loadend
loadend
--[XXX]
[progress]+
load
loadend

Does that look like what you'd expect?  Am I reading it right?  Yes,
this is a wacky fringe case.  But it's certainly reasonable to expect
someone to start a new read in onabort, so you have to implement at
least enough bookkeeping for that case.  And UAs will want to defend
against stack overflow, in the event that a bad app sticks in an
abort/loadstart loop.



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-20 Thread Glenn Maynard
On Tue, Sep 20, 2011 at 8:01 PM, Eric U er...@google.com wrote:

 I have a read running, and at some point I abort it--it could be in
 onprogress or elsewhere.  In onabort I start another read.  In
 onloadstart I abort again.  Repeat as many times as you like, then let
 a read complete.  I believe we've specced that the event sequence
 should look like this:

 loadstart
 [progress]*
 --[events from here to XXX happen synchronously, with no queueing]
 abort
 loadstart

abort
 loadstart


XHR handles this by not allowing a new request to be opened until the
abort() method terminates.  Could that be done here?  It seems like an
important thing to be consistent about.

http://dev.w3.org/2006/webapi/XMLHttpRequest/#the-abort-method

-- 
Glenn Maynard


Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-20 Thread Jonas Sicking
On Tue, Sep 20, 2011 at 5:26 PM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Sep 20, 2011 at 8:01 PM, Eric U er...@google.com wrote:

 I have a read running, and at some point I abort it--it could be in
 onprogress or elsewhere.  In onabort I start another read.  In
 onloadstart I abort again.  Repeat as many times as you like, then let
 a read complete.  I believe we've specced that the event sequence
 should look like this:

 loadstart
 [progress]*
 --[events from here to XXX happen synchronously, with no queueing]
 abort
 loadstart

 abort
 loadstart

 XHR handles this by not allowing a new request to be opened until the
 abort() method terminates.  Could that be done here?  It seems like an
 important thing to be consistent about.

 http://dev.w3.org/2006/webapi/XMLHttpRequest/#the-abort-method

Ooh, that's a good idea.

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-09-20 Thread Eric U
On Tue, Sep 20, 2011 at 5:32 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Tue, Sep 20, 2011 at 5:26 PM, Glenn Maynard gl...@zewt.org wrote:
 On Tue, Sep 20, 2011 at 8:01 PM, Eric U er...@google.com wrote:

 I have a read running, and at some point I abort it--it could be in
 onprogress or elsewhere.  In onabort I start another read.  In
 onloadstart I abort again.  Repeat as many times as you like, then let
 a read complete.  I believe we've specced that the event sequence
 should look like this:

 loadstart
 [progress]*
 --[events from here to XXX happen synchronously, with no queueing]
 abort
 loadstart

 abort
 loadstart

 XHR handles this by not allowing a new request to be opened until the
 abort() method terminates.  Could that be done here?  It seems like an
 important thing to be consistent about.

 http://dev.w3.org/2006/webapi/XMLHttpRequest/#the-abort-method

 Ooh, that's a good idea.

 / Jonas

Indeed--however, from a quick skim of XHR and XHR2, that's not what
they do.  They let open() terminate abort(), however far along it's
gotten.  If we did that, then an abort killed by a read might lead to
the aborted read never getting an onloadend.  But you could still get
the stack-busting chain of onloadstart/onabort.

If we wanted to prevent read methods from being called during abort,
we'd probably want to do that by setting an aborting flag or mucking
around with yet another readyState of ABORTING.



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-23 Thread Kyle Huey
To close the loop a bit here, Firefox 6 will make the change to
FileReader.abort()'s throwing behavior agreed upon here.  (
https://bugzilla.mozilla.org/show_bug.cgi?id=657964)

We have not changed the timing of the events, which are still dispatched
synchronously.

- Kyle

On Tue, May 17, 2011 at 3:01 PM, Kyle Huey m...@kylehuey.com wrote:

 There is actually another difference, the writing API sets the error,
 readystate value, and dispatches events off of a queued task, while the
 reading API does that synchronously.

 I'm inclined to think the synchronous version is the way to go here, since
 then the FileReader or FileWriter is totally ready for another use once the
 abort method returns.  This is less interesting for FileSaver since that can
 only do one thing.

 - Kyle

 On Tue, May 17, 2011 at 2:35 PM, Kyle Huey m...@kylehuey.com wrote:

 The abort behaviors of FileReader and File[Saver|Writer] differ.  The
 writing objects throw if the abort method is called when a write is not
 currently under way, while the reading object does not throw.

 The behaviors should be consistent.  I don't particularly care either way,
 but I believe Jonas would like to change FileReader to match
 File[Saver|Writer].

 - Kyle





Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-23 Thread Arun Ranganathan

On 5/23/11 1:20 PM, Kyle Huey wrote:
To close the loop a bit here, Firefox 6 will make the change to 
FileReader.abort()'s throwing behavior agreed upon here.  
(https://bugzilla.mozilla.org/show_bug.cgi?id=657964)


We have not changed the timing of the events, which are still 
dispatched synchronously.


The editor's draft presently does nothing when readyState is EMPTY, but 
if readyState is DONE it is specified to set result to null and fire 
events (but flush any pending tasks that are queued).


http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

Also note that we're NOT firing *both* error and abort; we should only 
fire abort, and *not* error.


I should change the spec. to throw.  Eric, you might change the spec. 
(and Chrome) to NOT fire error and abort events :)


-- A*


- Kyle

On Tue, May 17, 2011 at 3:01 PM, Kyle Huey m...@kylehuey.com 
mailto:m...@kylehuey.com wrote:


There is actually another difference, the writing API sets the
error, readystate value, and dispatches events off of a queued
task, while the reading API does that synchronously.

I'm inclined to think the synchronous version is the way to go
here, since then the FileReader or FileWriter is totally ready for
another use once the abort method returns.  This is less
interesting for FileSaver since that can only do one thing.

- Kyle

On Tue, May 17, 2011 at 2:35 PM, Kyle Huey m...@kylehuey.com
mailto:m...@kylehuey.com wrote:

The abort behaviors of FileReader and File[Saver|Writer]
differ.  The writing objects throw if the abort method is
called when a write is not currently under way, while the
reading object does not throw.

The behaviors should be consistent.  I don't particularly care
either way, but I believe Jonas would like to change
FileReader to match File[Saver|Writer].

- Kyle







Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-23 Thread Arun Ranganathan

On 5/23/11 6:14 PM, Arun Ranganathan wrote:

On 5/23/11 1:20 PM, Kyle Huey wrote:
To close the loop a bit here, Firefox 6 will make the change to 
FileReader.abort()'s throwing behavior agreed upon here.  
(https://bugzilla.mozilla.org/show_bug.cgi?id=657964)


We have not changed the timing of the events, which are still 
dispatched synchronously.


The editor's draft presently does nothing when readyState is EMPTY, 
but if readyState is DONE it is specified to set result to null and 
fire events (but flush any pending tasks that are queued).


http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort

Also note that we're NOT firing *both* error and abort; we should only 
fire abort, and *not* error.


I should change the spec. to throw.  Eric, you might change the spec. 
(and Chrome) to NOT fire error and abort events :)


Sorry, to be a bit clearer: I'm talking about Eric changing 
http://dev.w3.org/2009/dap/file-system/file-writer.html#widl-FileSaver-abort-void 
to match http://dev.w3.org/2006/webapi/FileAPI/#dfn-abort


-- A*



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-17 Thread Jonas Sicking
On Tue, May 17, 2011 at 2:35 PM, Kyle Huey m...@kylehuey.com wrote:
 The abort behaviors of FileReader and File[Saver|Writer] differ.  The
 writing objects throw if the abort method is called when a write is not
 currently under way, while the reading object does not throw.

 The behaviors should be consistent.  I don't particularly care either way,
 but I believe Jonas would like to change FileReader to match
 File[Saver|Writer].

Yeah, since we made FileReader.readAsX throw when called in the wrong
state, I believe doing the same for abort() is the better option.

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-17 Thread Eric U
On Tue, May 17, 2011 at 2:41 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Tue, May 17, 2011 at 2:35 PM, Kyle Huey m...@kylehuey.com wrote:
 The abort behaviors of FileReader and File[Saver|Writer] differ.  The
 writing objects throw if the abort method is called when a write is not
 currently under way, while the reading object does not throw.

 The behaviors should be consistent.  I don't particularly care either way,
 but I believe Jonas would like to change FileReader to match
 File[Saver|Writer].

 Yeah, since we made FileReader.readAsX throw when called in the wrong
 state, I believe doing the same for abort() is the better option.

 / Jonas

Sounds good to me.



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-17 Thread Jonas Sicking
On Tue, May 17, 2011 at 2:42 PM, Eric U er...@google.com wrote:
 It was likely just an oversight on my part that they differ.
 It does seem a bit odd to dispatch error/abort/loadend if aborting
 with no write in progress, so I favor the FileWriter/FileSaver
 behavior, but as long as they match, I'm not too bothered.

For what it's worth, FileReader.abort() currently follows what
XHR.abort() does, which is to do nothing if called in the wrong
state. I.e. no events are aborted and no exceptions are thrown.

/ Jonas



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-17 Thread Eric U
It was likely just an oversight on my part that they differ.
It does seem a bit odd to dispatch error/abort/loadend if aborting
with no write in progress, so I favor the FileWriter/FileSaver
behavior, but as long as they match, I'm not too bothered.

On Tue, May 17, 2011 at 2:35 PM, Kyle Huey m...@kylehuey.com wrote:
 The abort behaviors of FileReader and File[Saver|Writer] differ.  The
 writing objects throw if the abort method is called when a write is not
 currently under way, while the reading object does not throw.

 The behaviors should be consistent.  I don't particularly care either way,
 but I believe Jonas would like to change FileReader to match
 File[Saver|Writer].

 - Kyle




Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-17 Thread Eric U
On Tue, May 17, 2011 at 2:48 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Tue, May 17, 2011 at 2:42 PM, Eric U er...@google.com wrote:
 It was likely just an oversight on my part that they differ.
 It does seem a bit odd to dispatch error/abort/loadend if aborting
 with no write in progress, so I favor the FileWriter/FileSaver
 behavior, but as long as they match, I'm not too bothered.

 For what it's worth, FileReader.abort() currently follows what
 XHR.abort() does, which is to do nothing if called in the wrong
 state. I.e. no events are aborted and no exceptions are thrown.

Ah, my mistake; I was reading http://www.w3.org/TR/FileAPI/#abort
instead of http://dev.w3.org/2006/webapi/FileAPI/#abort.



Re: [FileAPI] FileReader.abort() and File[Saver|Writer].abort have different behaviors

2011-05-17 Thread Kyle Huey
There is actually another difference, the writing API sets the error,
readystate value, and dispatches events off of a queued task, while the
reading API does that synchronously.

I'm inclined to think the synchronous version is the way to go here, since
then the FileReader or FileWriter is totally ready for another use once the
abort method returns.  This is less interesting for FileSaver since that can
only do one thing.

- Kyle

On Tue, May 17, 2011 at 2:35 PM, Kyle Huey m...@kylehuey.com wrote:

 The abort behaviors of FileReader and File[Saver|Writer] differ.  The
 writing objects throw if the abort method is called when a write is not
 currently under way, while the reading object does not throw.

 The behaviors should be consistent.  I don't particularly care either way,
 but I believe Jonas would like to change FileReader to match
 File[Saver|Writer].

 - Kyle