Re: [clipboard] Feature detect Clipboard API support?

2015-02-11 Thread Glenn Maynard
On Wed, Feb 11, 2015 at 12:34 PM, Michaela Merz michaela.m...@hermetos.com
wrote:


 AFAIK, you can't trigger a clip board request without human interaction.

  $('#element).off().on('click',function(e) {
 var clip = new ClipboardEvent('copy');
 clip.clipboardData.setData('text/plain','some data');
 clip.preventDefault();
 e.target.dispatchEvent(clip);
 });

 This unfortunately won't work in my environment since my code is not
 'trusted'.


Events are used to detect that something happened, not to cause the thing
to happen.  The copy event tells you that a copy happened, you don't
dispatch copy to cause a copy to happen.  You use regular API calls to do
that, like execCommand(copy).  You're correct that you usually can't use
that except in response to a user action, of course.

-- 
Glenn Maynard


Re: {Spam?} Re: [xhr]

2014-09-03 Thread Glenn Maynard
(Branden, your mails keep getting {Spam?} put in the header, which means
every time you post, you create a new thread for Gmail users.  I guess it's
the list software to blame for changing subject lines, but it's making a
mess of this thread...)

On Wed, Sep 3, 2014 at 12:49 PM, Anne van Kesteren ann...@annevk.nl wrote:

 See
 http://lists.w3.org/Archives/Public/public-webapps/2014JanMar/thread.html#msg232
 for why we added a warning to the specification. It was thought that
 if we made a collective effort we can steer people away from depending
 on this. And I think from that perspective gradually phasing it out
 from the specification makes sense. With some other features we take
 the opposite approach, we never really defined them and are awaiting
 implementation experience to see whether they can be killed or need to
 be added (mutation events). I think it's fine to have several
 strategies for removing features. Hopefully over time we learn what is
 effective and what is not.


It's perfectly valid to warn people when they shouldn't use a feature.
 Sync XHR is such a strong case of this that a spec would be deeply
neglegent not to have a warning.

My only issue is the wording: it doesn't make sense to have normative
language saying you must not use this feature.  This should be a
non-normative note warning that this shouldn't be used, not a normative
requirement telling people that they must not use it.  (This is a more
general problem--the use of normative language to describe authoring
conformance criteria is generally confusing.)

-- 
Glenn Maynard


Re: Blocking message passing for Workers

2014-08-12 Thread Glenn Maynard
On Mon, Aug 11, 2014 at 6:52 PM, David Bruant bruan...@gmail.com wrote:

  Le 12/08/2014 00:40, Glenn Maynard a écrit :

  On Sat, Aug 9, 2014 at 9:12 AM, David Bruant bruan...@gmail.com wrote:

 This topic is on people minds [1]. My understanding of where we're at is
 that ECMAScript 7 will bring syntax (async/await keywords [2]) that looks
 like sync syntax, but acts asynchronously. This should eliminate the need
 for web devs for blocking message passing primitives for workers.


  Syntax sugar around async is not a replacement for synchronous APIs.

 I have yet to find a use case for hand-written code that requires sync
 APIs and cannot be achieved with async programming.


I have yet to find a use case for hand-written code that requires
structured programming and cannot be achieved with raw assembly.





 I personally hope it won't happen as it would be a step backwards.
 Blocking communication (cross-thread/process/computer) was a mistake. We
 need a culture shift. The browser and Node.js are a step in the right
 direction (they did not initiate it, but helped popularize it).


  The problem wasn't that synchronous programming is bad, the problem was
 that synchronous code in the UI thread blocks UI, and the solution to that
 is asynchronous programming.  Saying therefore all synchronous programming
 is bad is a very deep misunderstanding of the issue.

 If you block on workers, you'll mechanically need more workers. That's
 what happened with Apache that was spawning more threads as more HTTP
 requests were coming because the existing threads were busy waiting for
 blocking I/O.


That's incorrect.  If I want to perform one CPU-intensive task per CPU on a
4-CPU machine, I'm going to have 4 workers whether it's implemented sync or
async.  Not all software is a web server.

-- 
Glenn Maynard


Re: Blocking message passing for Workers

2014-08-12 Thread Glenn Maynard
On Tue, Aug 12, 2014 at 9:21 AM, David Bruant bruan...@gmail.com wrote:

 With C, Java and all, we already know where adding blocking I/O primitives
 leads to. Admittedly maybe dogma trying to learn from history.


You still seem to be confusing the issue that I explained earlier.  There's
nothing wrong with blocking in and of itself, it's doing it in a shared
thread like a UI thread that causes problems.

On Tue, Aug 12, 2014 at 1:38 PM, David Bruant bruan...@gmail.com wrote:

 Workers don't have all the APIs that main-thread JS has today. What's
 more, if one chooses to write async-only code for all contexts, then
 there's no problem.

 That's not what I had understood. So both types of APIs (sync and async)
 will be available to workers for say, IndexedDB?


No, the general idea was that most APIs (especially complex ones, like IDB)
would only have async APIs.  The block-until-a-message-is-received API
(which is all this thread is about) could then be used to create a sync
interface for any async interface (or any combination of async interfaces,
or for number crunching work in another worker).  Nobody said anything
about only having sync APIs.

-- 
Glenn Maynard


Re: Blocking message passing for Workers

2014-08-11 Thread Glenn Maynard
On Sat, Aug 9, 2014 at 9:12 AM, David Bruant bruan...@gmail.com wrote:

 This topic is on people minds [1]. My understanding of where we're at is
 that ECMAScript 7 will bring syntax (async/await keywords [2]) that looks
 like sync syntax, but acts asynchronously. This should eliminate the need
 for web devs for blocking message passing primitives for workers.


Syntax sugar around async is not a replacement for synchronous APIs.


 I personally hope it won't happen as it would be a step backwards.
 Blocking communication (cross-thread/process/computer) was a mistake. We
 need a culture shift. The browser and Node.js are a step in the right
 direction (they did not initiate it, but helped popularize it).


The problem wasn't that synchronous programming is bad, the problem was
that synchronous code in the UI thread blocks UI, and the solution to that
is asynchronous programming.  Saying therefore all synchronous programming
is bad is a very deep misunderstanding of the issue.

-- 
Glenn Maynard


Re: Blocking message passing for Workers

2014-08-08 Thread Glenn Maynard
On Fri, Aug 8, 2014 at 12:49 PM, Alan deLespinasse adelespina...@gmail.com
wrote:

 I would find it extremely useful to have a function available to a Worker
 that would block and wait for a message from another Worker or from the
 main thread. For example, instead of:

 onmessage = function(event) {
   // Do some work
   // Save all state for next time
 };

 I'd like to have something like this:

 while (true) {
   var data = waitForMessage().data;
   // Do some work
 }

 or:

 var subworker = new Worker('subworker.js');
 while (true) {
   var data = subworker.waitForMessage().data;
   // Do some work
 }


There have probably been other threads since, but here's a starting point:

http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1075.html

-- 
Glenn Maynard


Re: =[xhr]

2014-08-01 Thread Glenn Maynard
On Fri, Aug 1, 2014 at 8:39 AM, nmork_consult...@cusa.canon.com wrote:

 Spinner is not sufficient.  All user activity must stop.  They can take  a
 coffee break if it takes too long.  Browser must be frozen and locked down
 completely.  No other options are desirable.  All tabs, menus, etc. must be
 frozen.  That is exactly the desired result.


My browser isn't yours to lock down.  My menus aren't yours to freeze.  You
don't get to halt my browser, it doesn't belong to you.

In this case, a freeze on all browser operations is desirable.


It may be desirable to you, but it's never desirable to the user, and users
come first.

-- 
Glenn Maynard


Re: File API: Blob URL origin

2014-06-30 Thread Glenn Maynard
On Mon, Jun 30, 2014 at 3:57 PM, Anne van Kesteren ann...@annevk.nl wrote:

 On Mon, Jun 30, 2014 at 10:48 PM, Arun Ranganathan a...@mozilla.com
 wrote:
  They are! That is, at the time the method URL.createObjectURL(blob) is
  called on blob, that method adds an entry to the Blob URL Store:
  http://dev.w3.org/2006/webapi/FileAPI/#add-an-entry
 
  I’ve only defined identifier extraction for use with adding an entry. Is
  that wrong?

 It seems like you could define identifier creation, use that, use the
 return value to add an entry, and then return blob: + the return
 value. Creating a URL first and then parsing it again to extract
 something seems needlessly complicated.


Why would the identifier not just be the blob URL itself?  The spec
currently makes the identifier just the scheme data, which seems much more
complex than it needs to be.  revokeObjectURL should simply be Remove the
entry from the Blob URL Store for URL.  If we want to allow revoking URLs
that have a fragment attached it'd still need to strip it off; Firefox does
this, but Chrome doesn't.

Also, both Chrome and Firefox treat the entire URL as case-sensitive, eg.
Blob:... won't revoke the URL, or uppercasing the hostname portion in
Chrome.  Using the whole URL as the identifier makes this easy to do.

Subsequent attempts to dereference url must return a network error should
be removed.  That should already be the consequence of unregistering the
URL, so this is a redundant requirement.

-- 
Glenn Maynard


Re: IE - Security error with new Worker(URL.createObjectURL(new Blob([workerjs],{type:'text/javascript'})))

2014-06-06 Thread Glenn Maynard
On Fri, Jun 6, 2014 at 11:42 AM, Travis Leithead 
travis.leith...@microsoft.com wrote:

 Well, in IE's defense, this is not specifically allowed by:
 http://www.w3.org/TR/workers/#dom-worker. Regardless, the product team is
 working to fix this so that it works in IE as well. Stay tuned. I updated
 the Connect bug below.


(That link is very out of date and hard to read.  Corrected link:
http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#dom-worker
)

The algorithm described by the spec does allow blob URLs, just like any
other URL, as long as the origin is the same.  There's a non-normative note
in the spec that makes this extra clear, but IE11 may predate it: For
example, scripts can be external files with the same scheme, host, and port
as the original page, or data: URLs, or same-origin blob: URLs.

One potentially ambiguous part is that the origin of blob URLs isn't
defined clearly yet.  This is being worked on.

That said, IE11 isn't strictly out of spec, because the first step of the
algorithm allows browsers to refuse to load web workers for UA-defined
policy reasons: 1. The user agent may throw a SecurityError exception and
abort these steps if the request violates a policy decision.  However,
having a policy of not allowing workers to be loaded from blob URLs will
probably break pages that work in other browsers.

-- 
Glenn Maynard


Re: [clipboard events] click-to-copy support could be hasFeature discoverable?

2014-05-23 Thread Glenn Maynard
Hallvord: By the way, please add the editor of the HTML spec to the
beginning of the list in your references.  It's strange to list a bunch of
author names, but not the person who actually writes the spec.


On Fri, May 23, 2014 at 8:21 AM, James Greene james.m.gre...@gmail.comwrote:

 This kind of copy does not implicitly have anything to do with Selection,
 unless we continue to have its default action be copying the currently
 selected text.  It is substantially more likely to be used for custom text
 insertion.


I'd assume something like:

// Copy text:
window.copyToClipboard(hello);
// Copy HTML text:
span = document.createElement(span);
span.innerHTML = bhello/b;
window.copyToClipboard(span);
// Copy an image from a CanvasImageSource:
window.copyToClipboard(canvas);
window.copyToClipboard(img);
// Copy the selection:
window.copyToClipboard(window.getSelection());
// Copy HTML text with plaintext alternative:
dt = new DataTransferItemList();
dt.add(hello, text/plain);
dt.add(span.innerHTML, text/html);
window.copyToClipboard(dt);

This avoids the busywork of creating a DataTransfer in common cases, but
allows using DataTransfer when you want to do something more advanced, like
provide alternatives or explicitly specify a MIME type.  Note
that DataTransferItemList isn't actually constructable right now.  Note
that I used DataTransferItemList in the example and not DataTransfer, since
DataTransfer is only relevant to drag-and-drop.

I wonder what the right way to handle images is.  Native Windows
applications can copy pixel data to the clipboard, then paste it back out.
 DataTransferItem wants things to act like strings, though, so you'd have
to encode the image to a file format.  If that's PNG, that's an expensive
conversion.  Maybe DataTransferItem should be able to return an ImageSource.

(As an aside, why is the paste event's .clipboardData not set to the text
being pasted?  I wanted to see what pasting images did in current browsers,
but at least in Chrome there's nothing in there, even if I just paste plain
text.)

-- 
Glenn Maynard


Re: Blob URL Origin

2014-05-21 Thread Glenn Maynard
Hmm.  One factor that might change my mind on this: If I pass a blob URL,
revoking the URL appropriately becomes hard.  Even if it gets implemented,
auto-revoke can't help with this.  That brings back all of the problems
with non-auto-revoking blob URLs, and adds a new layer of complexity, since
I have to coordinate between the site creating the blob URL and everyone
receiving it to figure out when to revoke it.

On the other hand, I can just post the blob itself.  That avoids all of
that mess, and the other side can just create a blob URL from it itself if
that's what it needs.

That suggests that it's not worth trying to make blob URLs more accessible
cross-origin.  I can't think of any case where I'd rather pass a blob URL
instead of just posting the Blob itself.

-- 
Glenn Maynard


Re: [clipboard events] implicitly prevent default event action?

2014-05-20 Thread Glenn Maynard
On Tue, May 20, 2014 at 3:42 AM, Hallvord R. M. Steen hst...@mozilla.comwrote:

  a) The event is script-generated and has a data payload (new
  ClipboardEvent('copy', {dataType:'text/plain', data:'Hi World'}))

  I'm a little confused.  Script-generated events never have a default
  action, except for a couple isolated web-compatibility hacks where
  dispatching an event in script has side-effects, like click.

 Hm.. I didn't really know that was a rule. I basically want


I think two reasons people get confused over this are the use of the term
default action, which makes it sound like the action is part of
dispatching the event, and that there are a couple events which break this
rule (onclick; I think there are one or two others).  Reading
http://dom.spec.whatwg.org/#dispatching-events helps make this clear--it
never talks about a default action, it just tells the caller if
preventDefault() was called.

Anne: Something else that might help is speccing how the weird click-like
events work.  Those really do need a default action (though it should
probably be called something else, too much confusion over that phrase),
and there could be a big bold for web-compatibility use only warning next
to it.  I don't know if it'll help, but it seems like the event model needs
a hook for this anyway.


  Is there any way for the .clipboardData object to get reused (eg. where
 the
  .changed flag would be set to true from a previous event)?

 Well, I guess it's always possible to have an event listener call
 dispatchEvent() on some other element, passing the same event object.. Not
 sure if that matters?


As long as the implicit default behavior is removed this will have no
effect, since the only place this flag would be checked is after a real
event dispatch.

Checking whether the DataTransfer has data in it could work, too.  I
assumed that it would be pre-filled with the user's selection, and calling
setData() would just replace it.  By the way, what's the reason for not
doing it that way?  It seems to make everything simpler: it's always the
contents of .clipboardData that's being copied, .clipboardData is initially
set to the selection (resulting in no change to behavior if you don't touch
.clipboardData), and you never have to preventDefault() to change what's
copied.  I guess it assumes that any selection that the UA can support for
copy can be represented in DataTransfer, but that seems like it could be
dealt with (not every detail of the selection necessarily needs to be
script-visible in the DataTransfer).

-- 
Glenn Maynard


Re: Blob URL Origin

2014-05-20 Thread Glenn Maynard
On Tue, May 20, 2014 at 2:24 PM, Jonas Sicking jo...@sicking.cc wrote:

 Yes, we could demand that that implementations generate unguessable

UUIDs. And then define that a page from http://a.com can use img
 src=blob:http://b.com/uuid;, but if it then used that element to
 drawImage into a canvas, that the canvas would get tainted.

 But there appears to be very little utility of doing this. Rather than
 spending time implementing an unguessable UUID generator, and then
 worrying that someone would still accidentally pass a blob: URL where
 they shouldn't, I'd rather implement a way to generate a blob: URL
 which is explicitly usable cross-origin. But in img and in XHR. I.e.
 a Blob URL which responds with CORS headers.


It'd be a lot better for blob URLs to act like other resources: either full
access (same origin or CORS cross-origin) or limited access cross-origin
(usable but taints canvas, can't be read with XHR, etc.) than to block them
entirely cross-origin.

Generating unguessable tokens (including version 4 UUIDs) is so easy to do
that it doesn't make sense to limit the API based on this.

-- 
Glenn Maynard


Re: [clipboard events] click-to-copy support could be hasFeature discoverable?

2014-05-20 Thread Glenn Maynard
I think I'd suggest avoiding the mess of execCommand altogether, and add
new methods, eg. window.copy() and window.cut() (or maybe just one method,
with a cut option).  execCommand is such a nonsensical way to expose an
API that trying to stay consistent with its commands is probably not much
of a win.


On Tue, May 20, 2014 at 5:11 AM, Hallvord R. M. Steen hst...@mozilla.com
 wrote:

 However, if a scripted copy event can't take a payload and have it placed
 on the clipboard, what's the point of making script-generated copy events
 possible in the first place? If there's no point I'd rather disallow them.


This seems like you don't like an aspect of the DOM event model, so you
want it to behave differently when used with your API.  :)  There's nothing
special about copy for it to behave differently from other events, and the
other events on the platform can be generated by script.

On Tue, May 20, 2014 at 5:48 AM, Anne van Kesteren ann...@annevk.nl wrote:

 How is it true for click?


(We clarified this out of band.  Dispatching click does cause navigation,
but you have to use new MouseEvent.  This is a weird exceptional case and
should be ignored when designing new features.)

-- 
Glenn Maynard


Re: Blob URL Origin

2014-05-19 Thread Glenn Maynard
On Mon, May 19, 2014 at 3:30 AM, Jonas Sicking jo...@sicking.cc wrote:

 In at least Chrome and Firefox, blob: acts like filesystem: and can't

be loaded cross-origin. Even in cases when we normally permit loading
 of cross-origin resources like in img and script.

 This has been to prevent websites from being able to steal data by
 guessing UUIDs (at least the Gecko UUID generator isn't guaranteed to
 produce unguessable UUIDs).


Again, generating securely unguessable tokens (whether in UUID format or
not) is straightforward, so this seems doesn't seem like a reason to block
cross-origin blob URLs.

