Re: [clipboard] Feature detect Clipboard API support?
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]
(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
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
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
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
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]
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
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'})))
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?
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
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?
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
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?
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?
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
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
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
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
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
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
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
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
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
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
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
(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
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...
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
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
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
(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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?)
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
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
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
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?
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
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?
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?
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
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
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
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
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
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
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
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?
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?
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?
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
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.
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
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
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?
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?
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?
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
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
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
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
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
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
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
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?
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
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?
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?
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
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
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
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
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
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
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
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
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