Re: [clipboard] Feature detect Clipboard API support?

2015-02-11 Thread Glenn Maynard
On Wed, Feb 11, 2015 at 12:34 PM, Michaela Merz 
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  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 Tue, Aug 12, 2014 at 9:21 AM, David Bruant  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  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-12 Thread Glenn Maynard
On Mon, Aug 11, 2014 at 6:52 PM, David Bruant  wrote:

>  Le 12/08/2014 00:40, Glenn Maynard a écrit :
>
>  On Sat, Aug 9, 2014 at 9:12 AM, David Bruant  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-11 Thread Glenn Maynard
On Sat, Aug 9, 2014 at 9:12 AM, David Bruant  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 
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,  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  wrote:

> On Mon, Jun 30, 2014 at 10:48 PM, Arun Ranganathan 
> 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 wrote:

> 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 = "hello";
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] 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 
 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  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-20 Thread Glenn Maynard
On Tue, May 20, 2014 at 2:24 PM, Jonas Sicking  wrote:

> Yes, we could demand that that implementations generate unguessable
>
UUIDs. And then define that a page from http://a.com can use  src="blob:http://b.com/uuid";>, but if it then used that element to
> drawImage into a , 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  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] implicitly prevent default event action?

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

> >> 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: [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 wrote:

> 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-19 Thread Glenn Maynard
On Mon, May 19, 2014 at 3:30 AM, Jonas Sicking  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  and 

Re: Blob URL Origin

2014-05-16 Thread Glenn Maynard
On Fri, May 16, 2014 at 9:11 AM, Anne van Kesteren  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 -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  wrote:

> On Thu, May 15, 2014 at 6:52 AM, Anne van Kesteren 
> 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  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  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  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  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
On Tue, Apr 29, 2014 at 8:25 PM, Ted Mielczarek  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: [Gamepad] Liveness of Gamepad objects

2014-04-29 Thread Glenn Maynard
On Tue, Apr 29, 2014 at 6:42 PM, Brandon Jones  wrote:

> On Tue Apr 29 2014 at 4:28:31 PM, Glenn Maynard  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
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  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  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: [request] "Download" Event for HTMLAnchorElement

2014-03-25 Thread Glenn Maynard
On Mon, Mar 24, 2014 at 8:10 PM, Si Robertson wrote:

> 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
(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: [request] "Download" Event for HTMLAnchorElement

2014-03-24 Thread Glenn Maynard
On Mon, Mar 24, 2014 at 2:45 PM, Si Robertson 
 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 wrote:

> 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: On starting WebWorkers with blob: URLs...

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

> On Fri, Mar 14, 2014 at 10:40 PM, Ian Hickson  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 wrote:

> 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 12:19 PM, Florian Bösch  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  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: [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  wrote:

> On Mon, Feb 24, 2014 at 5:18 PM, Glenn Maynard  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 4:17 AM, Florian Bösch  wrote:

> On Mon, Feb 24, 2014 at 1:16 AM, Thibaut Despoulain  > 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: File API: closed Blob objects

2013-12-16 Thread Glenn Maynard
On Mon, Dec 16, 2013 at 10:16 AM, Anne van Kesteren wrote:

> On Mon, Dec 16, 2013 at 4:07 PM, Glenn Maynard  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: File API: closed Blob objects

2013-12-16 Thread Glenn Maynard
On Mon, Dec 16, 2013 at 9:54 AM, Anne van Kesteren  wrote:

> On Mon, Dec 16, 2013 at 3:48 PM, Glenn Maynard  wrote:
> > Also, you can close() a Blob while an async XHR is taking place on it.
>
> Yeah, for that to be clear the model blobs are using needs to be much
> better defined. To make it clear what the order of steps here is.
>
>
> > It also means you can say xhr.open("GET", blobURL); blob.close(); and
> have it work sensibly
>
> You can still have an IO error of sorts so there needs to be an
> underlying model that describes blob read operations upon which the
> blob API is layered. XMLHttpRequest and other consumers can then use
> the underlying model rather than the vague language we have now.
>

What I meant is that it would be good for the above pattern to work, and
not cause an IO error.  For example, you can have a black-box API call that
takes a blob or a blob URL, and happens to start an XHR inside the black
box.  The caller of the API can close the blob (or revoke the blob URL)
after calling into the API without interfering with the XHR that it doesn't
know about.

-- 
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  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: RE : Sync IO APIs in Shared Workers

2013-12-07 Thread Glenn Maynard
On Wed, Dec 4, 2013 at 6:38 PM, Charles Pritchard  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  wrote:

> On Nov 26, 2013 9:17 AM, "Mounir Lamouri"  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 Fri, Nov 22, 2013 at 11:55 AM, Jonas Sicking  wrote:

> On Fri, Nov 22, 2013 at 7:54 AM, Glenn Maynard  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 IO APIs in Shared Workers

2013-11-22 Thread Glenn Maynard
On Thu, Nov 21, 2013 at 8:33 PM, Jonas Sicking  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 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  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
On Sun, Oct 13, 2013 at 8:11 PM, Glenn Maynard  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-13 Thread Glenn Maynard
 worker = createWorker(); // create the above worker
worker.onmessage = function(e)
{
var confirmPort = event.data.port;
confirmPort.onmessage = function(e)
{
var answer = confirm(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-11 Thread Glenn Maynard
On Fri, Oct 11, 2013 at 2:24 PM, pira...@gmail.com wrote:

> 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  src="blob:..."> and providing links to content using .
> 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  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  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 wrote:

> 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  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  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 wrote:

> 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 11:31 AM, Arun Ranganathan  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 wrote:

> 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 wrote:

> 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-09-03 Thread Glenn Maynard
On Tue, Sep 3, 2013 at 9:03 AM, Arun Ranganathan  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 wrote:

> 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-08-29 Thread Glenn Maynard
On Thu, Aug 29, 2013 at 10:51 AM, Anne van Kesteren wrote:

> On Thu, Aug 29, 2013 at 4:46 PM, Glenn Maynard  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: File API: File's name property

2013-08-29 Thread Glenn Maynard
On Thu, Aug 29, 2013 at 10:14 AM, Anne van Kesteren wrote:

> On Thu, Aug 29, 2013 at 4:10 PM, Glenn Maynard  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 9:48 AM, Anne van Kesteren  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: Files on IndexedDB

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

> 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-06-02 Thread Glenn Maynard
On Sun, Jun 2, 2013 at 5:02 PM, 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-05-30 Thread Glenn Maynard
On Thu, May 30, 2013 at 4:24 AM, pira...@gmail.com wrote:

> 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: jar protocol (was: ZIP archive API?)

2013-05-07 Thread Glenn Maynard
On Tue, May 7, 2013 at 9:29 AM, Robin Berjon  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.


>
> and
>
> 
>

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: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-07 Thread Glenn Maynard
On Tue, May 7, 2013 at 4:54 PM, Jonas Sicking  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: Blob URLs | autoRevoke, defaults, and resolutions

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

> On Mon, May 6, 2013 at 11:11 PM, Jonas Sicking  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 Mon, May 6, 2013 at 10:52 PM, Eric U  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  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: ZIP archive API?

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

> On Mon, May 6, 2013 at 5:15 PM, Glenn Maynard  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-06 Thread Glenn Maynard
On Mon, May 6, 2013 at 7:57 PM, Anne van Kesteren  wrote:

> On Mon, May 6, 2013 at 5:45 PM, Jonas Sicking  wrote:
> > On Mon, May 6, 2013 at 4:28 PM, Anne van Kesteren 
> 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 1:11 PM, Eric U  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  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: ZIP archive API?

2013-05-06 Thread Glenn Maynard
On Mon, May 6, 2013 at 6:27 AM, Robin Berjon  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: 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  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-05 Thread Glenn Maynard
On Sun, May 5, 2013 at 7:37 PM, Jonas Sicking  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-01 Thread Glenn Maynard
On Wed, May 1, 2013 at 7:01 PM, Eric U  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: Blob URLs | autoRevoke, defaults, and resolutions

2013-05-01 Thread Glenn Maynard
On Wed, May 1, 2013 at 5:36 PM, Arun Ranganathan  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. ).  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: File API: auto-revoking blob URLs

2013-04-17 Thread Glenn Maynard
On Wed, Apr 17, 2013 at 4:58 AM, Anne van Kesteren wrote:

> 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  wrote:

>   .style.backgroundImage = "url(" + url + ")"
>   .src = url
>   .srcset = "1x" + url + ", 2x " + url2
>   xhr.open("GET", url)
>body { background:url(url) } 
>
> "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  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  synchronously.
>
> That would make  behave differently from e.g. .
> Pretty sure  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  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
>
> .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  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  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 
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  wrote:

> Same question applies if you create an  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  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  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 wrote:

> 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  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
 and not
mysteriously fail a year later when somebody eventually throws a MIME type
parameter into the mix.  Today, all browsers expose text files at
text/plain.  If a browser a year from now decides to call text files with a
UTF-8 BOM "text/plain; charset=UTF-8", it'll break interop.

Additionally, determining a blob's file type seems like the most obvious
use of this property, and making people say "if(blob.type.split(";")[0] ==
'text/plain')" is simply not a good interface.

(I don't know what #3 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  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 7:23 PM, Jonas Sicking  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: Streams and Blobs

2013-03-15 Thread Glenn Maynard
On Fri, Mar 15, 2013 at 5:07 AM, Jonas Sicking  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: 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 wrote:

> 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: 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. wrote:

> 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 
 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 1:54 PM, Alex Russell wrote:

> 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: Streams and Blobs

2013-03-11 Thread Glenn Maynard
On Mon, Mar 11, 2013 at 3:03 AM, Jonas Sicking  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
d (or one of the other redundant events fired at
that time), which this approach follows.

> With the runs-for-the-duration-of-the-stream model, when is the .response
> > available?
>
> Ideally as soon as .send() is called. If that causes problem then
> maybe as soon as we enter readystate 3.
>

You need to know the MIME type to create a Stream, so you can't create it
until you've received headers.  This means that you'd have to wait for a
different condition to know when the response is ready to be used than just
about every other use of XHR.

-- 
Glenn Maynard


Re: Persistent Storage vs. Database

2013-03-08 Thread Glenn Maynard
On Fri, Mar 8, 2013 at 12:36 AM, Kyle Huey  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
wrote:

> 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: File API: Blob.type

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

> On Thu, Mar 7, 2013 at 6:35 PM, Arun Ranganathan
>  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 

Re: Streams and Blobs

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

> On Thu, Mar 7, 2013 at 4:42 PM, Glenn Maynard  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: Streams and Blobs

2013-03-07 Thread Glenn Maynard
 you only need to do simple
fetches (a GET, with no custom headers and so on), then you don't need any
of this; all you need is to hand the URL to the API, as with .
That's simple and robust: 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-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 
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  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: 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 (イアンフェッティ) wrote:

> 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-06 Thread Glenn Maynard
On Wed, Mar 6, 2013 at 8:29 AM, Anne van Kesteren  wrote:

> On Wed, Mar 6, 2013 at 2:21 PM, Glenn Maynard  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  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: 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 10:18 AM, Alex Russell wrote:

> So which part do you disagree with? That events are a bad model for a
> one-time action? Or that it's not clear what the expected contract is?
> Going by what you've written below, I have to assume the latter, so I'll
> just say this: try sitting a non-webdev down with IDB or any other DOM API
> that works this way and try to get them to figure it out from code samples.
> Yes, yes, being a webdev means knowing the platform idioms, but if we can
> agree they're confusing and difficult, we can start to do something about
> it. And in any case, you haven't refuted the former; events are simply a
> bad model here.
>

I disagree that events are bad for one-time actions, and I disagree DOM
events are confusing or difficult.

There's currently no other way to allow an API to be synchronous in workers
>> but only async in the UI thread.
>>
>
> Of course not...but what does that have to do with the price of fish? The
> core question is what's motivating a sync API here in the first place.
>

One of the primary reasons Web Workers exist is to allow writing linear,
synchronous code, because it's often inherently more convenient than
asynchronous code.  That requires synchronous APIs, so asynchronous APIs
typically gain a synchronous version when exposed to workers.  This isn't
the only way to go, and complex APIs like this may warrant giving the "sync
API for workers" thing another go, but it's the pattern today.

 I won't be responding to the rest of your message.
>

(FYI, if you're not replying to something, you don't have to say you're not
replying to it.  Just snip the quotes.)

On Wed, Mar 6, 2013 at 10:51 AM, Jarred Nicholls  wrote:

> I'm not understanding how this refutes the fact that single-fired events
> is an odd model for the job.  Sure it may be consistent, but it's
> consistently bad.  There are plenty of criteria for judging an API, one of
> which is consistency amongst the rest of the platform idioms.  But it
> should be no wonder that solid API developers come along and create
> comprehensible wrappers around the platform.
>

It's up to people claiming that it doesn't work well to demonstrate it; the
discussion started at "since DOM Events are bad for this...", assuming
everyone will automatically agree and skipping the step of actually arguing
that they're bad.  I find events to be simple and straightforward, so it
seems like a strange assumption to me.

I think this would be very desirable on all fronts to avoid duplication of
> interfaces; maybe something like signal events on which a caller can wait:
>
> var signal = someAsyncAction(),
>   result = signal.wait();
>

The discussion starts here, if you want to revive it (but it's fairly long,
with a few false starts, if I remember correctly):
http://lists.w3.org/Archives/Public/public-webapps/2012JulSep/0629.html

-- 
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  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 3:22 AM, Anne van Kesteren  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: The need to re-subscribe to requestAnimationFrame

2013-03-02 Thread Glenn Maynard
On Sat, Mar 2, 2013 at 5:03 AM, David Bruant  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  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 10:39 AM, Aaron Colwell wrote:

>  - 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;
 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  wrote:
>
>> These are separate.  We're talking about taking the result of an XHR and
>> handing it off to a native API like .  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. , 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 
 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 wo

Re: Streams and Blobs

2013-02-27 Thread Glenn Maynard
On Wed, Feb 27, 2013 at 12:02 AM, Darin Fisher  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 wrote:

> 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 .  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 , 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-26 Thread Glenn Maynard
On Tue, Feb 26, 2013 at 7:16 PM, Darin Fisher  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: Streams and Blobs

2013-02-26 Thread Glenn Maynard
On Tue, Feb 26, 2013 at 11:12 AM, Anne van Kesteren wrote:

> 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 10:38 AM, Anne van Kesteren wrote:

> > 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


  1   2   3   4   5   >