-- 
Glenn Maynard


Re: [clipboard events] implicitly prevent default event action?

2014-05-19 Thread Glenn Maynard
On Mon, May 19, 2014 at 8:50 AM, Hallvord R. M. Steen hst...@mozilla.comwrote:

 a) The event is script-generated and has a data payload (new
 ClipboardEvent('copy', {dataType:'text/plain', data:'Hi World'}))


I'm a little confused.  Script-generated events never have a default
action, except for a couple isolated web-compatibility hacks where
dispatching an event in script has side-effects, like click.  As far as I
can tell, clipboard events (tested copy and paste) aren't in that category
in Firefox, at least (Chrome doesn't have ClipboardEvent).  Can you clarify?

(Unless we're talking about events like click, I don't think we should use
the term default action at all, since it leads to a lot of confusion
about how the event model works.  The canceled flag makes this clearer:
http://dom.spec.whatwg.org/#canceled-flag)

b) Any event listener calls setData() or modifies the DataTransfer payload
 some other way


Put a changed flag on clipboardData, which is set to true by
setData.  (This flag doesn't have to be visible to script.)  When the event
handler returns, copy the selected text if both preventDefault was not
called and the changed flag on clipboardData isn't set.  That is, the UA
behavior looks like this:

var dataTransfer = new DataTransfer(selectedText);
var clipboardEvent = new ClipboardEvent(copy, { clipboardData:
dataTransfer });
if(element.dispatchEvent(clipboardEvent) || dataTransfer.changed)
copyTextToClipboard(dataTransfer);

This avoids having any weird interactions between DataTransfer and the
event system, and it's trivial to explain in terms of JS.

Is there any way for the .clipboardData object to get reused (eg. where the
.changed flag would be set to true from a previous event)?

-- 
Glenn Maynard


Re: Blob URL Origin

2014-05-16 Thread Glenn Maynard
On Fri, May 16, 2014 at 9:11 AM, Anne van Kesteren ann...@annevk.nl wrote:

 I think the sad thing is that if you couple origins with blob URLs you

can no longer hand a blob URL to an iframe-based widget and let them
 play with it. E.g. draw, modify, and hand a URL back for the modified
 image. But I guess this is a scenario you explicitly want to outlaw,
 even though you could do the equivalent by passing a Blob object
 directly and that would always work.


As I recall, when I asked why blob URLs were same-origin only, the answer
was that it was uncertain whether all platforms had a good enough PRNG to
allow generating securely-unguessable tokens for blob URLs in order to make
sure sites can't guess blob URLs for other sites.  I don't think that's an
issue (if you don't have an entropy source to implement a secure PRNG, you
don't even have basic crypto).  I think that the same-origin restriction
for blob URLs should be removed.

-- 
Glenn Maynard


Re: Blob URL Origin

2014-05-15 Thread Glenn Maynard
On Thu, May 15, 2014 at 12:07 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Thu, May 15, 2014 at 6:52 AM, Anne van Kesteren ann...@annevk.nl
 wrote:
  I was thinking about the latter and that would not work if the URL was
  revoked. Unless we store origin at parse time.

 Good point. Without using the explicit syntax we couldn't return a
 consistent result for the origin.


I pointed this out three days ago.  If my mails aren't making it through,
please let me know.
http://lists.w3.org/Archives/Public/public-webapps/2014AprJun/0397.html

-- 
Glenn Maynard


Re: Blob URL Origin

2014-05-12 Thread Glenn Maynard
On Mon, May 12, 2014 at 11:41 AM, Jonas Sicking jo...@sicking.cc wrote:

 I'd really rather we didn't make web pages parse these strings to get the
 origin.  A static method on Blob that takes a valid blob: URI and returns
 its origin seems like it should be pretty easy for UAs to implement, though.

 (new URL(url)).origin should work, no?

I don't think there have been any real differences to argue between the
implicitly or explicitly approaches, but this does argue for
explicit.  Otherwise, new URL(blobURL) would have to synchronously read
the associated Blob's metadata (which might be on disk or in another
process), and the result of new URL() would change when a blob URL is
revoked.

-- 
Glenn Maynard


Re: Custom Elements: 'data-' attributes

2014-05-07 Thread Glenn Maynard
On Wed, May 7, 2014 at 5:07 PM, Ryosuke Niwa rn...@apple.com wrote:

 There is a difference in people not caring about forward compatibility and
 polluting the global namespace, and not providing a mechanism to do it
 right in the first place.


You'll always need to be able to declare attributes that the browser
doesn't know about, for polyfills.


 If we're encouraging authors to define their own attributes, then we
 should provide a mechanism or a guideline to do so in a forward compatible
 manner.


Allowing isn't necessarily encouraging, and we do have a guideline: use
data-*.  Be careful of falling into the trap of adding complexity to fix
something that isn't actually a serious problem...

-- 
Glenn Maynard


Re: [Gamepad] Liveness of Gamepad objects

2014-04-30 Thread Glenn Maynard
On Wed, Apr 30, 2014 at 5:58 AM, Ted Mielczarek t...@mozilla.com wrote:

 Yes, it's true. In any event, this is going a bit afield. We're not going
 to spec events for the first version of the spec.


Examining the features that each design would make easier or harder isn't
afield.

On Wed, Apr 30, 2014 at 6:11 AM, Ted Mielczarek t...@mozilla.com wrote:

 My only reservation is that if Gamepad becomes a snapshot instead of a
 live object, it feels weird to suggest adding output methods to it (like
 adding vibration support). Perhaps I'm overthinking it, though.


I cut out a comment about that for length, actually.  It would be better to
have separate objects for the gamepad itself and where output methods live,
and another interface holding a snapshot of an input state.  Then, you'd
just call gamepad.getState() to read the state for that device.  It's also
a natural place for an event interface to live, and for input state that
doesn't change, like the device's ID.

I definitely wouldn't make Gamepad live just to avoid doing that, though.
 It could always be added later, by adding a GamepadDevice interface, eg:

gamepadDevices = navigator.getGamepadDevices();
gamepad = gamepads[0];
state = gamepad.getState();

equivalent to navigator.getGamepads()[0].

--
Glenn Maynard


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Glenn Maynard
Gamepad objects should definitely be a snapshot.  Otherwise, change events
could only expose the most recent state of the gamepad.  For example, if
the user presses a button and then releases it very quickly (before the
down press gets handled by script), and you fire two change events, the
script would never see the buttons as pressed.

(That said, I'm confused--where's the event to tell the user that the
gamepad has changed?  Surely this API doesn't require the developer to
poll, which would lose inputs at the slightest GC skip and could never give
high resolution timing.)

I'd also be very surprised if I received a Gamepad object and its values
were live--the interface looks like a snapshot.

On Tue, Apr 29, 2014 at 9:39 AM, Ted Mielczarek t...@mozilla.com wrote:

 snapshots and see what's changed. (Additionally as an implementation
 detail this maps very well to the Windows XInput API, which is a
 polling-based API.)


You can't just map a gamepad.xButton property to
NativeInputAPI.getCurrentXButton(), because you need to guarantee that if
you read the property twice in a row without returning to the event loop
the result is always the same, even if the button state changes while the
script is executing.  You could prevent this by caching the result and
clearing the cache when scripts aren't running, of course.

On Tue, Apr 29, 2014 at 2:27 PM, Florian Bösch pya...@gmail.com wrote:

 I think both semantics are workable. I'd likely prefer the gamepad state
 to be immutable from JS, because assigning state there is smelly. I'd also
 prefer the option that incurs less GC overhead if possible. Beyond that, I
 just think the implementations should be semantically and symbolically
 identical.


No, the object should be mutable, since most web API objects have mutable
properties.  If I want to do things like

gamepadState = getGamepads()[0]
// Run the input logic, but pretend the A button isn't pressed:
gamepadState.aButton = false;
checkInput(gamepadState);

then I should be allowed to.  There's nothing strange about this in a JS
API.

-- 
Glenn Maynard


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Glenn Maynard
On Tue, Apr 29, 2014 at 6:42 PM, Brandon Jones bajo...@google.com wrote:

 On Tue Apr 29 2014 at 4:28:31 PM, Glenn Maynard gl...@zewt.org wrote:

 (That said, I'm confused--where's the event to tell the user that the
 gamepad has changed?  Surely this API doesn't require the developer to
 poll, which would lose inputs at the slightest GC skip and could never give
 high resolution timing.)


 This is slightly off topic, but worth addressing. The spec does not, in
 fact, have any change notifications. Firefox has some experimental ones you
 can enable but they're not official. This does indeed provide an
 opportunity for input loss, but I'm not aware of anyone who's actually
 found it to be a problem. (Given the sparse number of apps using the API,
 though, that doesn't say much.)


Using snapshots makes it easier to add this later, even if it's not done
right away, since you just stash a snapshot in each event when you create
it.

I think not having change events assumed that everyone using gamepads will
have a requestAnimationFrame loop running, but not everything that might
use gamepads is a game.  Regular web pages can also use gamepads, eg. for
navigating menus.

-- 
Glenn Maynard


Re: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Glenn Maynard
On Tue, Apr 29, 2014 at 8:25 PM, Ted Mielczarek t...@mozilla.com wrote:

  On 4/29/2014 7:28 PM, Glenn Maynard wrote:

   Gamepad objects should definitely be a snapshot.  Otherwise, change
 events could only expose the most recent state of the gamepad.  For
 example, if the user presses a button and then releases it very quickly
 (before the down press gets handled by script), and you fire two change
 events, the script would never see the buttons as pressed.


 This is a good point--if we have live objects then if we do implement
 change events we'd need to store the state elsewhere. Firefox has
 gamepadbutton{press,release} events and gamepadaxismove events[1][2]
 (behind a pref), they actually do this already but it's not fantastic.


There should simply be a change event, which is fired when any property
changes.  (Some rate clamping might be needed for analog inputs, which
could change very quickly, but that's an implementation detail.)

My original prototype provided the events mentioned above. The feedback I
 received was overwhelmingly in favor of a polling API instead[3]. I decided
 to go ahead with that (actually Scott beat me to the punch and implemented
 that in Chrome first), figuring we could always spec events in a future
 revision.


(Please try to direct conversations here or to the whatwg list, so everyone
has a chance to participate...)

Supporting polling is a separate issue from whether the Gamepad interface
is live or a snapshot.  You definitely want to be able to retrieve a
snapshot of the current state, and as long as you can do that you
automatically support polling.

That is, users can either use polling:

onRequestAnimationFrame = function() {
// Once we create this, it never changes, so we can compare it the next
time around when it becomes lastGamepadState.
var gamepadState = navigator.getGamepads();

// Find differences between lastGamepadState and gamepadState and act
on them:
for(var i = 0; i  gamepadState.length; ++i)
processInput(gamepadState[i], lastGamepadState[i]);

// Save the current state, for comparison during the next frame.
lastGamepadState = gamepadState;
}

or events:

navigator.onGamepadChange = function(e) {
var gamepadState = e.state;
processInput(e.gamepadIndex, gamepadState, lastGamepadState);
lastGamepadState[e.gamepadIndex] = gamepadState;
}

In either case, gamepadState is a static snapshot.

(Aside: I'm not sure if the top one is correct.  Does
getGamepads()[n].index == n, so that gamepadState[i] always corresponds to
lastGamepadState[i]?  The spec suggests that with index of the gamepad in
the Navigator, but I'm not sure.  If so, what is getGamepads()[1] if
controller index 1 is disconnected, since you can't reorder the later
items?  undefined?)

-- 
Glenn Maynard


Re: [request] Download Event for HTMLAnchorElement

2014-03-25 Thread Glenn Maynard
On Mon, Mar 24, 2014 at 8:10 PM, Si Robertson retromodu...@gmail.comwrote:

 Allowing users to save/download a runtime-generated file with the use of
 object URLs and the anchor download attribute is the only viable way of
 doing things at the moment. Bouncing the file through a server isn't
 acceptable for web applications that are supposed to act like native apps.


You didn't quote anything, so I'm not sure what this is a reply to, but I
don't think anybody mentioned bouncing the file through a server.


 Ideally, the File API would provide a way for users to save a file, and
 I'm surprised this is still an issue. Writing a file to a user selected
 location is no less secure than allowing a user to download a file with an
 anchor.


As I mentioned earlier, the FileSaver API is defined but it hasn't been
implemented as far as I know, and it wouldn't necessarily actually solve
this problem.

-- 
Glenn Maynard


Re: [request] Download Event for HTMLAnchorElement

2014-03-24 Thread Glenn Maynard
On Mon, Mar 24, 2014 at 2:45 PM, Si Robertson retromodu...@gmail.com
 wrote:

 If a developer creates an object URL, e.g. theFile =
 URL.createObjectURL(theData), then it's the developer's responsibility to
 revoke that object URL. Assigning theFile to an anchor href so the data
 can be downloaded doesn't create a copy of data.


Requiring the user to revoke blob URLs is manual resource management, which
is inherently brittle in JS.  The eventual solution should be auto-revoke
URLs, which makes it the browser's job to revoke the URL.  We should make
that work fully, not add more events to allow manual revocation.

Autorevoke URLs are in, but the mechanism for the browser to see a.href =
myAutoRevokeObjectURL and keep the URL alive correctly is still being
worked on (https://www.w3.org/Bugs/Public/show_bug.cgi?id=17765).

That said:

On Mon, Mar 24, 2014 at 2:45 PM, Si Robertson retromodu...@gmail.comwrote:

 The web browser will definitely know when the data has been written to
 disk, the problem is the developer won't know when the data has been
 written to disk, so it's currently impossible to revoke the object URL
 (release the data from memory) at a safe time. When the anchor is clicked
 you could create a timer and revoke the object URL after a certain number
 of seconds have elapsed but you will still be taking a shot in dark.


If you don't care about the user clicking the link more than once, it
should always be safe to release the object URL immediately after the click
event has completed.  If the browser has begun downloading (copying to
disk) the blob, that operation should be unaffected by you releasing the
object URL.  You would just need to use a zero-second timer, so that you
release it after the click event has completed and not while it's being
dispatched.

(If you do something like this, be sure to hide the download link and at
least replace it with a Download in progress, or better a Click here to
restart download to regenerate the blob, so you don't leave a broken
anchor on the page.)

This may not  work in browsers yet, and this may not be well-defined in the
spec.  If it's not, I'm guessing it'll be fixed as part of
https://www.w3.org/Bugs/Public/show_bug.cgi?id=24338.

-- 
Glenn Maynard


Re: [request] Download Event for HTMLAnchorElement

2014-03-24 Thread Glenn Maynard
(Can you turn off the Outlook-style indentation quoting?  It makes the
archives unreadable:
http://lists.w3.org/Archives/Public/public-webapps/2014JanMar/0738.html,
and doesn't mix well with regular quoting.)

On Mon, Mar 24, 2014 at 5:24 PM, Brian Matthews (brmatthe) 
brmat...@cisco.com wrote:

  But I do care about the user clicking more than once. I know I do that
 occasionally, and would be annoyed at a site that wouldn't let me, and I
 don't want to annoy my users in that way. Presumably in that case I want
 the URL and blob to stay around until the page goes away, which I'd guess
 is how it would work?


Right, if you want the link to be reusable, then you can't revoke the blob
URL.  Even if the download completes, the user might still click it again.

FileSaver avoids the need for blob URLs entirely, but never got much
momentum.  It might not really solve this problem anyway, since you'd still
need to have a synchronous reference to the Blob for it to work.  If you
had to do an async request in onclick to create the Blob before you could
start the FileSaver, browsers would probably treat it as an unsolicited
popup and disallow it anyway.
http://dev.w3.org/2009/dap/file-system/file-writer.html#the-filesaver-interface

If you're actually generating a large blob of data and allowing the user to
save it to disk (for example, gunzipping a 500 MB file and saving the
uncompressed file to disk), neither of these are very good, since they both
mean writing the big data to a Blob first (probably going to disk), then
copying that to the user file when he saves it.  I haven't been following
the stream API much, but I assume this is something it would help address.

-- 
Glenn Maynard


Re: On starting WebWorkers with blob: URLs...

2014-03-17 Thread Glenn Maynard
On Mon, Mar 17, 2014 at 6:59 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Fri, Mar 14, 2014 at 10:40 PM, Ian Hickson i...@hixie.ch wrote:
  On Fri, 14 Mar 2014, Arun Ranganathan wrote:
  http://dev.w3.org/2006/webapi/FileAPI/#originOfBlobURL
 
  LGTM. Assuming that UAs implement this, that makes Workers automatically
  support blob: URLs, too.

 I don't think this is the way we should go about this. I don't
 understand why a blob URL would have an origin. Simply fetching a blob
 URL will work and the response won't be tainted and therefore it
 should work. Trying to couple origins with strings seems like a bad
 idea.


If you can load a blob URL as a worker, then it would become the origin of
the worker, right?  (That could matter more if blobs weren't same-origin
only and after cross-origin workers are supported.)

(I don't understand why blobs are only accessible by the same origin.  They
contain an unguessable random string anyway.)

-- 
Glenn Maynard


Re: [push] Consider renaming push notification to push message in the Push API spec

2014-03-11 Thread Glenn Maynard
On Mon, Mar 10, 2014 at 1:14 PM, Jeffrey Yasskin jyass...@google.comwrote:

 The term push notification in
 https://dvcs.w3.org/hg/push/raw-file/tip/index.html#dfn-push-notification
 seems to confuse people into thinking that the user will be
 notified/bothered when such a message arrives. This is reinforced by
 the fact that iOS uses push notification for exactly that: a way to
 notify the user based on a message from a server. See

 https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/WhatAreRemoteNotif.html
 .


iOS push notifications refer to sending data to the device, including
sending data to a running application without doing anything user-visible.
 The part of push notifications that displays a message to the user is
referred to as an alert, which is an optional part of a push notification.

Since the spec already uses the name PushMessage for the thing
 delivered by a push notification
 (https://dvcs.w3.org/hg/push/raw-file/tip/index.html#pushmessage-interface
 ),
 it seems like push message would be a good replacement for the
 current ambiguous name.


Calling them push messages tells me that it does mean a message to the
user.  I think using the established term push notification is clearer
than making up a new term.

-- 
Glenn Maynard


Re: [fullscreen] Problems with mouse-edge scrolling and games

2014-02-24 Thread Glenn Maynard
On Mon, Feb 24, 2014 at 4:17 AM, Florian Bösch pya...@gmail.com wrote:

 On Mon, Feb 24, 2014 at 1:16 AM, Thibaut Despoulain thib...@artillery.com
  wrote:

  I've written a test for this here:
 http://codeflow.org/issues/software-cursor.html

 My observation from testing on linux is that I can't distinguish latency
 for the software cursor from the OS cursor (or not by much anyway) in
 google chrome. In firefox however there's noticable lag. Mileage may vary
 for other platforms.


 This is true, but sadly your test runs on an empty animation frame. If
 your main thread is doing a lot of work already (barely hitting the 60fps
 mark, as it is the case for demanding games), the lag will be much more
 perceptible as you will most likely drop a frame every now and then.


 I regard dropping below 60fps as an application defect for a realtime
 interactive application where the users input is time critical.


First, mouse input is always time-critical, even if the application itself
is not.  Even for a spreadsheet, the mouse must still move responsively,
since pointing devices are difficult to use with any delay.  Some games
only run graphics at 30 FPS (like it or not), but the pointer if any must
still update at 60 FPS.

Second, system-driven pointers allow better responsiveness than is possible
at the application level.  They can process mouse input and update the
mouse cursor right when the backbuffer is flipped, giving the lowest
possible latency.  Applications (especially web apps) simply can't do that.

Going forward this could be even more severe.  For example, AirPlay video
streaming has significant video delay, but they could send mouse movement
over a sideband and draw it on the rendering device, allowing responsive
mouse movement where it would otherwise be impossible.

It's not the application's job to keep the mouse cursor responsive, it's
the system's.  Hiding the system mouse cursor and drawing one manually is
always a bad idea.

-- 
Glenn Maynard


Re: [fullscreen] Problems with mouse-edge scrolling and games

2014-02-24 Thread Glenn Maynard
(More reasons: it's very likely that you'll end up implementing a cursor
with different motion and acceleration, a different feel, than the real
mouse cursor.  It also breaks accessibility features, like mouse trails.)

On Mon, Feb 24, 2014 at 10:30 AM, Florian Bösch pya...@gmail.com wrote:

 On Mon, Feb 24, 2014 at 5:18 PM, Glenn Maynard gl...@zewt.org wrote:

 It's not the application's job to keep the mouse cursor responsive, it's
 the system's.  Hiding the system mouse cursor and drawing one manually is
 always a bad idea.


 That's a wonderful argument. And now we look at an FPS game,  or an Oculus
 Rift title, or something that requires something else than a picture cursor
 like say, an on terrain selection, a bounding box selection, a 3D ray
 picking selection/cursor, or anything like that.

 Always a bad idea, sure. How about you think about that again hm?


This doesn't seem to relate to the discussion, which is about mouse
pointers.

-- 
Glenn Maynard


Re: [fullscreen] Problems with mouse-edge scrolling and games

2014-02-24 Thread Glenn Maynard
On Mon, Feb 24, 2014 at 12:19 PM, Florian Bösch pya...@gmail.com wrote:

 Like I say, some usecases are fine with OS cursors. But that doesn't mean
 that somehow, vendors are absolved from improving input - output latency
 issues even if pointerlock is updated to allow OS cursor showing, which I'm
 all for.


Only if low latency is important to the application.  It's very important
for some games (rhythm games), moderately important for some (first-person
games controlled with a mouse, which in turn is more sensitive than with a
gamepad), and not very important at all for others (turn-based strategy).
 How much time to spend on this is a business decision, since this can be
very time-consuming and can require visual tradeoffs.

 There are a lot of usecases that involve pointing devices, and pointing
 metaphors, or view controls, virtual helmets, and so forth, that cannot
 properly function with a high input - output latency.

For this reason it's imperative not only to address the ability to make the
 OS cursor visible, but also to continue working on low latency input -
 output.


True, but tangental.  :)  (My last job was making music rhythm games, which
are more sensitive to consistent framerates than any other game genre I
know of--one dropped frame can wreck someone's game--so I'm sympathetic to
the cause.)

On Fri, Feb 21, 2014 at 7:00 PM, Ian Langworth i...@artillery.com wrote:

 The better option is to go fullscreen with the Fullscreen API, but this
 has problems as well. There are certain behaviors that occur when moving
 the cursor to the top and bottom of the screen,


I think that going fullscreen is the right approach, since locking the
mouse into the window while not fullscreen is really weird and rare, at
least in Windows.  By going fullscreen, this hooks into the same UI design
to allow the user to escape.  Even if this was supported in a window,
there'd still have to be some UI to tell the user how to exit, which could
end up having the same problem.

I've been annoyed by the edge-of-screen browser behavior too.  It's a part
of the screen where you might want to put something, like navigation UI.  I
haven't come up with a better solution, though.  I don't think having a
stronger fullscreen mode that asks the user for more permission will fly.
 Browsers try very hard to avoid asking for special permissions--people
will just agree without reading it, then won't know how to escape from the
app.

I think that for your use case of edge scrolling, having a fullscreen
notice appear at the top is OK (if a little ugly), as long as it's
transparent to mouse events so you can still see the mouse moving around
(or else you might see the mouse move to 20 pixels from the top, then never
see it actually reach the top, so you'd never start scrolling).  Menus and
address bars appearing seems like a bug.  That makes sense for the
fullscreen you get by hitting F11 in Windows or Command-Shift-F in OSX, but
application fullscreen should just act like a game, and keep as much as
possible out of the way.

-- 
Glenn Maynard


Re: File API: closed Blob objects

2013-12-16 Thread Glenn Maynard
On Thu, Dec 12, 2013 at 9:07 AM, Anne van Kesteren ann...@annevk.nl wrote:

 See https://www.w3.org/Bugs/Public/show_bug.cgi?id=24072 for context.

 What's the use case for close()?

 If we are to have close(), let's define it in such a way that once you
 invoke it the Blob represents the empty byte sequence. This way other
 code that takes and operates on Blob objects does not have to special
 case closed Blob objects, but can just treat them as Blob objects that
 happen to be empty.


Also, you can close() a Blob while an async XHR is taking place on it.
 That shouldn't affect the running operation.  It also means you can say
xhr.open(GET, blobURL); blob.close(); and have it work sensibly--the UA
can throw away the data as soon as all current operations on it have
completed.

This could be handled by synchronously taking a reference to the underlying
Blob data during the open() call.  (There are other issues about blob URLs
that need this, too, such as if a blob URL is revoked at various times
during fetch.)  If this is handled as part of parsing a URL string to a
logical URL object, and if that's done synchronously, that could take care
of a number of issues without any special casing.

-- 
Glenn Maynard


Re: File API: closed Blob objects

2013-12-16 Thread Glenn Maynard
On Mon, Dec 16, 2013 at 10:16 AM, Anne van Kesteren ann...@annevk.nlwrote:

 On Mon, Dec 16, 2013 at 4:07 PM, Glenn Maynard gl...@zewt.org wrote:
  What I meant is that it would be good for the above pattern to work, and
 not
  cause an IO error.

 Can't you always get an IO error? User removes the file, some kind of
 hard drive failure, etc.


Sure.  I mean that it shouldn't fail at all.  We should enable this as a
pattern:

function doSomething(url)
{
var xhr = new XMLHttpRequest();
xhr.open(GET, url);
xhr.send();
xhr.onload = complete_request;
}
...
function foo()
{
var blob = createSomeBlob();
var url = URL.createObjectURL(blob);
doSomething(url);
URL.revokeObjectURL(url); // or use autorevoke, but this should work too
blob.close();
}

Where the author of foo() doesn't know anything about the internals of
doSomething.  If this throws an IO error then it won't work, since closing
the blob will cause doSomething's request to fail.  You'd have to either
add a callback mechanism so foo() can call close() later, which you
shouldn't need to do for an API that simply takes a URL.

This way, you call close() to indicate that you're done with the instance
of the blob.  The browser can't actually discard the underlying data
immediately, but it knows that it can as soon as the XHR fetch finishes.
 This would be undetectable from scripts and the blob would still be
unusable for the script immediately.

-- 
Glenn Maynard


Re: RE : Sync IO APIs in Shared Workers

2013-12-07 Thread Glenn Maynard
On Wed, Dec 4, 2013 at 6:38 PM, Charles Pritchard ch...@jumis.com wrote:

 1) Sync APIs are inherently easier to use than async ones, and they are
 much
 less error prone. JS developers are not C++ developers. Whenever
 possible, it's
 just better to make things more simpler and convenient.


 This argument is not particularly helpful.


I don't know what JS developers are not C++ developers means, but it's
definitely true that it's better to provide convenient interfaces.


 Apart from that, many JS APIs use callbacks,
 all developers are-or-have to be aware of them.


Just because we can develop in more cumbersome environments isn't an
argument that we should have to.


 Devs are already in an async world when doing JS.


This isn't an argument that they should *have* to be.

It's not particularly fun re-writing async methods from the webpage to be
 sync for workers, or otherwise using shims to avoid redundancy.


(What?  Nobody is arguing that async APIs shouldn't be exposed in workers.)


 The extra semantic load on the namespaces (docs and otherwise) isn't all
 that pleasing either. There is a cost.


Yes, there's definitely a cost.  It would help a lot if things were
designed so that a sync API followed from the async API implicitly, instead
of always having to expose a separate interface.  For example, a
select()-like interface to block until the first completion from a list of
running async operations (among other things, such as MessagePorts to wake
on receipt of a message) would allow using async APIs as-is in a
synchronous way, without the need to expose a separate sync API for each
async API.

It would also solve the problem of not being able to interrupt synchronous
APIs, since the developer could--at his option--wait for both a long
operation and the receipt of a message on a cancel what you're doing
message port, whichever comes first, while still being able to write code
in a linear fashion.

-- 
Glenn Maynard


Re: [screen-orientation] Locking to 'current' orientation

2013-12-02 Thread Glenn Maynard
On Mon, Dec 2, 2013 at 10:52 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Nov 26, 2013 9:17 AM, Mounir Lamouri mou...@lamouri.fr wrote:
 
  Hi,
 
  I got some requests from different organizations to add the ability to
  lock to the 'current' orientation in the Screen Orientation API.
 
  From Javascript, that would allow writing
window.screen.lockOrientation('current');
  instead of
window.screen.lockOrientation(window.screen.orientation);
  Basically, a syntax sugar.

 I don't care too much about this one. But syntax sugar for something
 that isn't really a very common operation seems excessive. Unless
 locking to current is something we really want to encourage?


The whole point is that the API must not allow locking to a particular
orientation at all, only to the current orientation.  Allowing web pages to
cause my phone to *switch* orientations is crazy.  (You'd end up with half
of the web locking to one orientation or another, because the page looks
better that way, and you'll have the browser jumping between orientations
as you hit browser back, causing the browser UI itself to jump around.)

Locking to the current orientation deals with the use cases surrounding
gyro-based games, where you don't want the phone shifting orientations as
you move the device, without exposing something as insane as letting pages
actually force a particular orientation.

-- 
Glenn Maynard


Re: Sync IO APIs in Shared Workers

2013-11-22 Thread Glenn Maynard
On Thu, Nov 21, 2013 at 8:33 PM, Jonas Sicking jo...@sicking.cc wrote:

 One of the arguments made against sync APIs in workers made in [1] is
 that even for workers, it is often important to keep code responsive
 in order to react to actions taken by the user.


The only relevant thing I can dig out of [1] can be summarized much more
simply: we need a way to interrupt synchronous calls.

It'd be tricky to allow interruption while still leading to robust code,
but I think it's worth exploring.  In principle it violates the don't
expose asynchronous behavior principle, but in reality, asynchronous
programming with messages coming from other threads does the same thing.
We'd need to make sure it's very clear which calls can be interrupted, to
avoid EINTR-like problems.

But, we should explore the use cases more thoroughly first, to see if this
is really needed.  An alternative is to just terminate() the whole worker
and start a new one.  That's not very elegant, but it's very simple and
robust: you don't end up with synchronous APIs throwing exceptions
unexpectedly and worker code having to clean up after it.  If the work is
expensive enough that you need to cancel it, the cost of spinning up a new
worker is negligible.  Are there use cases where this doesn't work?

I.e. while locking up a worker thread for an extended period of time
 won't cause problems like stuttered scrolling or UI that doesn't
 visually react when you click them, you can still end up with apps
 that seem unresponsive since the main thread is waiting to get back an
 answer from a worker thread that is busy.


(This isn't an argument against sync APIs.  The same thing will happen with
async APIs if the page fails to give appropriate feedback to the user.)


 I also don't buy the argument that we can make async programming so
 convenient that there's little cost to async APIs compared to sync
 APIs.


I think it's wishful thinking.  My experience is that async programming is
inherently less convenient than sync programming.

Another solution would be to use real sync IO APIs, but expose an

object in the parent thread which allows the parent to abort the
 current operation.


(I'd use a MessagePort, eg. setCancellationPort(port), since the parent
thread shouldn't be special.)


 Something else that could improve responsiveness while still allowing
 people to write synchronous code is the ability to check if there are
 pending messages on a channel without having to return to the event
 loop. That way the code can keep running until there's a message to
 process, and only return to the event loop when there is.


http://lists.w3.org/Archives/Public/public-webapps/2010OctDec/1075.html
http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0967.html

The proposal is to allow polling a MessagePort, retrieving the next message
without having to return to the event loop.  I think that's useful to allow
number crunching workers to periodically check for new information, without
having to return all the way to the event loop.  It never got traction,
though.

One possible action here would be to disallow sync APIs in shared
 workers for now. This way we can use dedicated workers as a test bed
 to see if sync APIs are a problem, and if they are, if that problem
 can be fixed.


This will just make people proxy messages from the shared worker to a
dedicated worker, so nothing would change.  I don't think making shared
workers more different from dedicated workers than they have to be makes
much sense.

-- 
Glenn Maynard


Re: Sync IO APIs in Shared Workers

2013-11-22 Thread Glenn Maynard
On Fri, Nov 22, 2013 at 11:55 AM, Jonas Sicking jo...@sicking.cc wrote:

 On Fri, Nov 22, 2013 at 7:54 AM, Glenn Maynard gl...@zewt.org wrote:
  But, we should explore the use cases more thoroughly first, to see if
 this
  is really needed.  An alternative is to just terminate() the whole worker
  and start a new one.  That's not very elegant, but it's very simple and
  robust: you don't end up with synchronous APIs throwing exceptions
  unexpectedly and worker code having to clean up after it.  If the work is
  expensive enough that you need to cancel it, the cost of spinning up a
 new
  worker is negligible.

 What data are you basing this statement on?


If starting a worker is so expensive that this this is a real problem, that
seems like a bug.  If somebody is arguing that we should add a new API
because creating a new worker is slow, then that's an optimization
argument, and the burden of proof is on the claim that we need an
optimization, not that we never do.


  The proposal is to allow polling a MessagePort, retrieving the next
 message

 without having to return to the event loop.

 I don't like that solution since it's very similar to spinning event
 loops in deep call stacks. Having worked on code bases which does
 event loop spinning on deep call stacks it's a horror I wouldn't want
 to impose on anyone.


I don't think they're comparable.  Spinning the event loop may have
unrelated, unexpected side-effects, since it'll run tasks from any event
source.  This wouldn't have any effects like that at all; it would just
check for messages on a specific MessagePort, and pop off and return the
first one.  It wouldn't pull a message from any port other than the one
you're working with.

 One possible action here would be to disallow sync APIs in shared
  workers for now. This way we can use dedicated workers as a test bed
  to see if sync APIs are a problem, and if they are, if that problem
  can be fixed.
 
  This will just make people proxy messages from the shared worker to a
  dedicated worker, so nothing would change.  I don't think making shared
  workers more different from dedicated workers than they have to be makes
  much sense.

 People can already do things the wrong way is a terrible argument
 for introducing more ways of doing it the wrong way. The same argument
 could be used to say that we should add sync IO APIs on the main
 thread. It's already the case that you can write pages whose UI
 doesn't respond until you get a result back from a worker or an async
 IO operation.


I'm not convinced that synchronous work in shared workers *is* always the
wrong way.  For example, sharing client-side autocomplete in a single
shared worker may be fine, since the user isn't going to be typing into two
tabs simultaneously.

And no, that's not the argument at all.  The argument is that this is
trivial to sidestep.  The lack of sync APIs on the UI thread is hard or
impossible to sidestep.

-- 
Glenn Maynard


Re: Sync API for workers

2013-10-14 Thread Glenn Maynard
You snipped the comment about waitForMessage().  I think it should return
an Event, as if the message had been received from onmessage, not just the
received data.

On Sun, Oct 13, 2013 at 10:37 PM, Jonas Sicking jo...@sicking.cc wrote:

 This is certainly an improvement over the previous proposal. However
 given that synchronous APIs of any type are quite controversial, I'd
 rather stick to a basic approach for now.


There's nothing controversial about synchronous APIs in workers.  Doing
work synchronously is the whole point.

The nice thing about your proposal is that it's strictly additive, so
 it's something we can add later if there's agreement that the problems
 it aims to solve are problems that need solving, and there's agreement
 that the proposal is the right way to solve them.


This will cause people to learn to structure their workers poorly, and to
create worker libraries based on that structure, with extra message
relaying infrastructure to work around this, and pollute people's
still-immature understanding of message ports.  We should do it right in
the first place.


On Mon, Oct 14, 2013 at 4:33 AM, David Rajchenbach-Teller 
dtel...@mozilla.com wrote:

 Let me introduce the first sketch of a variant. The general idea is to
 add a |postSyncMessage|


(I'm not sure what problems with the existing proposals this is trying to
solve.)

-- 
Glenn Maynard


Re: Sync API for workers

2013-10-13 Thread Glenn Maynard
(e.data);
confirmPort.postMessage(answer);
}
}
---

This gives a blocking confirm() that works in workers, that can be used
with no other special work in the worker.  (Generators would not allow
that.)

-- 
Glenn Maynard


Re: Sync API for workers

2013-10-13 Thread Glenn Maynard
On Sun, Oct 13, 2013 at 8:11 PM, Glenn Maynard gl...@zewt.org wrote:

 - Descendants of a MessagePortSyncSide's initial thread are always legal
 threads.  Additionally, if the port's transferred first value is true, the
 initial thread itself is also a legal thread.
 - Ancestors of a MessagePortSyncSide's initial thread are always legal
 threads.  Additionally, if the port's transferred first value is false, the
 initial thread itself is also a legal thread.


Correction:

- Descendants of a MessagePortSyncSide's initial thread are always legal
threads.  Additionally, if the port's transferred first value is *false*,
the initial thread itself is also a legal thread.
- Ancestors of a *MessagePortAsyncSide*'s initial thread are always legal
threads.  Additionally, if the port's transferred first value is false, the
initial thread itself is also a legal thread.

The initial thread is only a valid thread for the port that was *not*
transferred first.  When the first port is transferred for the first time,
the remaining port, which is still in the thread it was created in, is
always in a valid thread.

-- 
Glenn Maynard


Re: Sync API for workers

2013-10-11 Thread Glenn Maynard
On Fri, Oct 11, 2013 at 2:24 PM, pira...@gmail.com pira...@gmail.comwrote:

 Synchronous APIs are easier to use since it's how things have been done
 since decades ago,


No, they're easier to use because they fit the model of linear human
thought more naturally.  The idea that asynchronous APIs are just as good
and easy as synchronous APIs, and that people only disagree because of lack
of experience with asynchronous APIs, is mistaken.  APIs must be designed
around how programmer's minds actually work, not how you'd like them to
work.

but the required POSIX-like APIs would be better developed as external
 libraries on top of the asynchronous ones.

  You can't build synchronous APIs on top of asynchronous APIs without the
mechanism this thread is specifically about.

-- 
Glenn Maynard


Re: [FileAPI] Questions on using Blobs for img src and a href

2013-10-04 Thread Glenn Maynard
On Thu, Oct 3, 2013 at 5:35 PM, Brian Matthews (brmatthe) 
brmat...@cisco.com wrote:

  I've been doing some prototyping around displaying images with img
 src=blob:... and providing links to content using a href=blob:
 I've got it working, and it's all very cool, but there are a couple of
 things that seem like they could work better. They might be things that are
 too user agent specific for the spec (http://www.w3.org/TR/FileAPI/) to
 comment on, but I thought I'd ask here and see if there's something I'm
 missing, and make a suggestion.


(FYI, the link you want is http://dev.w3.org/2006/webapi/FileAPI/.  Click
the Editor's Draft link at the top of the spec.  This TR link happens
to be recent, but they're often very out of date.)

 Note that from the spec one would think I could do a new File(myBlob,
 myFilename), but both Firefox and Chrome throw exceptions when I do that
 (is that expected?), and if I use a real File (from a FileList), the name
 doesn't flow through to the blob URL and isn't used when saving.


The File ctor is probably not implemented in browsers yet.  They definitely
should use the File's filename as the save-as hint, which may also not yet
be implemented.  You can file bugs on those browsers if you think it'll
help.

-- 
Glenn Maynard


Re: Regarding: Making the W3C Web SQL Database Specification Active

2013-09-27 Thread Glenn Maynard
On Fri, Sep 27, 2013 at 4:23 PM, Jonas Sicking jo...@sicking.cc wrote:

 2. *Two* independent, production quality, database implementations
 being willing to implement exactly that SQL dialect. Not a subset of
 it, and not a superset of it.


This is an overstatement.  It's not required that there be two
implementations of something that are exactly the same, match the spec
exactly, with no experimental features, no unimplemented features and no
known bugs.  That's not how development of features on the Web works.

-- 
Glenn Maynard


Re: [XHR] Content-Length header for data: URLs

2013-09-19 Thread Glenn Maynard
On Thu, Sep 19, 2013 at 6:24 PM, Hallvord Steen hst...@mozilla.com wrote:

  Are you saying it's possible to use 'data:' requests with XHR? What's
  the sense for this? The data is already on the client...

 You can indeed, in browsers that (more or less) support spec:
 http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#data:-urls-and-http

 Don't know if there are that many use cases but I guess you could easily
 get a blob from a base64-string, or use it as a more or less convenient XML
 parser if all you have is a URL-encoded string of XML source text.. :-)


The use is where you want to expose a script API that takes a URL.  Your
API can use XHR on the URL without caring if it's a data: URL, and the user
can pass in a data: URL without caring that the innards of the script
happen to use XHR with it.  It's ordinary layering--the user of your API
shouldn't have to care about those things, and you (the author of the API)
shouldn't have to worry about avoiding XHR because it'll break data: URLs.

-- 
Glenn Maynard


Re: File API: File's name property

2013-09-06 Thread Glenn Maynard
On Fri, Sep 6, 2013 at 10:42 AM, Anne van Kesteren ann...@annevk.nlwrote:

 If the raw input to the URL parser includes a backslash, it'll be
 treated as a forward slash. I am not really expecting people to use
 encodeURI or such utilities.


People who don't will have a bug, but all this is doing is preemptively
adding the bug, not preventing it, and forcing it on unrelated features
(HTMLInputElement.files).  Don't the ZIP URL proposals require some
characters or other to be escaped anyway (at least of the ones that support
navigation)?

It's far too late to try to keep people from having to escape things in
URLs.

  Having a separate field is fine.  This is specific to ZIPs, so it feels
 like
  it belongs in a ZipFile subclass, not File itself.

 Is it? There's no other file systems where the file names are
 effectively byte sequences? If that's the case, maybe that's fine.


There are lots of them.  I meant that it seems like wanting to expose raw
bytes is specific to ZIPs.  I hope we wouldn't expose the user's local
filesystem locale to the Web.  Depending on the user's locale causes some
of the more obnoxious bugs the platform has, we should be fighting to kill
it, not add more of it.


   We definitely wouldn't
  want raw bytes from filenames being filled in from user filesystems (eg.
  Shift-JIS filenames in Linux),

 The question is whether you can have something random without
 associated encoding. If there's an encoding it's easy to put lipstick
 on a pig.


You can have filenames in Linux that are in a different encoding than
expected.  I don't know why you'd want to expose that to the web, though.


   There's an API too.
 
  It might be better to wait until we have a filesystem API, then
 piggyback on
  that...

 Yeah, I wondered about that. It depends on whether we want to expose
 directories or just treat a zip archive as an ordered map of
 path/resource pairs.


I've found being able to work with a directory or a ZIP in the same way to
be useful in the past, too.


On Fri, Sep 6, 2013 at 12:08 PM, Anne van Kesteren ann...@annevk.nl wrote:

 Actually, given that zip paths are byte sequences, that would not work
 anyway. The alternative might be to always map it to code points
 somehow via requiring an encoding to be specified and just deal with
 the losses, but that doesn't seem general purpose enough.


Taking an arbitrary use case: showing the user a list of files inside a
ZIP, and letting him pick one to be extracted.  Exposing raw filenames is
one way to make this work: you iterate over Files in the ZIP, pull out the
File.name for display to the user and stash the File.rawName so you can
look up the File later.  Once the user picks a file from the list, you call
zip.getFileByRawName(stashedRawName) with the associated rawName to
retrieve the selected file.

But, that doesn't just work.  I assume the API will have a
getFileByName(DOMString filename)-like method as well as a rawName
method, and people will be much more likely to ignore byRawName and only
use byName.  The developer has to be careful to store the rawName and only
look up files using raw names if he wants broken filenames to work.

An alternative solution: as you iterate over Files to create a list to
display to the user, stash the File as well (instead of the rawName),
associated with each list entry.  When the user selects a file, you just
use the File you already have, and never pass the filename back to the
API.  This would also take special effort by developers, but no more than
the rawName solution, and it avoids exposing raw filenames entirely.

For ZIP URLs, it seems like linking inside a legacy ZIP (rather than a ZIP
of icons or whatever that you just created to link to) would be uncommon.
(Also, if you think people won't escape backslashes, they definitely won't
escape garbage filenames with a special byte-escape mechanism...)  Are
there likely use cases here?


On Fri, Sep 6, 2013 at 1:04 PM, Arun Ranganathan a...@mozilla.com wrote:

 I think it may be ok to restrict / and \.  I don't think we lose too
 much here by not allowing historically directory delimiting characters in
 file names.


\ is a valid character in real filenames.  This would break selecting
filenames with backslashes in them with HTMLInputElement, which works fine
today.

-- 
Glenn Maynard


Re: File API: File's name property

2013-09-04 Thread Glenn Maynard
On Tue, Sep 3, 2013 at 12:04 PM, Anne van Kesteren ann...@annevk.nlwrote:

 The problem is that once you put it through the URL parser it'll
 become /. And I suspect given directory APIs and such it'll go
 through that layer at some point.


I don't follow.  Backslashes in filenames are escaped in URLs (
http://zewt.org/~glenn/test%5Cfile), like all the other things that require
escaping.

 Well, my suggestion was rawName and name (which would have loss of
 information), per the current zip archive API design.


Having a separate field is fine.  This is specific to ZIPs, so it feels
like it belongs in a ZipFile subclass, not File itself.  We definitely
wouldn't want raw bytes from filenames being filled in from user
filesystems (eg. Shift-JIS filenames in Linux), and Windows filenames
aren't even bytes (they're natively UTF-16).


  By the way, in the current ZIP URL proposal, where would a File be
 created?
  If you use XHR to access a file inside a ZIP URL then you'd just get a
 Blob,
  right?

 There's an API too.


It might be better to wait until we have a filesystem API, then piggyback
on that...

-- 
Glenn Maynard


Re: File API: File's name property

2013-09-03 Thread Glenn Maynard
On Tue, Sep 3, 2013 at 9:03 AM, Arun Ranganathan a...@mozilla.com wrote:

 It wouldn't be wise to restrict '/' or '\' or try to delve too deep into
 platform land BUT the FileSystem API introduces directory syntax which
 might make being lax a fly in the ointment for later.


I wouldn't object to restricting / if it'll make other APIs more
sensible.  Every platform I've used treats it as a separator.

On Tue, Sep 3, 2013 at 10:17 AM, Anne van Kesteren ann...@annevk.nlwrote:

 I don't think you want those conversion semantics for name. I do think
 we want the value space for names across different systems to be
 equivalent, which if we support zip basically means bytes.


I don't really understand the suggestion of using a ByteString for
File.name.  Can you explain how that wouldn't break
https://zewt.org/~glenn/picker.html, if the user picks a file named
漢字.txt?

-- 
Glenn Maynard


Re: File API: File's name property

2013-09-03 Thread Glenn Maynard
On Tue, Sep 3, 2013 at 11:31 AM, Arun Ranganathan a...@mozilla.com wrote:

 And, restrict separators such as / and \.


I thought we just agreed that \ is a platform-specific thing that
File.name shouldn't restrict.  / is a directory separator on just about
every platform, but \ can appear in filenames on many systems.

On Tue, Sep 3, 2013 at 11:28 AM, Anne van Kesteren ann...@annevk.nlwrote:

 ByteString doesn't work. A byte sequence might. If the platform does
 file names in Unicode it would be converted to bytes using utf-8.


I don't know what API is being suggested that would keep File.name acting
like a String, but also allow containing arbitrary bytes.  I could imagine
one (an object that holds bytes, stringifies assuming UTF-8 and converts
from strings assuming UTF-8), but that's pretty ugly...

On Tue, Sep 3, 2013 at 11:42 AM, Anne van Kesteren ann...@annevk.nlwrote:

 That doesn't solve the problem I mentioned earlier for arbitrary file
 names coming out of zip archives. And then your data model is not
 bytes, but Unicode scalar values. We could of course accept
 information loss of some kind in the conversion process between zip
 archive resources and File objects and require developers to keep
 track of that if they care.


If you want to retain the original bytes of the filename somewhere, it
seems like it should go somewhere other than File.name.  For example, a
subclass of File, ZipFile, could contain a ByteString filenameBytes with
the original filename.  I wonder when you'd need that info, though.

By the way, in the current ZIP URL proposal, where would a File be
created?  If you use XHR to access a file inside a ZIP URL then you'd just
get a Blob, right?

-- 
Glenn Maynard


Re: File API: File's name property

2013-08-29 Thread Glenn Maynard
On Thu, Aug 29, 2013 at 9:48 AM, Anne van Kesteren ann...@annevk.nl wrote:

 As currently specified File's name property seems to be a code unit
 sequence. In zip archives the resource's path is a byte sequence. I
 don't really know what popular file systems do. Given that a File has
 to be transmitted over the wire now and then, including it's name
 property value, a code unit sequence seems like the wrong type. It
 would at least lead to information loss which I'm not sure is
 acceptable if we can prevent it (or at least make it more obvious that
 it is going on, by doing a transformation early on).


I don't think it makes sense to expect filenames to round-trip through
File.name, especially for filenames with a broken or unknown encoding.
File.name should be a best-effort at converting the platform filename to
something that can be displayed to users or encoded and put in a
Content-Disposition header, not an identifier for finding the file later.

We may also want to restrict \ and / to leave room for using these
 objects in path-based contexts later.


Forward slash, but not backslash.  That's a platform-specific restriction.
If we go down the route of limiting filenames which don't work on one or
another system, the list of restrictions becomes very long.  If path
separators are exposed on the web, they should always be forward-slashes.

-- 
Glenn Maynard


Re: File API: File's name property

2013-08-29 Thread Glenn Maynard
On Thu, Aug 29, 2013 at 10:14 AM, Anne van Kesteren ann...@annevk.nlwrote:

 On Thu, Aug 29, 2013 at 4:10 PM, Glenn Maynard gl...@zewt.org wrote:
  I don't think it makes sense to expect filenames to round-trip through
  File.name, especially for filenames with a broken or unknown encoding.
  File.name should be a best-effort at converting the platform filename to
  something that can be displayed to users or encoded and put in a
  Content-Disposition header, not an identifier for finding the file later.

 File has a constructor. We should be clearer about platforms too I suppose.


All constructing a File does is give a name (and date) to a Blob.  It
doesn't create an association to an on-disk file, and shouldn't be
restricted to filenames the local platform's filesystem can represent.

Given that the URL parser treats them identically, we should treat
 them identically everywhere else too.


URL parsing does lots of weird things that shouldn't be spread to the rest
of the platform.  File.name and URL parsing are completely different
things, and filenames on non-Windows systems can contain backslashes.

-- 
Glenn Maynard


Re: File API: File's name property

2013-08-29 Thread Glenn Maynard
On Thu, Aug 29, 2013 at 10:51 AM, Anne van Kesteren ann...@annevk.nlwrote:

 On Thu, Aug 29, 2013 at 4:46 PM, Glenn Maynard gl...@zewt.org wrote:
  All constructing a File does is give a name (and date) to a Blob.  It
  doesn't create an association to an on-disk file, and shouldn't be
  restricted to filenames the local platform's filesystem can represent.

 Yes, but it can be submitted to a server so it has to be transformed
 at some point. It seems way better to do the transformation early so
 what you see in client-side JavaScript is similar to what you'd see in
 Node.js.


It's transformed from a UTF-16 DOMString to the encoding of the protocol
it's being transferred over, just like any other DOMString being sent over
a non-UTF-16 protocol.

 URL parsing does lots of weird things that shouldn't be spread to the rest
  of the platform.  File.name and URL parsing are completely different
 things,
  and filenames on non-Windows systems can contain backslashes.

 All the more reason to do something with it to prevent down-level bugs.


We shouldn't prevent people in Linux from seeing their filenames because
those filenames wouldn't be valid on Windows.  That would require much more
than just backslashes--you'd need to prevent all characters and strings
that aren't valid in Windows, such as COM0.

Even having non-ASCII filenames will cause problems for Windows users,
since many Windows applications can only access filenames which are a
subset of the user's locale (it takes extra work to use Unicode filenames
in Windows).

-- 
Glenn Maynard


Re: Files on IndexedDB

2013-06-02 Thread Glenn Maynard
On Sun, Jun 2, 2013 at 5:02 PM, pira...@gmail.com pira...@gmail.com wrote:

  The File API spec does allow browsers to store File by reference.
 
 I thought so... that's the reason I was surprised when readed about
 implementors where doing otherwise and in fact didn't found anything
 about it on the spec.


Note that by reference means store a pointer to the original data, which
only remains valid so long as the original data is unchanged.  It doesn't
mean store the filename and allow accessing the most recent data in the
file.  All I mean is that there are things browsers can do other than
making a pessimistic deep copy of the whole file.  The spec specifically
means to avoid that, since clearly making a deep copy of a large file isn't
acceptable (and I'm very surprised if browsers are naively doing that).


  Note that there's one limitation to keep in mind.  File is meant to
  represent a snapshot of the file at the time the user gave them to the
 site,
  rather than the latest copy.  That is, if you store a File object in
  something like IDB, and the user changes the file, the next time the
 site is
  loaded it should either see a copy of the file as it was before, or get
 an
  error, not see the user's changes.  This is meant as a security measure;
 the
  idea is that a user giving a file to a site may not expect that he's
 giving
  access to that file, and all future changes, for all time, and that
  expecting users to manually revoke access to files somehow isn't
 reasonable.
 
  This is represented by the snapshot state concept.
  http://dev.w3.org/2006/webapi/FileAPI/#snapshot-state-section
 
 In fact, this can be seen both ways, just a snapshoot or a live
 update...


The spec says:

Each Blob must have a snapshot state, which must be initially set to the
state of the underlying storage, if any such underlying storage exists.

NotReadableError If the snapshot state of a File or a Blob does not match
the state of the underlying storage [...]

The snapshot state is set to the initial state of the underlying storage
(eg. the initial data).  If the current state of the file is not the same
as it was when the Blob/File was first created, reads to it fail with
NotReadableError.

I don't think this can be reasonably interpreted as allowing live updates.

(The precise definition of snapshot state is left to the browser.
Ideally, it would mean the contents of the file, but that's not possible
to do efficiently in most filesystems.  In practice, it's expected to mean
something like the mtime of the file is unchanged.  Maybe this could use
some more non-normative explanation in the spec.)


 From my point of view, if an app want just a file particular
 version (a snapshoot, by instance), it would directly copy and/or
 upload it, and if it wants to get the updated version, it would get
 the reference and being aware of this particular case.


Like I said in my first message, this is to address a security concern.
Since it's for security reasons, telling site authors to do it themselves
rather misses the point :)

-- 
Glenn Maynard


Re: Files on IndexedDB

2013-06-02 Thread Glenn Maynard
On Sun, Jun 2, 2013 at 5:50 PM, pira...@gmail.com pira...@gmail.comwrote:

 I agree, it makes sense, only that I have read contradictory info
 regarding to actual implementations. Maybe they are doing hard links
 instead plain copies, and that's the source of the confusion? This
 would be acceptable, although not all OSes or filesystems can do
 that...


Sorry, I don't know about Chrome's current behavior.  This would be pretty
easy to test; look at the link count on the file.  (I'd be surprised if
they were using hard links.)

Then Chrome is taking REALLY liberally the interpretation, because on
 some tests I removed the file and instead of raising an error it just
 gave me an empty content and null modifiedTime and lenght...


That sounds more like a simple bug/incomplete implementation than a liberal
interpretation.  If lastModifiedDate or length are null, that's definitely
a bug (neither one is nullable).

Yep :-) So, what other solution would be feasable? Both behaviours
 (inmutable and live files) seems to be valid for some use cases...


File objects aren't appropriate for live file updates, as Sicking said
elsewhere.  (If I had a nicer solution I'd have proposed it already...)

-- 
Glenn Maynard


Re: Files on IndexedDB

2013-05-30 Thread Glenn Maynard
On Thu, May 30, 2013 at 4:24 AM, pira...@gmail.com pira...@gmail.comwrote:

 According to IndexedDB specification, File and Blob and FileList objects
 should be allowed to be stored inside IndexedDB doing a shallow copy. On
 Mozilla this is possible, although File and Blob objects are stored
 nativelly on a special place on the hard disk. Chrome is working on it at
 this moment. Problem is, seems they are being duplicated and a copy is
 stored instead of a reference to the original File. I think is not the
 correct way to do it... or at least not always.

The File API spec does allow browsers to store File by reference.

Note that there's one limitation to keep in mind.  File is meant to
represent a snapshot of the file at the time the user gave them to the
site, rather than the latest copy.  That is, if you store a File object in
something like IDB, and the user changes the file, the next time the site
is loaded it should either see a copy of the file as it was before, or get
an error, not see the user's changes.  This is meant as a security measure;
the idea is that a user giving a file to a site may not expect that he's
giving access to that file, and all future changes, for all time, and that
expecting users to manually revoke access to files somehow isn't reasonable.

This is represented by the snapshot state concept.
http://dev.w3.org/2006/webapi/FileAPI/#snapshot-state-section

The difficulty is that most filesystems don't support lightweight snapshots
of files.  Making a deep copy is one way to implement this, but painfully
inefficient for large files.  Storing the file's modification time with the
snapshot, and using it to determine if the file has been changed, should be
a close enough approximation to address the security concerns.  The spec
allows this (it leaves the specifics of the state of the underlying
storage as an implementation detail).

I don't know if there are other IndexedDB-specific issues (not familiar
with that API).

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-07 Thread Glenn Maynard
On Mon, May 6, 2013 at 10:52 PM, Eric U er...@google.com wrote:

  I'm not really sure what you're saying, here.  If you want an URL to

expire or otherwise be revoked, no, you can't use it multiple times
 after that.  If you want it to work multiple times, don't revoke it or
 don't set oneTimeOnly.


No, I'm saying that APIs *internally* may perform multiple fetches, such as
if you load an API into video and the user performs multiple pauses and
seeks.  This should be completely transparent to script.  Similarly, if you
load blob URLs into srcset, the fact that srcset might load or reload the
images any number of times in the future due to changes to the environment
should be completely transparent to script.  There are lots of cases of
this, and we should have a simple, predictable approach to dealing with it.

At a high-level, my view is that (within reason) blobs should be captured
at the point of entry into the native API.  As soon as you say img.srcset
= '...; blob URL; ...', or xhr.open(objectURL), or img.src =
createObjectURL(), that point where the URL first enters the native API is
what matters.  That's a simple rule that's easy for developers to
understand in general, without needing to care about when or how many times
the fetch algorithm is run (if ever, as with srcset) on the URLs.

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-07 Thread Glenn Maynard
On Tue, May 7, 2013 at 9:45 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Mon, May 6, 2013 at 11:11 PM, Jonas Sicking jo...@sicking.cc wrote:
  The only thing that's different about XHR is that the first step in my
  list lives in one function, and the other steps live in another
  function. Doesn't seem to have any effect on the discussions here
  other than that we'd need to define which of the two functions does
  the step which grabs a reference to the Blob.

 Fair enough. So I guess we can indeed fix this by changing
 http://fetch.spec.whatwg.org/#concept-fetch to get a reference to the
 Blob/MediaStream/... before returning early as Arun suggested.


Step 1 is resolve, step 3 is fetch.  Moving it into step 1 means it would
go in resolve, not fetch.  Putting it in fetch wouldn't help, since fetch
doesn't always start synchronously.  (I'm confused, because we've talked
about this distinction several times.)

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-07 Thread Glenn Maynard
On Tue, May 7, 2013 at 4:54 PM, Jonas Sicking jo...@sicking.cc wrote:

 I'd be worried about letting any resolved URL to hold a reference to
 the Blob. We are playing very fast and loose with URLs in Gecko and
 it's never been intended that they hold on to any resources of
 significant size.


Note that I'm not suggesting that every invocation of the resolve algorithm
start capturing blob URLs.  It'd be an explicit operation at entry points
that support it, not a catch-all happening behind the scenes any time you
resolve a URL anywhere.  (Actually, I went a bit further--entry points that
don't explicitly do this shouldn't allow autorevoke URLs at all.)

The actual change required in the particular entry points might be as
simple as saying resolve URL with capture instead of resolve URL to
invoke a wrapper algorithm, but it lets it be introduced gradually and make
it clear exactly where it happens.

-- 
Glenn Maynard


Re: jar protocol (was: ZIP archive API?)

2013-05-07 Thread Glenn Maynard
On Tue, May 7, 2013 at 9:29 AM, Robin Berjon ro...@w3.org wrote:

 Have you looked at just reusing JAR for this (given that you support it in
 some form already)? I wonder how well it works. Off the top of my head I
 see at least two issues:


JARs are just ZIPs with Java metadata.  We don't need metadata, so plain
ZIPs are enough.

link rel=bundle href=bundle.wrap

 and

 img src=bundle.wrap/img/dahut.**png alt=a dahut


This depends on a document, so it wouldn't work in workers unless we add a
second API to register them in script.

--
Glenn Maynard


Re: ZIP archive API?

2013-05-06 Thread Glenn Maynard
On Mon, May 6, 2013 at 6:27 AM, Robin Berjon ro...@w3.org wrote:

 Another question to take into account here is whether this should only be
 about zip. One of the limitations of zip archives is that they aren't
 streamable. Without boiling the ocean, adding support for a streamable
 format (which I don't think needs be more complex than tar) would be a big
 plus.


Zips are streamable.  That's what the local file headers are for.
http://www.pkware.com/documents/casestudies/APPNOTE.TXT

-- 
Glenn Maynard


Re: ZIP archive API?

2013-05-06 Thread Glenn Maynard
On Mon, May 6, 2013 at 1:11 PM, Eric U er...@google.com wrote:

 This came up a few years ago; Gregg Tavares explained in [1] that only
 /some/ zipfiles are streamable, and you don't know whether yours are
 or not until you've seen the whole file.

  Eric

 [1]
 http://lists.w3.org/Archives/Public/public-webapps/2010AprJun/0362.html


The file format is streamable.  You can create files that follow the spec
that will fail when streaming, but you can also create files that follow
the spec that will fail when not streaming.  (The end of central directory
record sometimes has data after it, so you have to do a search; there's no
spec defining how far you have to search, so if you put too much data there
it'll start to fail.)  Those are both problems with the spec that would
have to be addressed.  I don't think there's any reason to support tar (and
it would significantly complicate the API, since tar *only* supports
streaming).

The bigger point here is that the ZIP appnote isn't enough.  It doesn't
define parsers or error handling.  This means that defining an API to
expose ZIPs isn't only a matter of defining an API, somebody will need to
spec the file format itself.  Also, the appnote isn't free, so this would
probably need to be a clean-room spec.  (However, it wouldn't need to
specify all of the features of the format, a huge number of which are never
used, only how to parse past them and ignore them.)


On Mon, May 6, 2013 at 1:42 PM, Jonas Sicking jo...@sicking.cc wrote:

  Another question to take into account here is whether this should only be
  about zip. One of the limitations of zip archives is that they aren't
  streamable. Without boiling the ocean, adding support for a streamable
  format (which I don't think needs be more complex than tar) would be a
 big
  plus.

 Indeed. This is IMO an argument for relying on libraries.


It's not.  ZIP has been around longer than PNG and JPEG; its only real
competors are tar.gz (which isn't useful here) and RAR (proprietary).  It's
not going away and there's no indication of a sudden influx of competing
file formats, any more than image formats.

That said, I don't know if a ZIP API is worthwhile.  I'd start lower level
here, and think about supporting inflating blobs.  That's the same
functionality any ZIP API will want, and it's the main part of the ZIP
format that you really don't want to have to do in script.  The surface
area is also far simpler: new InflatedBlob(compressedBlob)

I'm still hoping to see some performance numbers from the people
 arguing that we should add this to the platform. Without that I see
 little hope of getting enough browser vendors behind this.


I'm not aware of any optimized inflate implementation in JS to compare
against, and it's a complex algorithm, so nobody is likely to jump forward
to spend a lot of time implementing and heavily optimizing it just to show
how slow it is.  I've seen an implementation around somewhere, but it
didn't use typed arrays so it would need a lot of reworking to have any
meaning.

Every browser already has native inflate, though.

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-06 Thread Glenn Maynard
On Mon, May 6, 2013 at 7:57 PM, Anne van Kesteren ann...@annevk.nl wrote:

 On Mon, May 6, 2013 at 5:45 PM, Jonas Sicking jo...@sicking.cc wrote:
  On Mon, May 6, 2013 at 4:28 PM, Anne van Kesteren ann...@annevk.nl
 wrote:
  Okay. So that fails for XMLHttpRequest :-(
 
  What do you mean? Those are the steps we take for XHR requests too.

 So e.g. open() needs to do URL parsing (per XHR spec), send() would
 cause CSP to fail (per CSP spec), send() also does the fetch (per XHR
 spec). Overall it seems like a different model from the other APIs,
 but maybe I'm missing something?


XHR isn't so different from other APIs, it's just that the separation of
URL enters the API and the fetch is started is more obvious, and more
easily controlled from script.  I think that makes it a really good test
case.

-- 
Glenn Maynard


Re: ZIP archive API?

2013-05-06 Thread Glenn Maynard
On Mon, May 6, 2013 at 8:01 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Mon, May 6, 2013 at 5:15 PM, Glenn Maynard gl...@zewt.org wrote:
  I'm not aware of any optimized inflate implementation in JS to compare
  against, and it's a complex algorithm, so nobody is likely to jump
 forward
  to spend a lot of time implementing and heavily optimizing it just to
 show
  how slow it is.  I've seen an implementation around somewhere, but it
 didn't
  use typed arrays so it would need a lot of reworking to have any meaning.

 Likewise, I don't see any browser vendor jumping ahead and doing both
 the work to implement a library *and* and API to compare the two.


Sorry, this didn't make sense.  What library *and* API are you talking
about?  To compare what?

  Every browser already has native inflate, though.

 This is unfortunately not a terribly strong argument. Exposing that
 implementation through a DOM API requires a fairly large amount of
 work. Not to add maintaining that over the years.


You're arguing for allowing accessing files inside ZIPs by URL, which means
you're going to have to do the work anyway, since you'd be able to create a
blob URL, reference a file inside it using XHR, and get a Blob as a
result.  This is a small subset of that.

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-05 Thread Glenn Maynard
On Sun, May 5, 2013 at 7:37 PM, Jonas Sicking jo...@sicking.cc wrote:

 What we do is that we

 1. Resolve the URL against the current base URL
 2. Perform some security checks
 3. Kick off a network fetch
 4. Return

 Note that no actual network activity happens here. That is all being
 done on background threads. But what we do in step 3 is to send the
 signal to the network code that it should start doing all the stuff
 that it needs to do.

 Step 3 is where we inserted the code to grab a reference to the Blob
 such that it doesn't matter if the URL is revoked.

 Some of this code will change. For example I'd like to move towards
 doing the security checks asynchronously. Essentially by making them
 part of the the stuff that the network code needs to do. But I we'll
 always need to fire off that algorithm from the main thread, and
 generally doing that synchronously is the simplest solution.


I think the only difference between this and what I'm suggesting is that
grabbing the blob happens in step #1, instead of step #3.  That way, it
still works if the fetch isn't actually started right away (srcset,
on-demand image loading, xhr.open(), etc).

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-05 Thread Glenn Maynard
Oops, forgot this was sitting here.

On Fri, May 3, 2013 at 8:55 AM, Anne van Kesteren ann...@annevk.nl wrote:

 Glenn has at times suggested we could make a pertinent reference to
 the Blob object from the URL object you get from the parsing. That
 might work, but requires some special casing of blob URLs and soon
 mediastream URLs (and ...) in a thin wrapper around the URL parser
 which all end points would need to use.


The special casing doesn't seem bad (the specs using it don't need to know
anything about it).  It's the need to insert something into every entry
point that's annoying, but I don't see any way around that.

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-01 Thread Glenn Maynard
On Wed, May 1, 2013 at 5:36 PM, Arun Ranganathan a...@mozilla.com wrote:

 2a. To meticulously special-case Blob URLs, per Bug 17765 [4].  This calls
 for a synchronous step attached to wherever URLs are used to peg Blob URL
 data at fetch, so that the chance of a concurrent revocation doesn't cause
 things to behave unpredictably.  Firefox does a variation of this with
 keeping channels open, but solving this bug interoperably is going to be
 very hard, and has to be done in different places across the platform.  And
 even within CSS.  This is hard to move forward with.

 2b.To adopt an 80-20 rule, and only specify what happens for some cases
 that seem common, but expressly disallow other cases.  This might be a more
 muted version of Bug 17765, especially if it can't be done within fetch [5].


I'm okay with limiting this in cases where it's particularly hard to
define.  In particular, it seems like placing a hook in CSS in any
deterministic way is hard, at least today: from what I understand, the time
CSS parsing happens is unspecified.

However, we probably can't break non-autorevoke blob URLs with CSS.  So,
I'd propose:

- Start by defining that auto-revoke blob URLs may only be used with APIs
that explicitly capture the blob (putting aside the mechanics of how we do
that, for now).  Blob capture would still affect non-autorevoke blob URLs,
since it fixes race conditions, but an uncaptured blob URL would continue
to work with non-autorevoke URLs.
- Apply blob capture to one or two test cases.  I think XHR is a good place
for this, because it's easy to test, due to the xhr.open() and xhr.send()
split.  xhr.open() is where blob capture should happen, and xhr.send() is
where the fetch happens.
- Once people are comfortable with how it works, start applying it to other
major blob URL cases (eg. img).  Whether to apply it broadly to all APIs
next or not is something that could be decided at this point.

This will make autorevoke blob URLs work, gradually fix manual-revoke blob
URLs as a side-effect, and leave manual-revoke URLs unspecified but
functional for the remaining cases.  It also doesn't require us to dive in
head-first and try to apply this to every API on the platform all at once,
which nobody wants to do; it lets us test it out, then apply it to more
APIs at whatever pace makes sense.

(I don't know any way to deal with the CSS case.)



 2c. Re-use oneTimeOnly as in IE's behavior for autoRevoke (but call it
 autoRevoke).  But we jettisoned this for race conditions e.g.

 // This is in IE only

 img2.src = URL.createObjectURL(fileBlob, {oneTimeOnly: true});

 // race now! then fail in IE only
 img1.src = img2.src;

 will fail in IE with oneTimeOnly.  It appears to fail reliably, but again,
 dereference URL may not be interoperable here.  This is probably not what
 we should do, but it was worth listing, since it carries the brute force of
 a shipping implementation, and shows how some % of the market has actively
 solved this problem :)


There are a lot of problems with oneTimeOnly.  It's very easy for the URL
to never actually be used, which results in a subtle and expensive blob
leak.  For example, this:

setInterval(function() {
img.src = URL.createObjectURL(createBlob(), {oneTimeOnly: true});
}, 100);

might leak 10 blobs per second, since a browser that obtains images on
demand might not fetch the blob at all, while a browser that obtains
images immediately wouldn't.

-- 
Glenn Maynard


Re: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-01 Thread Glenn Maynard
On Wed, May 1, 2013 at 7:01 PM, Eric U er...@google.com wrote:

 Hmm...now Glenn points out another problem: if you /never/ load the
 image, for whatever reason, you can still leak it.  How likely is that
 in good code, though?  And is it worse than the current state in good
 or bad code?


I think it's much too easy for well-meaning developers to mess this up.
The example I gave is code that *does* use the URL, but the browser may or
may not actually do anything with it.  (I wouldn't even call that author
error--it's an interoperability failure.)  Also, the failures are both
expensive and subtle (eg. lots of big blobs being silently leaked to disk),
which is a pretty nasty failure mode.

Another problem is that APIs should be able to receive an API, then use it
multiple times.  For example, srcset can change the image being displayed
when the environment changes.  oneTimeOnly would be weird in that case.
For example, it would work when you load your page on a tablet, then work
again when your browser outputs the display to a TV and changes the srcset
image.  (The image was never used, so the URL is still valid.)  But then
when you go back to the tablet screen and reconfigure back to the original
configuration, it suddenly breaks, since the first URL was already used and
discarded.  The blob capture approach can be made to work with srcset, so
this would work reliably.

-- 
Glenn Maynard


Re: File API: auto-revoking blob URLs

2013-04-17 Thread Glenn Maynard
On Wed, Apr 17, 2013 at 4:58 AM, Anne van Kesteren ann...@annevk.nlwrote:

 In https://www.w3.org/Bugs/Public/show_bug.cgi?id=19594 roc suggests
 the default cannot be changed from no auto-revoking to auto-revoking.
 (And that we'll have mediastream URLs too.) Given that, I kinda doubt
 anyone will opt into setting autoRevoke to true... We could maybe
 create a different API that does the right thing but then right
 thing has not had much interest from implementers thus far (when it
 comes to the details).


I hope we can change the default, but auto-revoke is important whether we
can or not.

And again, we need to solve the blob data capturing problem anyway, because
it's a problem for manual blob URLs too (the problems are just not as
pronounced).  Currently the precise point where the fetch will no longer
fail because of a revoked blob URL is badly underdefined.  Even if you
assume dereferenced happens some time during fetch, the result is bad
interop, since it ends up depending on async task ordering, gets bit by the
loads image data on demand issue, etc.

For example, https://zewt.org/~glenn/test-blob-timing.html works
consistently in both Firefox and Chrome, which isn't clear from the specs.

https://zewt.org/~glenn/test-blob-xhr-timing.html work in Chrome, but fails
in Firefox with a mysterious not well-formed log followed by some
mojibake.

On Wed, Apr 17, 2013 at 8:07 AM, Anne van Kesteren ann...@annevk.nl wrote:

   div.style.backgroundImage = url( + url + )
   img.src = url
   img.srcset = 1x + url + , 2x  + url2
   xhr.open(GET, url)
   style body { background:url(url) } /style

 deferenced?


Are you asking when it should happen, or when the specs say they do?  No
spec defines it today, which is what we're trying to fix.  My proposal
would do it synchronously on assignment.  The CSS path is harder if its
parse time isn't clearly defined, and if that can't be fixed then it may be
impossible to support blob URLs with CSS interoperably, and we'll have to
pick whether to live with the interop issues or to not support blob URLs in
CSS at all (probably too late for that).

Again, this is for all blob URLs, not just autorevoke ones.

--
Glenn Maynard


Re: File API: auto-revoking blob URLs

2013-04-16 Thread Glenn Maynard
On Tue, Apr 16, 2013 at 4:57 AM, Anne van Kesteren ann...@annevk.nl wrote:

 As Ian pointed out (see WHATWG IRC reference above) you don't always
 want to parse synchronously as the base URL might change at a later
 stage.


For images, that's what you want--if the base URL changes after you assign
.src, the old base should still be used.  Most of the time this is what you
get now with images.  The only time you don't is the images on demand
path, which I think is a bug (this would just align those two paths).

If there are cases where base changes do need to be picked up after
assignment, we might need a bit of a hack to deal with this.  First, parse
and capture the URL synchronously, as above.  Then, at fetch time parse the
URL again.  If the resulting parsed URL is the same, use the original one,
so you retain any captured blob.  If the parsed URL has changed (because of
a base change), discard the original parsed URL and use the new one instead.

That means that if the base doesn't change (or if the URL is absolute, as
with blob URLs), the captured blob data is still there.  If the URL did
change, it'll use the new parsed URL.

This also does not work for CSS where when parsing happens is
 even less defined (which might benefit projects such as Servo).


If the time CSS parses its URLs isn't defined, then I think blob URLs are
fundamentally incompatible with being put into CSS.  Either CSS's parse
time needs to be defined, or we should disallow blob URLs in CSS.  I know
putting blob URLs in CSS is a major case for some people, but we can only
support it if we can define it interoperably.  (This applies to
non-autorevoke blobs, too, I think, depending on how undefined it is.)

 This would also fix https://www.w3.org/Bugs/Public/show_bug.cgi?id=21058,
  because URLs would be resolved against base href synchronously.

 That would make img behave differently from e.g. a download.
 Pretty sure a needs to resolve at the point it is actually clicked.


The above hack would deal with this.

-- 
Glenn Maynard


Re: File API: auto-revoking blob URLs

2013-04-15 Thread Glenn Maynard
On Mon, Apr 15, 2013 at 1:49 PM, Anne van Kesteren ann...@annevk.nl wrote:

 So blob URLs are auto-revoked by default after the current script
 stops running. However, every fetch operation in existence (apart from
 synchronous XMLHttpRequest) does so asynchronous.

 So

 img.src = blobURL


For anyone not familiar with this discussion, see
https://www.w3.org/Bugs/Public/show_bug.cgi?id=17765 for some of the prior
discussion.

This problem isn't limited to auto-revoking blobs.  UAs that obtain images
on demand won't invoke fetch synchronously at all, which causes similar
problems.  (I think the only major UA in that category is Opera.)

The solution I propose is the same as it's always been.  Have a synchronous
algorithm, eg. parse and capture the URL, which is invoked at the time
(eg.) .src is set.  This 1: invokes the URL spec's parser; 2: if the result
is a blob URL, grabs the associated blob data and puts a reference to it in
the resulting parsed URL; then 3: returns the result.  Assigning .src would
then synchronously invoke this, so the blob is always captured immediately,
even if the fetch isn't.  This way, we can synchronously resolve all this
stuff, even if the fetch won't happen for a while.

The same algorithm would be invoked at all reasonable URL entry points, so
it happens synchronously at the point where URLs enter into platform APIs.
 (For example, that means it should happen in xhr.open, not xhr.send, and
that .srcset should be pre-parsed on assignment rather than reparsed
whenever the environment changes so blob URLs in srcset are captured.)

This would also fix https://www.w3.org/Bugs/Public/show_bug.cgi?id=21058,
because URLs would be resolved against base href synchronously.

There's some question about precisely where this algorithm would be
invoked, and I don't have a complete answer to that, but I think the
discussion in #17765 makes a good start at figuring this out.  I think any
possible solution to this problem (and related problems with
non-autorevoking blobs) will have this problem, so this isn't an issue
specific to this proposal.

-- 
Glenn Maynard


Re: File API: why is there same-origin restriction on blob URLs?

2013-03-29 Thread Glenn Maynard
On Fri, Mar 29, 2013 at 10:17 AM, Jonas Sicking jo...@sicking.cc wrote:

  What I'm saying if that different browsers behave differently here.

 Requiring the crossorigin attribute might be your opinion on how to solve
 it, but its not matching how any browsers treat data: URLs right now.

We're talking about changing the behavior of blob URLs, not about data:
URLs.

This isn't my opinion; I'm just explaining what the spec currently says.
Drawing cross-origin images always taint the canvas, and img crossorigin
is used to prevent that, by effectively changing the image's origin (
http://www.whatwg.org/specs/web-apps/current-work/#origin-0 for images).

-- 
Glenn Maynard


Re: File API: why is there same-origin restriction on blob URLs?

2013-03-28 Thread Glenn Maynard
On Wed, Mar 27, 2013 at 1:35 PM, Jonas Sicking jo...@sicking.cc wrote:

 Same question applies if you create an img src=blob:... and then
 drawImage it into a canvas, does the canvas get tainted? Again, I
 think different browsers do different things for data: URLs here.


You'd need to say img crossorigin to not taint, since it's still
cross-origin, but other than that there's no reason to taint.  The idea of
image tainting is preventing access when the caller wouldn't have direct
access to pixels, which isn't the case here.


On Wed, Mar 27, 2013 at 3:16 PM, Arun Ranganathan a...@mozilla.com wrote:

  I think the original concern was that implementations might not be
  able to reliably generate unguessable URLs. Potentially that's
  something that we could require though.

 We already require this -- opaque strings should be globally unique.


Globally unique doesn't imply unguessable, of course, but it's still
trivial to do (a 256-bit securely-random number is all you need).


On Thu, Mar 28, 2013 at 12:55 AM, Anne van Kesteren ann...@annevk.nlwrote:

 As for a use case, you could have a widget that does something given a
 URL. E.g. put Googly eyes on the image resource. This widget could be
 embedded anywhere and all you'd need to do is postMessage() it a URL.
 Requiring a special code path for URLs generated from a Blob seems
 annoying for both the consumer of the widget and the producer of it.


At least for code that isn't a quick hack (where you can't ignore the
problem), you're going to need a special code path anyway to revoke the
URL.  The widget needs to communicate when it's done with the URL, and the
user needs to listen for that and revoke the URL.  If you pass in a blob,
you don't have to care about this at the widget-interface level and the
widget itself can (hopefully, some day) just use autoRevoke, and things
don't get complex if the widget wants to reuse the resource later.

This all seems more complex than just taking a Blob in the first place.
The widget (or worker, or whatever) can just say

var url = (event.data.src instanceof Blob)?
URL.createObjectURL(event.data.src, {autoRevoke: true}): event.data.src;

and use that URL.  The sender can then send either a regular URL or a
Blob.  This way, there's no extra careful communication needed to
coordinate freeing a blob URL.  It also works better in a shared worker,
where the worker might outlive the sender.

I'm not opposed to relaxing the same-origin restriction, since it seems
like a general simplification and doesn't seem to have any purpose, but I
can't really think of any case where I'd ever use it.

-- 
Glenn Maynard


Re: File API: why is there same-origin restriction on blob URLs?

2013-03-26 Thread Glenn Maynard
On Tue, Mar 26, 2013 at 7:30 PM, Jonas Sicking jo...@sicking.cc wrote:

 I think the original concern was that implementations might not be

able to reliably generate unguessable URLs. Potentially that's
 something that we could require though.


Being able to generate a securely-random token isn't a concern--if you
don't have a secure PRNG, you probably can't even do TLS.  The platform
already requires one for
https://developer.mozilla.org/en-US/docs/DOM/window.crypto.getRandomValues,
too.

For what it's worth, it seems like you don't strictly need to have
cross-origin access to blob URLs if you're passing the resource via
postMessage, since you can just post the Blob itself.  Doing it that way
avoids the brittleness of needing to revoke the URL--autoRevoke won't help
you if your'e posting a URL asynchronously--which is a significant
simplification for authors.  (Not to argue against relaxing this
restriction if the above is the only reason for it; in retrospect I might
have argued for restricting blob URLs to the same thread and event loop,
but it's too late for that now.)

-- 
Glenn Maynard


Re: File API: Blob.type

2013-03-19 Thread Glenn Maynard
 means.  I'm not saying .type should be removed.)

-- 
Glenn Maynard


Re: Pointer lock updated with clarification of lock and focus requirements.

2013-03-16 Thread Glenn Maynard
On Fri, Mar 15, 2013 at 5:24 PM, Vincent Scheib sch...@google.com wrote:

 After discussion with Olli Pettay I have clarified portions of the pointer
 lock specification.

 https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html
 https://dvcs.w3.org/hg/pointerlock/diff/6543d83c0b74/index.html

 When requesting pointer lock, this paragraph replaces previous statements
 regarding the target being in the DOM tree.
 
 Pointer lock must succeed only if the target is in the active document of
 a browsing context which is (or has an ancestor browsing context which is)
 in focus by a window which is in focus by the operating system's window
 manager. The target element and its browsing context need not be in focus.
 

 In Requirements, clarification was added that focus MAY be shifted out of
 a document and into others without exiting lock:
 
 The Pointer Lock API must exit the pointer lock state if the target is
 removed from its document, or the user agent, window, or tab loses focus.
 Moving focus between elements of active documents, including between
 browsing contexts, does not exit pointer lock. E.g. using the keyboard to
 move focus between contents of frames or iframes will not exit.
 

 Feedback and suggestions welcome.


Why would pointer lock care about focus?  If the browsing context doesn't
have focus, pointer lock may be released at the system level, but that
should be transparent to the page and reestablished automatically if the
user returns.  Pages shouldn't need to care about this.

This is the same as fullscreen--obviously a page shouldn't be forced out of
fullscreen if the user switches to another tab or application, unless
that's the system convention (which it isn't on any platform I know of).

(By the way, if a web specification finds itself talking about windows or
window managers or tabs normatively, something is probably wrong.
Interfaces at a higher abstraction level than browsing contexts are
implementation details.  Please see
http://www.whatwg.org/specs/web-apps/current-work/#dom-document-hasfocusfor
platform-independent language.)

-- 
Glenn Maynard


Re: Streams and Blobs

2013-03-15 Thread Glenn Maynard
On Fri, Mar 15, 2013 at 5:07 AM, Jonas Sicking jo...@sicking.cc wrote:

 For an async XHR, if .responseType is set to stream, then when we
 reach the HEADERS_RECEIVED state .response is set to a Stream object.
 (See more about this below)

 As data is being downloaded, we add the data to the end of the Stream
 and then fire the normal ProgressEvent events on the XHR object.
 Putting data into the Stream might cause other actions to happen,
 including firing of events. These actions thus happen before the
 ProgressEvent is fired on the XHR object.


This isn't guaranteed.  Progress events are queued tasks, and the other
actions (such as EventSource's onmessage) are also typically queued
tasks.  Since they're from different task sources, the order the tasks are
performed is unspecified.

For a sync XHR in Workers, if .responseType is set to stream when
 XHR.send() is called, we block until the HEADERS_RECEIVED state is
 reached. At that point we return from the .send() function and return
 a newly constructed Stream object. Note that reading from the Stream
 object should likely not be permitted synchronously, even within
 workers. So all that's synchronous here is waiting until we reach the
 HEADERS_RECEIVED state.


Synchronous XHR returns when it reaches DONE.  Returning at
HEADERS_RECEIVED would be strange and inconsistent.

Not supporting synchronously reading from streams is also strange.  We
should definitely be able to support this, just like we support other
synchronous I/O in workers.  Even if we don't tackle exposing this right
away, having an API design incapable of supporting it would be a serious
mistake.

This all seems to be bending and twisting XHR, and imposing arbitrary
restrictions, in order to try to make the API work in the way you first
envisioned it.  The approach I've suggested doesn't require these
contortions and restrictions.

I guess we could always make the Stream object immediately produce an
 error if .responseType is changed to something other than stream.


Specifically, I'd recommend that when readyState isn't UNSENT, setting
responseType to stream should fail, and if readyState is set to stream
then setting it to something else should fail.  That is, once the request
is started it's too late to change into or out of stream mode.

-- 
Glenn Maynard


Re: Streams and Blobs

2013-03-15 Thread Glenn Maynard
On Fri, Mar 15, 2013 at 7:23 PM, Jonas Sicking jo...@sicking.cc wrote:

  Specifically, I'd recommend that when readyState isn't UNSENT, setting
  responseType to stream should fail, and if readyState is set to
 stream
  then setting it to something else should fail.  That is, once the
 request is
  started it's too late to change into or out of stream mode.

 That would mean not supporting the ability to choose to handle a
 response as a Stream based on metadata in the response. That was the
 reason we decided to support setting .responseType in the
 HEADERS_RECEIVED state to other values. I don't see why the same
 reasons doesn't apply here.


Change readyState != UNSENT above to readyState  HEADERS_RECEIVED.
That means you have a last chance to change to or from stream mode during
the HEADERS_RECEIVED onreadystatechange event, after headers are available
and before any of the body is read, but once you're in LOADING or DONE,
stream mode is locked in (or out).  (This should apply to both of the XHR
models we've been discussing.)

-- 
Glenn Maynard


Re: IndexedDB, what were the issues? How do we stop it from happening again?

2013-03-14 Thread Glenn Maynard
On Thu, Mar 14, 2013 at 1:54 PM, Alex Russell slightly...@google.comwrote:

 On Wednesday, March 6, 2013, Tobie Langel wrote:

 On Wednesday, March 6, 2013 at 5:51 PM, Jarred Nicholls wrote:
  This is an entirely different conversation though. I don't know the
 answer to why sync interfaces are there and expected, except that some
 would argue that it makes the code easier to read/write for some devs.
 Since this is mirrored throughout other platform APIs, I wouldn't count
 this as a fault in IDB specifically.

 Sync APIs are useful to do I/O inside of a Worker.


 I don't understand why that's true. Workers have a message-oriented API
 that's inherently async. They can get back to their caller whenevs.
 What's the motivator for needing this?


Being able to write synchronous code is one of the basic uses for Workers
in the first place.  Synchronously creating streams is useful in the same
way that other synchronous APIs are useful, such as FileReaderSync.

That doesn't necessarily mean having a synchronous API for a complex
interface like this is the ideal approach (there are other ways to do it),
but that's the end goal.

(FYI, the messaging in Workers isn't inherently async; it just happens to
only have an async interface.  There's been discussion about adding a
synchronous interface to messaging.)

-- 
Glenn Maynard


Re: IndexedDB, what were the issues? How do we stop it from happening again?

2013-03-14 Thread Glenn Maynard
On Thu, Mar 14, 2013 at 8:58 PM, Tab Atkins Jr. jackalm...@gmail.comwrote:

 The entire reason for most async (all?) APIs is thus irrelevant in a

Worker, and it may be a good idea to provide sync versions, or do
 something else that negates the annoyance of dealing with async code.


I agree, except that async APIs are also useful and relevant in workers.
 Sometimes you want synchronous code and sometimes you want asynchronous
code, depending on what you're doing.


On Thu, Mar 14, 2013 at 9:19 PM, Alex Russell slightly...@google.com
 wrote:

 My *first* approach to this annoyance would be to start adding some async
 primitives to the platform that don't suck so hard; e.g., Futures/Promises.
 Saying that you should do something does not imply that doubling up on API
 surface area for a corner-case is the right solution.


Futures are nothing but a different async API.  They're in no way
comparable to synchronous code.

But, as I said, it's true that a second synchronous interface isn't
necessarily the best solution for complex APIs like IndexedDB.  At least in
this particular case, if we have a synchronous messaging API I might call
the synchronous IDB interface unnecessary.

-- 
Glenn Maynard


Re: IndexedDB, what were the issues? How do we stop it from happening again?

2013-03-14 Thread Glenn Maynard
On Thu, Mar 14, 2013 at 9:41 PM, Alex Russell slightly...@google.comwrote:

 I didn't imply they were. But addressing the pain point of asynchronous
 code that's hard to use doesn't imply that the only answer is a synchronous
 version.


The asynchronous programming model is often inherently inconvenient
compared to synchronous code, and synchronous APIs (whether at the
individual API level, or at another level such as synchronous messaging or
yieldable coroutines) are indeed the only practical solution that's been
proposed so far.  I believe this is a fundamental issue, but if you have a
concrete alternative proposal to make then by all means do so (in another
thread).  Otherwise, this just isn't helpful.

This is not a particularly hard or subtle point.


(Let's try to remain civil.)

-- 
Glenn Maynard


Re: Streams and Blobs

2013-03-11 Thread Glenn Maynard
On Mon, Mar 11, 2013 at 3:03 AM, Jonas Sicking jo...@sicking.cc wrote:

  Indeed, returning a Stream from a sync XHR in workers would be fine.
 And in that case you should do that as soon as the headers data has
 been successfully parsed.


You seem to be saying that synchronous XHR would return at LOADING, then
keep working in the background to feed the Stream.  This would be very
inconsistent.  Synchronous XHR returns to the caller when it enters the
DONE state, and once it does, its work is finished.

Also, returning to the original point: threads could block each other,
threads could deadlock each other, and a thread could deadlock with itself.

   With the supply-the-stream-and-it's-done model, XHR follows the same
   model
   it normally does: you start a request, XHR does some work, and onload
 is
   fired once the result is ready for you to use.



 I was wrong about .responseXML. But I'm correct about .response and
 .responseText.


That's just one of five modes (text vs. arraybuffer, blob, document,
json).  So, I think it's reasonable to say that providing the result at
onload isn't inconsistent with XHR's model; only text mode is inconsistent,
if anything.

(I don't really think text mode is deeply inconsistent, either, but that's
a bit of a tangent...)

 That seems to depend on how we define Stream. But if we define it as
 having a known mimetype then indeed readystate 3 is what we'll have to
 wait for.


The current spec does define it that way, at least, which makes sense for
parity with Blob.

(By the way, let's refer to states by name, so I don't have to check the
spec each time to remember what 3 means, and so we don't encourage people
to use those magic constants in their code.)

-- 
Glenn Maynard


Re: Streams and Blobs

2013-03-09 Thread Glenn Maynard
 the response is ready to be used than just
about every other use of XHR.

-- 
Glenn Maynard


Re: Streams and Blobs

2013-03-08 Thread Glenn Maynard
On Thu, Mar 7, 2013 at 9:40 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Thu, Mar 7, 2013 at 4:42 PM, Glenn Maynard gl...@zewt.org wrote:
  The alternative argument is that XHR should represent the data source,
  reading data from the network and pushing it to Stream.

 I think this is the approach I'd take. At least in Gecko this would
 allow the XHR code to generally do the same thing it does today with
 regards to actions taken on incoming network data. The only thing we'd
 do differently is which consumer to send the data to. We already have
 several such consumers which are used to implement the different
 .responseType modes, so adding another one fits right in with that
 model.


But what about the issues I mentioned (you snipped them)?  We would be
introducing overlap between XHR and every consumer of URLs
(HTMLImageElement, HTMLVideoElement, CSS loads, CSS subresources, other
XHRs), which could each mean all kinds of potential script-visible interop
subtleties.

Some more issues:

- What happens if you do a sync XHR?  It would block forever, since you'll
never see the Stream in time to hook it up to a consumer.  You don't want
to just disallow this, since then you can't set up streams synchronously at
all.  With the XHR finishes immediately model, this is straightforward:
XHR returns as soon as the headers are finished, giving you the Stream to
do whatever you need with.

- What if you create an async XHR, then hook it up to a sync XHR?  Async
XHR only does work during the event loop, so this would deadlock (the async
XHR would never run to feed data to the sync one).

- You could set up an async XHR in one worker, then read it synchronously
with XHR in another worker.  This means the first worker could block the
second worker at will, eg. by running a blocking operation during an
onprogress event, to prevent returning to the event loop.  I'm sure we
don't want to allow that (at least without careful thought, eg. the
synchronous messaging idea).


From an author point of view it also means that the XHR object behaves
 consistently for all .responseTypes. I.e. the same set of events are
 fired and the XHR object goes through the same set of states. The only
 difference is in how the data is consumed.


It would be less consistent, not more.

With the supply-the-stream-and-it's-done model, XHR follows the same model
it normally does: you start a request, XHR does some work, and onload is
fired once the result is ready for you to use.

With the runs-for-the-duration-of-the-stream model, when is the .response
available?  You can't wait for onload (where it normally becomes
available), because that wouldn't happen until the stream is finished.  The
author has to listen for readystatechange and check for the LOADING state,
which is inconsistent with most of XHR.  (Apparently text works this way
too, but that's an incremental response, not a one-time event.)

-- 
Glenn Maynard


Re: File API: Blob.type

2013-03-08 Thread Glenn Maynard
On Fri, Mar 8, 2013 at 3:43 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Thu, Mar 7, 2013 at 6:35 PM, Arun Ranganathan
 aranganat...@mozilla.com wrote:
  But I'm not sure about why we'd choose ByteString in lieu of being strict
  with what characters are allowed within DOMString.  Anne, can you shed
 some
  light on this?  And of course we should eliminate CR + LF as a
 possibility
  at constructor invocation time, possibly by throwing.

 MIME/HTTP consists of byte sequences, not code points. ByteString is a
 basic JavaScript string with certain restrictions on it to match the
 byte sequence semantics, while still behaving like a string.


MIME types are definitely strings of codepoints.  They're just strings.  We
wouldn't make script type or style type a ByteString.

And again, ByteString doesn't have anything to do with preventing CR/LF
from entering Blob.type.  You can still put CR/LF in ByteString, it does
nothing to solve the problem raised here.

ByteString is just a hack to deal with the unpleasant legacy of XHR not
encoding and decoding header text.  Don't leak that mess into Blob.  All
that's needed is the simple check I mentioned earlier (and similar
filtering in other places @type can be sourced from, if there are any other
places this could happen).

-- 
Glenn Maynard


Re: Persistent Storage vs. Database

2013-03-08 Thread Glenn Maynard
On Fri, Mar 8, 2013 at 12:36 AM, Kyle Huey m...@kylehuey.com wrote:

 On Thu, Mar 7, 2013 at 10:20 PM, Andrew Fedoniouk 
 n...@terrainformatica.com wrote:

 Physical commit (write) of objects to storage happens on either
 a) GC cycle or b) on explicit storage.commit() call or on c) VM shutdown.


 Persisting data off a GC cycle (via finalizers or something else) is a
 pretty well known antipattern.[0]


Correct, but just to be clear, there are other ways to get a similar
effect.  In particular, you can queue a task, add a job to the global
script clean-up jobs list, or use a microtask.

At least it is easier than http://www.w3.org/TR/IndexedDB/ :)


Note that if you see TR in a URL, you're probably looking at an old,
obsolete spec.  This one is almost a year out of date.  Click the editor's
draft link at the top to get to the real spec.
https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html

On Fri, Mar 8, 2013 at 1:02 PM, Andrew Fedoniouk
n...@terrainformatica.comwrote:

 At least my implementation does not use any events. Proposed
 system of events in IndexedDB is the antipattern indeed. Exactly for
 the same reasons as finalizer *events* you've mentioned above - there
 is no guarantee that all events will be delivered to the code awaiting
 and relaying on them.


This is wrong.  Events are not an antipattern (calling things that seems
a bit of a fad these days), and they're certainly not a proposal.  It's
the standard, well-established API on the Web, used broadly across the
whole platform.

-- 
Glenn Maynard


Re: IndexedDB, what were the issues? How do we stop it from happening again?

2013-03-07 Thread Glenn Maynard
On Wed, Mar 6, 2013 at 1:02 PM, Ian Fette (イアンフェッティ) ife...@google.comwrote:

 I seem to recall we contemplated people writing libraries on top of IDB
 from the beginning. I'm not sure why this is a bad thing.


Expecting libraries providing higher-level abstractions is fine, but it's
bad if an API is inconvenient to use directly for common cases.  For
example, it's natural to expect people to use a game engine library
wrapping Canvas to write a game, but Canvas itself is easy to use directly
most of the time, for lots of use cases.

The only API on the platform that I regularly use which I honestly find
unreasonable to use without a wrapper of some kind is cookies, which is one
of the worst APIs we've got.  Other than that, I can't think of any web API
that I actually need a wrapper for.  This is very good, since it means
everyone else reading my code already understands the APIs I'm using.

We originally shipped web sql / sqlite, which was a familiar interface
 for many and relatively easy to use, but had a sufficiently large API
 surface area that no one felt they wanted to document the whole thing such
 that we could have an inter-operable standard. (Yes, I'm simplifying a bit.)


(Not to get sidetracked on this, but this seems oversimplified to the point
of being confusing.
http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0025.html)

As a result, we came up with an approach of What are the fundamental
 primitives that we need?, spec'd that out, and shipped it. We had
 discussions at the time that we expected library authors to produce
 abstraction layers that made IDB easier to use, as the fundamental
 primitives approach was not necessarily intended to produce an API that
 was as straightforward and easy to use as what we were trying to replace.
 If that's now what is happening, that seems like a good thing, not a
 failure.


It's fine to not try to be as simple to use as localStorage.  That's not an
attainable goal; it's not a database in any practical sense and never tried
to be.

But if we've added a new API to the platform that typical developers
wouldn't want to use directly without any wrapper library, we've made an
error.

-- 
Glenn Maynard


Re: File API: Blob.type

2013-03-07 Thread Glenn Maynard
As an aside, I'd recommend minimizing normative dependencies on RFC2046.
Like many RFCs it's an old, unclear spec.

On Thu, Mar 7, 2013 at 12:35 PM, Arun Ranganathan aranganat...@mozilla.com
wrote:
 At some point there was a draft that specified *strict* parsing for
compliance with RFC2046, including tokenization (/) and eliminating
non-ASCII cruft.  But we scrapped that because bugs in all major browser
projects showed that this spec. text was callously ignored.  And I didn't
want to spec. fiction, so we went with the current model for Blob.type,
which is, as Anne points out, pretty lax.

Chrome, at least, throws on new Blob([], {type: 漢字}), as well as
lowercasing the string.

 I'm in favor of introducing stricter rules for Blob.type, and I'm also in
favor of allowing charset params; Glenn's example of  'if(blob.type ==
text/plain)' will break, but I don't think we should be encouraging
strict equality comparisons on blob.type (and in fact, should *discourage*
it as a practice).

 Glenn: I think that introducing a separate interface for other parameters
actually takes away from the elegance of a simple Blob.type.  The RFC
doesn't separate them, and I'm not sure we should either.  My reading of
the RFC is that parameters *are an intrinsic part of* the MIME type.

A couple points:

- I disagree that we should discourage comparing against Blob.type, but
ultimately it's such an obvious use of the property, people will do it
whether it's encouraged or not.  I'd never give it a second thought, since
that appears to be its very purpose.  Web APIs should be designed
defensively around how people will actually use the API, not how we wish
they would.  Unless lots of Blob.type parameters actually include
parameters, code will break unexpectedly when it ends up encountering one.
- The RFC defines a protocol (Content-Type), not a JavaScript API, and a
good protocols are rarely good APIs.  Having Blob.type be the literal value
of a Content-Type header isn't an elegant API.  You shouldn't need to do
parsing of a string value to extract text/plain, and you shouldn't have
to do serialization to get text/plain; charset=UTF-8.

(My reading of RFC2046 is different, but either way I don't think the
intent of that RFC should determine the design of this API, at least on
this point.  It's a spec designed with completely different goals than a
JavaScript API.)


On Thu, Mar 7, 2013 at 2:02 PM, Alexey Proskuryakov a...@webkit.org wrote:

 The current File API spec seems to have a mismatch between type in
 BlobPropertyBag, and type as Blob attribute. The latter declaratively
 states that the type is an ASCII lower case string. As mentioned by Glenn
 before, WebKit interpreted this by raising an exception in constructor for
 non-ASCII input, and lowercasing the string. I think that this is a
 reasonable reading of the spec. I'd be fine with raising exceptions for
 invalid types more eagerly.


With the file API spec as currently written, there's no normative text
saying to throw an exception, so WebKit's interpretation is incorrect, but
it's simple to fix.  In 7.1 (Constructors), add a step that says If the
type member of the options argument is set, and contains any Unicode
codepoints less than U+0020 or greater than U+007E, throw a SyntaxError
exception and abort these steps.

(WebKit actually only throws outside of [0,0x7F].  This language throws
outside of [0x20,0x7E], excluding control characters.)

I'd suggest importing WebKit's lowercasing of .type, too, in the same place.

-- 
Glenn Maynard


Re: Streams and Blobs

2013-03-07 Thread Glenn Maynard
: the receiving API can deal with restarting failed
connections transparently (you can't do that if you get a stream to a POST,
and it's not clear if you can do that even if it's a GET) instead of
pushing that onto developers; it's possible to close and reopen the stream,
and seek around as needed, and so on.  You only need a middleman like
Stream for streams that are based on complex requests (eg. a POST, or
script-sourced data).

-- 
Glenn Maynard


Re: File API: Blob.type

2013-03-06 Thread Glenn Maynard
On Wed, Mar 6, 2013 at 3:22 AM, Anne van Kesteren ann...@annevk.nl wrote:

 Okay, so given https://bugs.webkit.org/show_bug.cgi?id=111380 I think
 we should put at least minimal restrictions on Blob's constructor
 concerning Blob.type. We made it anything goes because in theory
 with Content-Type anything goes. But of course that is false and we
 should have noticed that at the time. Content-Type's value cannot
 contain CRLF, Content-Type's value is also a byte sequence, not a code
 point sequence, and certainly not a code unit sequence.

 1. I think we should change the type from DOMString to ByteString,
 just like XMLHttpRequest has it.


Blob.type is a MIME type, not a Content-Type header.  It's a string of
codepoints, not a series of bytes.  XHR is a protocol-level API, so maybe
it makes sense there, but it doesn't make sense for Blob.

WebKit already throws SyntaxError for codepoints outside the ASCII range,
eg. new Blob([], {type: 漢字}).  This should just be extended to throw for
anything that isn't printable ASCII, which would include CR, LF, and other
control characters (especially nil).  In other words, anything not in the
Unicode range [U+0020,U+007E].

It doesn't look like WebKit's exception is in the spec.  I think this
should be added.

Also, WebKit lowercases the type parameter.  This doesn't seem to be in the
spec.  (http://dev.w3.org/2006/webapi/FileAPI/#dfn-type says ASCII-encoded
string in lower case, but that's non-normative.)  I think it should be.

-- 
Glenn Maynard


Re: IndexedDB, what were the issues? How do we stop it from happening again?

2013-03-06 Thread Glenn Maynard
On Wed, Mar 6, 2013 at 8:01 AM, Alex Russell slightly...@google.com wrote:

 Comments inline. Adding some folks from the IDB team at Google to the
 thread as well as public-webapps.


(I don't want to cold CC so many people, and anybody working on an IDB
implementation should be on -webapps already, so I've trimmed the CC to
that.  I'm not subscribed to -tag, so a mail there would probably bounce
anyway.)


- *Abuse of events*
The current IDB design models one-time operations using events. This *
can* make sense insofar as events can occur zero or more times in the
future, but it's not a natural fit. What does it mean for oncomplete to
happen more than once? Is that an error? Are onsuccess and onerror
exclusive? Can they both be dispatched for an operation? The API isn't
clear. Events don't lead to good design here as they don't encapsulate
these concerns. Similarly, event handlers don't chain. This is natural, as
they could be invoked multiple times (conceptually), but it's not a good
fit for data access. It's great that IDB as async, and events are the
existing DOM model for this, but IDB's IDBRequest object is calling out for
a different kind of abstraction. I'll submit Futures for the job, but
others might work (explicit callback, whatever) so long as they maintain
chainability + async.


I disagree.  DOM events are used this way across the entire platform.
Everybody understands it, it works well, and coming up with something
different can only add more complexity and inconsistency to the platform by
having additional ways to model the same job.  I disagree both that we need
a new way of handling this, and that IDB made a mistake in using the
standard mechanism in an ordinary, well-practiced way.


- *Doubled API surface for sync version*
I assume I just don't understand why this choice was made, but the
explosion of API surface area combined with the conditional availability of
this version of the API make it an odd beast (to be charitable).

 There's currently no other way to allow an API to be synchronous in
workers but only async in the UI thread.

There was some discussion about a generalized way to allow workers to block
on a message from another thread, which would make it possible to implement
a synchronous shim for any async API in JavaScript.  In theory this could
make it unnecessary for each API to have its own synchronous interface.  It
wouldn't be as convenient, and probably wouldn't be suitable for every API,
but for big, complex interfaces like IDB it might make sense.  There might
also be other ways to express synchronous APIs based on their async
interfaces without having a whole second interface (eg. maybe something
like a method to block until an event is received).


- *The idea that this is all going to be wrapped up by libraries anyway
*

 I don't have an opinion about IDB specifically yet, but I agree that this
is wrong.

People have become so used to using wrappers around APIs that they've come
to think of them as normal, and that we should design APIs assuming people
will keep doing that.

People wrap libraries when they're hard to use, and if they're hard to use
then they're badly designed.  Just because people wrap bad APIs isn't an
excuse for designing more bad APIs.  Wrappers for basic usage are always a
bad thing: you always end up with lots of them, which means everyone is
using different APIs.  When everyone uses the provided APIs directly, we
can all read each others' code and all of our code interoperates much more
naturally.

(As you said, this is only referring to wrappers at the same level of
abstraction, of course, not libraries providing higher-level abstractions.)

-- 
Glenn Maynard


Re: File API: Blob.type

2013-03-06 Thread Glenn Maynard
On Wed, Mar 6, 2013 at 8:29 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Wed, Mar 6, 2013 at 2:21 PM, Glenn Maynard gl...@zewt.org wrote:
  Blob.type is a MIME type, not a Content-Type header.  It's a string of
  codepoints, not a series of bytes.  XHR is a protocol-level API, so
 maybe it
  makes sense there, but it doesn't make sense for Blob.

 It's a Content-Type header value and should have those restrictions.


It's not a Content-Type header, it's a MIME type.  That's part of a
Content-Type header, but they're not the same thing.

But String vs. ByteString has nothing to do with the restrictions applied
to it.

Making it a ByteString plus additional restrictions will make it do as
 required.


That doesn't make sense.  Blob.type isn't a string of bytes, it's a string
of Unicode codepoints that happens to be restricted to the ASCII range.
Applying WebKit's validity checks (with the addition of disallowing
nonprintable characters) will make it have the restrictions you want;
ByteString has nothing to do with this.


On Wed, Mar 6, 2013 at 11:47 AM, Darin Fisher da...@chromium.org wrote:

 So the intent is to allow specifying attributes like charset?  That
 sounds useful.


I don't think so.  This isn't very well-defined by RFC2046 (it seems vague
about the relationship of parameters to MIME types), but I'm pretty sure
Blob.type is meant to be only a MIME type, not a MIME type plus
content-type parameters.  Also, it would lead to a poor API: you could no
longer simply say 'if(blob.type == text/plain)'; you'd have to parse it
out yourself (which I expect nobody is actually doing).

Other parameters should have a separate interface, eg.
blob.typeParameters.charset = UTF-8, if we want that.

-- 
Glenn Maynard


Re: The need to re-subscribe to requestAnimationFrame

2013-03-02 Thread Glenn Maynard
On Sat, Mar 2, 2013 at 5:03 AM, David Bruant bruan...@gmail.com wrote:

 If someone wants to reuse the same function for requestionAnimationFrame,
 he/she has to go through:
 requestAnimationFrame(function f(){
 requestAnimationFrame(f);
 // do stuff
 })


FYI, this pattern is cleaner, so you only have to call
requestAnimationFrame in one place:

function draw() {
// render
requestAnimationFrame(draw);
}
draw();

-- 
Glenn Maynard


Re: Streams and Blobs

2013-02-28 Thread Glenn Maynard
On Thu, Feb 28, 2013 at 12:13 AM, Darin Fisher da...@chromium.org wrote:

 It's a fair question, and I think you've made a lot of good points.  I
 think XHR gives you the ability to customize the HTTP request.  You can set
 custom request headers, customize the request method, control cross-origin
 behavior, etc.  It gives the developer a lot of flexibility.


I just think the complexity hasn't been justified with actual use cases for
that flexibility.

 Another thing not to lose sight of is that a Stream abstraction could be
 useful as an optimization tool.  There are times when a developer just
 needs to connect a data stream from a provider to a consumer and doesn't
 necessarily care about seeing the raw bytes.  (The data may not even be
 available in the address space of the process running the developer's
 script.)  So, I can imagine some optimization opportunities when we work
 with a handle to a stream of data rather than the data itself.


Blob is already a handle to data that can be passed around without having
the data it represents in memory.  It's ArrayBuffer that usually represents
actual, in-memory data.  Blob is already meant to allow these optimizations.


On Thu, Feb 28, 2013 at 1:07 AM, Travis Leithead 
travis.leith...@microsoft.com wrote:
 Also, the Stream object lets you pipe the data from to/from Web Workers,
which can be handy in certain scenarios.

What's wrong with just posting a Blob or ArrayBuffer?

--
Glenn Maynard


Re: Streams and Blobs

2013-02-27 Thread Glenn Maynard
On Wed, Feb 27, 2013 at 12:02 AM, Darin Fisher da...@chromium.org wrote:

 I assume that even if the Stream is not done downloading that it should be
 safe to reuse the XHR object that provided the Stream, right?  Hmm, I can
 imagine some implementation complexity arising from saying that a XHR is
 done before the Stream is done.


Out of curiosity, what's the complexity?  Once XHR enters DONE, doesn't
calling open() again pretty much throw away the whole internal state of the
client and start from scratch?


On Wed, Feb 27, 2013 at 12:59 AM, Tillmann Karras tillm...@selfnet.dewrote:

 On 2013-02-27 02:55, Glenn Maynard wrote:

 What are some actual use cases?  I don't think any have been
 mentioned on this thread.


 - I would like to stream realtime TV. Pausing shouldn't be a problem
 because I don't rely on POST requests and I would just buffer up to a
 certain limit.

- Another use case that comes to mind is starting to watch a video file
 before it is fully downloaded.


You don't need XHR or Stream for this.  Just point video @src at the stream.


 - Another one would be downloading only the beginning of a file, e.g. for
 file type identification / thumbnails/ MP3 tags and so on. (How much data
 is needed is probably not known up front and just using increasing Range
 headers would require multiple round trips.)
 - Jonas mentioned incremental rendering of large Word or PDF documents.


These are separate.  We're talking about taking the result of an XHR and
handing it off to a native API like video.  There's a separate discussion
for incremental reads in JavaScript, which doesn't involve Stream at all
(search the thread for clearResponse for my rough proposal).

The use cases I'm asking for are where you want to hand a stream off to a
native API like video, but where you can't arrange it so it's a simple
URL--that is, where you need to make a POST request or set custom headers
in the stream request.  I can't think of any good reason to do this.  For
example, you might need to authenticate with a POST before starting to
stream, but that'd be better done by doing a separate POST, receiving an
authentication token in response, then putting the token in a simple URL to
be used for the actual stream, or in a cookie depending on security needs.
The stream itself shouldn't be POST.

-- 
Glenn Maynard


Re: Streams and Blobs

2013-02-27 Thread Glenn Maynard
On Wed, Feb 27, 2013 at 10:39 AM, Aaron Colwell acolw...@chromium.orgwrote:

  - I would like to stream realtime TV. Pausing shouldn't be a problem
 because I don't rely on POST requests and I would just buffer up to a
 certain limit.

   - Another use case that comes to mind is starting to watch a video
 file before it is fully downloaded.


 You don't need XHR or Stream for this.  Just point video @src at the
 stream.


 In the Media Source Extensions context it is valuable to be able to
 consume the data as it arrives instead of waiting for the whole transfer to
 complete. The normal use case for MSE involves chunks of media several
 seconds long and it is important to be able to process the data as it
 arrives to help minimize startup time and media prefetching.


(This reply doesn't seem related to the text you're quoting.  Tillmann said
he wants to be able to stream TV.  You don't need any of this to do that;
video can do it already.)

Sending data to MSE, or any other API, doesn't mean it has to be done with
XHR.  Simply handing over a URL is much simpler.  Why do you want to go
through XHR in any of these cases?

 On Wed, Feb 27, 2013 at 7:24 AM, Glenn Maynard gl...@zewt.org wrote:

 These are separate.  We're talking about taking the result of an XHR and
 handing it off to a native API like video.  There's a separate discussion
 for incremental reads in JavaScript, which doesn't involve Stream at all
 (search the thread for clearResponse for my rough proposal).


 Why do these need to be thought about differently? It seems to me that
 Stream simply represents a non-seekable stream of bytes. It seems
 convenient to be able to hand this object to MSE, video, or any other
 object native or otherwise that wants to consume such a stream. If
 JavaScript needs access to the bytes then something like the StreamReader
 seems reasonable to me just like FileReader seems reasonable for accessing
 Blob data.


The whole initial point of this thread is that the Streams spec is a lot of
API for streaming to script.  In response, the only argument made for
Stream is for handing streams off to native (video or anything else).  If
that can't be justified with use cases, then we're back where we
started--if the only use cases we have are for streaming to script, we
don't need Stream for that.  All we need to have to support that is one new
method (and maybe another property, depending on web-compatibility).

It seems convenient isn't good enough to justify adding something to the
web, if there's a much simpler, more reliable way to do the same thing.

I don't see why the difference between POST or GET usage matters. The XHR
 is just being used to fetch data. I don't think we should bake any
 assumptions into which methods people use.


The difference, more precisely, is between using XHR to initiate a fetch
and just handing in a URL for the resource.  (POST vs. GET is a mild
oversimplification of that, since POST is one thing you can't do by passing
in a URL.)

There's a huge, fundamental difference between a URL and an XHR-provided
POST.  If you have a simple URL, eg. video src=url, the browser can open,
close and seek the URL in any way it needs to.  The browser can handle
pausing, seeking, and recovering interrupted streams, completely
automatically.  If you have a POST initiated from XHR, the browser can't do
any of that and it all gets pushed onto the developer.  (Even if it's a
GET, it's not clear that the browser could restart it if it comes from XHR.)

On Wed, Feb 27, 2013 at 10:54 AM, Aaron Colwell acolw...@chromium.org
 wrote:

 That is not how I was assuming it would work. I assumed it would keep
 reading  buffer the data just like a normal XHR would do in the other
 modes.


I think this may be a more complicated model that will be harder to
precisely define.  But, I don't think the need for the feature has been
established, so for now I'll focus on that part of the discussion.

 It's not just pausing, it's resuming the stream after the TCP connection
 is closed for any reason, like a network hiccup.  Everyone should want to
 get that right, not just people who want to support pausing.  This is a
 problem for every application using this API, and it seems tricky to get
 right, which in a web API suggests there's something wrong with the API
 itself.  Handling seeking seems even harder.  If people use GET requests,
 and don't interject XHR in at all, the whole category of problems goes away.


 I don't expect XHR to have to deal with pausing. In most cases where the
 video tag would use Stream it would be for a live stream where pausing
 isn't an option.


But again: what cases are those?  Why would you use XHR, create a Stream
and pass the Stream to another API, instead of just giving the API the URL
in the first place?

 Even if it was, since all the video tag has is a non-seekable stream of
 bytes, it would have to either do its own caching or just give up and
 signal an error. It can't make any

Re: Streams and Blobs

2013-02-26 Thread Glenn Maynard
On Tue, Feb 26, 2013 at 4:56 AM, Anne van Kesteren ann...@annevk.nl wrote:

 The advantage the Streams API seems to have over moz-blob is that you

do not need to create a new object to read from each time there's
 fresh data. The disadvantage is that that's only a minor advantage and
 there's a whole lot of new API that comes with it.


I suppose a use case would be making a POST request or a request with
special headers set to access a video stream.  You can createObjectURL on
the resulting Stream and pass that to video.

Did I miss something?

 I'm kinda leaning towards adding incremental Blob and chunked
 ArrayBuffer support and removing the Streams API. I can see use for
 Stream construction going forward to generate a request entity body
 that increases over time, but nobody is there yet.

 (Also, in retrospect, I think we should have made Blob's be able to
 increase in size over time and not have the synchronous size
 getter...)


Yeah, the sync size getter is unfortunate.  I've wondered about taking Blob
and splitting out a base class without the size getter, but it's probably
not worth it now.  (Actually, wait.  That's almost exactly what Stream is.
 Hmm.)

I don't think it's a problem that Blob's size is immutable.  It's fine to
have XHR create and return a new Blob object each time you read .response,
since they'd all share the same underlying storage.

We can get chunked reads without an additional mode.  Just add an
additional method, eg. clearResponse, which empties .response.  This would
work for all modes that support incremental reads.  For Blobs, this would
cause .response to return an empty blob and start filling up from scratch.
 In other words, .response in incremental blob mode returns a slice of the
complete response in the range [start,end), where end is the total number
of bytes read, start is initialized to 0, and clearResponse sets start =
end.

-- 
Glenn Maynard


Re: Streams and Blobs

2013-02-26 Thread Glenn Maynard
On Tue, Feb 26, 2013 at 10:38 AM, Anne van Kesteren ann...@annevk.nlwrote:

  We can get chunked reads without an additional mode.  Just add an

 additional method, eg. clearResponse, which empties .response.  This would
  work for all modes that support incremental reads.  For Blobs, this would
  cause .response to return an empty blob and start filling up from
 scratch.
  In other words, .response in incremental blob mode returns a slice of the
  complete response in the range [start,end), where end is the total
 number of
  bytes read, start is initialized to 0, and clearResponse sets start =
 end.

 Keeping the API closer to responseType/response seems nicer.


I disagree.  That means creating a big matrix of responseTypes for (blob,
arraybuffer, text) * (chunked, incremental), to control what are
really two separate behavioral switches.

This is also easier to use.  If you want to process data 100 KB at a time,
you simply do:

var check_for_data = function()
{
// Return if we have too little data and more data is coming.
if(xhr.response.size  102400  xhr.readyState != xhr.DONE)
return;
var blob = xhr.response;
xhr.clearResponse();

// do work
}

xhr.onprogress = function(e) { check_for_data(); }

With an API that uses a separate responseType and clears the blob chunk
automatically, you'd have to accumulate the data yourself.  Also, you'd
have to worry about double-processing data (knowing precisely when the
.response chunk is replaced to make sure you don't process the same chunk
twice).

(In principle, there are three modes: all at once, which we have today,
incremental and chunked.  We could probably avoid adding any new
responseTypes at all.  If it's web-compatible, just change .response to
return incremental data.  If it isn't, add an .incrementalResponse
property.  This keeps the type of response--blob, text,
ArrayBuffer--orthogonal from whether data is exposed incrementally or not.)

-- 
Glenn Maynard


Re: Streams and Blobs

2013-02-26 Thread Glenn Maynard
On Tue, Feb 26, 2013 at 11:12 AM, Anne van Kesteren ann...@annevk.nlwrote:

 Okay, so we want to keep something like Stream around. Do you need a
 Blob without size kind of object? E.g. that would mean it cannot have
 chunked semantics (the stuff you read is thrown away), which is
 something we probably want for XMLHttpRequest. It seems like these are
 the types we've been discussing:

 * Blob fixed in size
 * Blob that grows over time
 * Blob that grows over time and shrinks from the start on read


For taking an XHR response and handing it off to some native API, the
Stream interface does seem like the right abstraction: it represents a
logical stream, not a block of data like Blob.  The only parts of the
Streams API needed to make this work are the simple Stream interface (which
is nothing but an object with a MIME type) and createObjectURL support for
it.  You don't need StreamReader or StreamBuilder.

You'd want XHR itself to behave a bit differently if it returns a Stream,
though.  It should never enter LOADING, instead finishing as soon as
headers complete, as if XHR hands off the file descriptor to the stream
object as soon as the headers finish.

That said, I'm not fully convinced about the overall picture of Stream:

- What happens if you start a video stream, then the user pauses the video
and goes away?  The browser (or server) will want to shut down the TCP
stream and reopen it again if the user unpauses a day later.  If the stream
comes from an XHR POST, it's not allowed to do that.  Similarly, you have
to deal with restarting the stream after a dropped connection.
- What about seekable streams (eg. streaming large but static videos,
rather than a live feed)?  You can't do it, for the same reason.

If you structure services with the GET, you don't have any of these
problems; the browser can stop, restart and seek the request whenever it
wants; and we don't need any new APIs.  What are the actual use cases for
POST (or other custom XHR-based requests) that are so hard to structure as
a GET (or an initial authenticating POST that replies with a GET URL) to
warrant all this?

-- 
Glenn Maynard


Re: Streams and Blobs

2013-02-26 Thread Glenn Maynard
On Tue, Feb 26, 2013 at 7:16 PM, Darin Fisher da...@chromium.org wrote:

 Interesting idea, but what is the motivation for this change?  Why would
 the XHR (data provider) state machine need to change?


XHR is a consumer, not a provider: it consumes data from the HTTP stream
and returns it in one form or another.  The provider is the HTTP stream
itself.  If XHR continues to run and read data from the HTTP connection
after creating the Stream, that essentially means we have two consumers for
the same provider.

That's confusing.  For example, if nobody is reading from the Stream, you
want to stop reading from the TCP socket so data buffers and the stream
backs up.  If XHR continues to be a consumer of the HTTP stream (as it is
in other modes), then it would keep reading full-speed from the socket even
if the Stream isn't being read.  (That, or it means it ghosts along as
the Stream is read by some other API, which is weird.)  It also means we
have two objects returning things like progress events for the same stream,
which is trickier to get right--you'd need to define the ordering for the
two sets of events, which probably happen in different task sources.  By
getting XHR out of the picture as soon as its work is done, all of this
goes away.

Think of it as if XHR always reads from a Stream object, and all it's doing
in stream mode is stopping after headers and giving you the underlying
stream to do something else with.



 That said, I'm not fully convinced about the overall picture of Stream:

 - What happens if you start a video stream, then the user pauses the
 video and goes away?  The browser (or server) will want to shut down the
 TCP stream and reopen it again if the user unpauses a day later.


 This seems like a problem for the application.  If an error is detected,
 then the application can do what it needs to restart the stream.
  Presumably, the application would be built to only create streams that can
 be restarted if pausing is a mode it wants to support.


It's not just pausing, it's resuming the stream after the TCP connection is
closed for any reason, like a network hiccup.  Everyone should want to get
that right, not just people who want to support pausing.  This is a problem
for every application using this API, and it seems tricky to get right,
which in a web API suggests there's something wrong with the API itself.
Handling seeking seems even harder.  If people use GET requests, and don't
interject XHR in at all, the whole category of problems goes away.

What are some actual use cases?  I don't think any have been mentioned on
this thread.

-- 
Glenn Maynard


Re: [XHR] remove user cancels request

2013-02-25 Thread Glenn Maynard
On Mon, Feb 25, 2013 at 3:37 AM, Anne van Kesteren ann...@annevk.nl wrote:

 Sure, for links (i.e. navigation)... For XMLHttpRequest (fetching)
 however those rarely change as that would make applications very
 confusing to the user. At least, when I still worked at Opera at some
 point the progress bars for fetching after the page had loaded (body
 load fired) were disabled as they were just too confusing.


Some data points:

- Firefox already sends onerror if you hit escape while an XHR is in
progress.  The onerror handler can just start another XHR request, and
pressing escape again will once again onerror that new request.
- In WebKit, if the document load is still in progress, escape cancels both
the document load (eg. images) and any running XHRs.  If this happens,
onabort is sent to the request.  However, this only happens during initial
document load; after that, XHR requests can't be cancelled.  The onabort
handler can also start another XHR, and since the document load is no
longer in progress, this one can't be cancelled.
- IE9 doesn't seem to abort XHR at all.

WebKit's behavior doesn't make sense.

Firefox's behavior seems to match what you're suggesting, and it's what I'd
expect.  Since it doesn't expose any code paths that can't happen
otherwise, it should also result in the least chance of bugs.

IE9's behavior of not cancelling XHR on escape at all seems reasonable, too.

For navigation,

- Firefox also fires onerror if you navigate while an XHR is in progress.
- WebKit fires onabort.
- IE9 doesn't seem to cancel XHR on navigation.  (You can get an XHR onload
after the user has already clicked a link, if the new page hasn't already
begun to load.)

If authors really want to be able to distinguish a user cancellation from a
regular network error, let's stick a flag on onerror.  It's much worse to
have to carefully distinguish abort() from a user abort.  They're
completely different things.

-- 
Glenn Maynard


  1   2   3   4   5   >