Re: New FileAPI Draft | was Re: FileAPI feedback
Hi, the spec lists a use case about a web app that needs to send file(s) to the server programmatically. I happen to think lately about an E-mail app that can send attachments. FileData and its splice() method are useful here. I assume the XHR2 spec would get XHR.send(FileData) method. XHR2 provides progress events. However, it seems some additional functionality is needed. For example, when sending e-mail with attachments, it may be good to 'release' the UI as soon as possible and have some sort of Outbox model when outgoing email and attachments are sent in the background, while user can close the page or navigate away, in which case the send could be resuming later when the app's page is open again - but it would be really bad to loose the unsent email. This is what comes to mind: - it'll need some way to save the File object to the Database field or a localStore value, so it can be stored there till uploaded by the worker or another page (I think this was discussed before, perhaps it's on the way into corresponding specs?) Of course, we don't want to write the content of the file into the Database, only opaquely roundtrip the 'file representing token'. - it'd be good to have the ability to 'snapshot' files. During the send/upload time the original files that user selected may 'disappear' from the locations captured. For example, they were photos on a flash card that got removed. It would be useful to (optionally) be able to make a copy of the file to some temporary location. This can be an async operation that comes back with a callback that gives a 'temp copy' File object (File.makeTemporaryCopy(callback)). Some limit on disk space could be set. They also will need to be removed at some point. Dmitry On Tue, Aug 4, 2009 at 6:55 PM, Arun Ranganathan a...@mozilla.com wrote: I have updated the draft of the File API, and welcome more review. Note that it is no longer called FileUpload since this term has become misleading. In particular, here are some of the issues addressed (and some not): Any reason you're using an XHTML file to edit this? Also, the indentation is awkward. http://dev.w3.org/2006/webapi/FileUpload/publish/FileAPI.html For what concerns the file as URI feature: What about reusing the cid scheme? After having looked at the RFCs for cid and mid schemes, I don't think the cid scheme is appropriate for our use case, since it is tightly tied to the notion of message body, which isn't necessarily true in all cases of file data. I have a proposal in this draft for the file as URL proposal (originally broached in IRC, but which has seen some discussion on the listserv). I'd welcome feedback on it, especially the processing model for these URLs. A simple ABNF using UUIDs as unique identifiers has been proposed here. File API should probably have some way to get only parts of the file. This has been added as a new method. Feedback welcome! [The existing design] limits the number of callbacks to one. That one callback can only be added in the invocation to read. Instead, allow multiple callbacks to be added with the DOM Events API While this was an intriguing suggestion (and seemed like it was a more powerful programming model), I wasn't convinced that it was needed for the File API. It did lead to a more complicated model that didn't seem to fully justify the power. However, I did study subsequent use cases, and eliminated error callbacks, allowing callbacks themselves to handle error conditions. Also, I introduced a cancelReads( ) which can be used with timeouts. I'm not convinced that an event model is necessary for asynchronous data accessors on file data; DOM events aren't useful in all cases. It's also worth nothing that the File API in general may be subject to further iteration in the Device API WG, which may introduce notions of write APIs. Note of course that whatever API supports ranges needs to ensure that the data isn't forcibly coerced into valid Unicode, as the underlying data for an image can include all sorts of patterns which aren't valid UTF8/16/ It was clear that getAsText was insufficient, so more asynchronous data accessor methods have been added. I think FileDialog is a bad idea. We already have UI for selecting multiple files: input type=file multiple. This has now been eliminated from this draft. I'm keen to move towards fpwd, and it seemed that FileDialog was needlessly controversial. I think it still is useful, and think it could be added later. -- A*
File API: Blob and underlying file changes.
Hi, Does the Blob, which is obtained as File (so it refers to an actual file on disk) track the changes in the underlying file and 'mutates', or does it represent the 'snapshot' of the file, or does it become 'invalid'? Today, if a user selects a file using input type=file, and then the file on the disk changes before the 'submit' is clicked, the form will submit the latest version of the file. This may be a surprisingly popular use case, when user submits a file via form and wants to do 'last moment' changes in the file, after partial pre-populating the form. It works 'intuitively' today. Now, if the page decides to use XHR to upload the file, I think var file = myInputElement.files[0]; var xhr = ... xhr.send(file); should also send the version of the file that exists at the moment of xhr.send(file), not when user picked the file (for consistency with form action). Assuming this is desired behavior, what should the following do: var file = myInputElement.files[0]; var blob = file.slice(0, file.size); // ... now file on the disk changes ... xhr.send(blob); Will it: - send the new version of the whole file (and update blob.size?) - send captured number of bytes from the new version of the file (perhaps truncated since file may be shorter now) - send original bytes from the previous version of the file that existed when Blob was created (sort of 'copy on write') - throw exception ? Thanks, Dmitry
Re: File API: Blob and underlying file changes.
Adding reply from Jonas Sicking from anther list (which I used first by mistake :( ) Technically, you should send this email to the webapps mailing list, since that is where this spec is being developed. That said, this is a really hard problem, and one that is hard to test. One thing that we decided when we did security review on this stuff at mozilla is that if a File object is ever passed cross origin using postMessage, then the File object that the other origin has should not work if the file is changed on disc. For some definition of not work. On Fri, Jan 8, 2010 at 2:21 PM, Dmitry Titov dim...@chromium.org wrote: Hi, Does the Blob, which is obtained as File (so it refers to an actual file on disk) track the changes in the underlying file and 'mutates', or does it represent the 'snapshot' of the file, or does it become 'invalid'? Today, if a user selects a file using input type=file, and then the file on the disk changes before the 'submit' is clicked, the form will submit the latest version of the file. This may be a surprisingly popular use case, when user submits a file via form and wants to do 'last moment' changes in the file, after partial pre-populating the form. It works 'intuitively' today. Now, if the page decides to use XHR to upload the file, I think var file = myInputElement.files[0]; var xhr = ... xhr.send(file); should also send the version of the file that exists at the moment of xhr.send(file), not when user picked the file (for consistency with form action). Assuming this is desired behavior, what should the following do: var file = myInputElement.files[0]; var blob = file.slice(0, file.size); // ... now file on the disk changes ... xhr.send(blob); Will it: - send the new version of the whole file (and update blob.size?) - send captured number of bytes from the new version of the file (perhaps truncated since file may be shorter now) - send original bytes from the previous version of the file that existed when Blob was created (sort of 'copy on write') - throw exception ? Thanks, Dmitry
Re: File API: Blob and underlying file changes.
Atomic read is obviously a nice thing - it would be hard to program against API that behaves as unpredictably as a single read operation that reads half of old content and half of new content. At the same note, it would be likely very hard to program against Blob objects if they could change underneath unpredictably. Imagine that we need to build an uploader that cuts a big file in multiple pieces and sends those pieces to the servers so they will be stitched together later. If during this operation the underlying file changes and this changes all the pieces that Blobs refer to (due to clamping and just silent change of content), all the slicing/stitching assumptions are invalid and it's hard to even notice since blobs are simply 'clamped' silently. Some degree of mess is possible then. Another use case could be a JPEG image processor that uses slice() to cut the headers from the image file and then uses info from the headers to cut further JFIF fields from the file (reading EXIF and populating local database of images for example). Changing the file in the middle of that is bad. It seems the typical use cases that will need Blob.slice() functionality form 'units of work' where Blob.slice() is used with likely assumption that underlying data is stable and does not change silently. Such a 'unit of work' should fail as a whole if underlying file changes. One way to achieve that is to reliably fail operations with 'derived' Blobs and even perhaps have a 'isValid' property on it. 'Derived' Blobs are those obtained via slice(), as opposite to 'original' Blobs that are also File. One disadvantage of this approach is that it implies that the same Blob has 2 possible behaviors - when it is obtained via Blob.slice() (or other methods) vs is a File. It all could be a bit cleaner if File did not derive from Blob, but instead had getAsBlob() method - then it would be possible to say that Blobs are always immutable but may become 'invalid' over time if underlying data changes. The FileReader can then be just a BlobReader and have cleaner semantics. If that was the case, then xhr.send(file) would capture the state of file at the moment of sending, while xhr.send(blob) would fail with exception if the blob is 'invalid' at the moment of send() operation. This would keep compatibility with current behavior and avoid duplicity of Blob behavior. Quite a change to the spec though... Dmitry On Wed, Jan 13, 2010 at 2:38 AM, Jonas Sicking jo...@sicking.cc wrote: On Tue, Jan 12, 2010 at 5:28 PM, Chris Prince cpri...@google.com wrote: For the record, I'd like to make the read atomic, such that you can never get half a file before a change, and half after. But it likely depends on what OSs can enforce here. I think *enforcing* atomicity is difficult across all OSes. But implementations can get nearly the same effect by checking the file's last modification time at the start + end of the API call. If it has changed, the read operation can throw an exception. I'm talking about during the actual read. I.e. not related to the lifetime of the File object, just related to the time between the first 'progress' event, and the 'loadend' event. If the file changes during this time there is no way to fake atomicity since the partial file has already been returned. / Jonas
Re: File API: Blob and underlying file changes.
So it seems there is 2 ideas on how to handle the underlying file changes in case of File and Blob objects, nicely captured by Arun above: 1. Keep all Blobs 'mutating', following the underlying file change. In particular, it means that Blob.size and similar properties may change from query to query, reflecting the current file state. In case the Blob was sliced and corresponding portion of the file does not exist anymore, it would be clamped, potentially to 0, as currently specified. Read operations would simply read the clamped portion. That would provide similar behavior of all Blobs regardless if they are the Files or obtained via slice(). It also has a slight disadvantage that every access to Blob.size or Blob.slice() will incur synchronous file I/O. Note that current File.fileSize is already implemented like that in FF and WebKit and uses sync file I/O. 2. Treat Blobs that are Files and Blobs that are produced by slice() as different blobs, semantically. While former ones would 'mutate' with the file on the disk (to keep compat with form submission), the later would simply 'inherit' the file information and never do sync IO. Instead, they would fail later during async read operations. This has disadvantage of Blob behaving differently in some cases, making it hard for web developers to produce correct code. The synchronous file IO would be reduced but not completely eliminated, because the Blobs that are Files would continue to 'sync' with the underlying file stats during sync JS calls. One benefit is that it allows detection of file content change, via checks of modification time captured when the first slice() operation is performed and verified during async read operations, which provides a way to implement reliable file operations in face of changing files, if the developer wants to spent an effort to do so. It seems folks on the thread do not like the duplicity of Blobs (hard to program and debug), and there is also a desire to avoid synchronous file IO. It seems the spec today leans more to the #1. The only problem with it is that it's hard to implement some scenarios, like a big file upload in chunks - in case the file changes, the result of upload may actually be a mix of new and old file contents and there is no way to check... Perhaps we can expose File.modificationTime? It still dos not get rid of sync I/O... Dmitry On Fri, Jan 15, 2010 at 12:10 PM, Dmitry Titov dim...@chromium.org wrote: On Fri, Jan 15, 2010 at 11:50 AM, Jonas Sicking jo...@sicking.cc wrote: This doesn't address the problem that authors are unlikely to even attempt to deal with this situation, given how rare it is. And even less likely to deal with it successfully given how hard the situation is reproduce while testing. I don't know how rare the case is. It might become less rare if there is an uploader of big movie files and it's easy to overwrite the big movie file by hitting 'save' button in movie editor while it is still uploading... Perhaps such uploader can use other means to detect the file change though... It would be nice to spell out *some* behavior though, or we can end up with some incompatible implementations. Speaking about Blob.slice(), what is recommended behavior of resultant Blobs on the underlying file change? / Jonas
Re: File API: Blob and underlying file changes.
On Wed, Jan 20, 2010 at 2:30 PM, Eric Uhrhane er...@google.com wrote: I think it could. Here's a third option: Make all blobs, file-based or not, just as async as the blobs in option 2. They never do sync IO, but could potentially fail future read operations if their metadata is out of date [e.g. reading beyond EOF]. However, expose the modification time on File via an async method and allow the user to pass it in to a read call to enforce fail if changed since this time. This keeps all file accesses async, but still allows for chunked uploads without mixing files accidentally. If we allow users to refresh the modification time asynchronously, it also allows for adding a file to a form, changing the file on disk, and then uploading the new file. The user would look up the mod time when starting the upload, rather than when the file's selected. It would be great to avoid sync file I/O on calls like Blob.size. They would simply return cached value. Actual mismatch would be detected during actual read operation. However then I'm not sure how to keep File derived from Blob, since: 1) Currently, in FF and WebKit File.fileSize is a sync I/O that returns current file size. The current spec says File is derived from Blob and Blob has Blob.size property that is likely going to co-exist with File.fileSize for a while, for compat reasons. It's weird for file.size and file.fileSize to return different things. 2) Currently, xhr.send(file) does not fail and sends the version of the file that exists somewhere around xhr.send(file) call was issued. Since File is also a Blob, xhr.send(blob) would behave the same which means if we want to preserve this behavior the Blob can not fail async read operation if file has changed. There is a contradiction here. One way to resolve it would be to break File is Blob and to be able to capture the File as Blob by having file.getAsBlob(). The latter would make a snapshot of the state of the file, to be able to fail subsequent async read operations if the file has been changed. I've asked a few people around in a non-scientific poll and it seems developers expect Blob to be a 'snapshot', reflecting the state of the file (or Canvas if we get Canvas.getBlob(...)) at the moment of Blob creation. Since it's obviously bad to actually copy data, it seems acceptable to capture enough information (like mod time) so the read operations later can fail if underlying storage has been changed. It feels really strange if reading the Blob can yield some data from one version of a file (or Canvas) mixed with some data from newer version, without any indication that this is happening. All that means there is an option 3: 3. Treat all Blobs as 'snapshots' that refer to the range of underlying data at the moment of creation of the Blob. Blobs produced further by Blob.slice() operation inherit the captured state w/o actually verifying it against 'live' underlying objects like files. All Blobs can be 'read' (or 'sent') via operations that can fail if the underlying content has changed. Optionally, expose snapshotTime property and perhaps read if not changed since parameter to read operations. Do not derive File from Blob, rather have File.getAsBlob() that produces a Blob which is a snapshot of the file at the moment of call. The advantage here is that it removes need for sync operations from Blob and provides mechanism to ensure the changing underlying storage is detectable. The disadvantage is a bit more complexity and bigger change to File spec.
Re: File API: Blob and underlying file changes.
I think the 'snapshotting' discussed above does not imply the actual copy of data, sync or async. The proposal seems to be to 'snapshot' enough information (in case of file on a disk - the modification time is enogh) so that later read operations can fail reliably if the Blob is out of sync with underlying storage. Making copies of large video files will probably never be a feasible option, for size/time issues and for potentially quite complicated lifetime of such copies... We might provide a separate API for file manipulation that can be used to make temporary copies of files in cases where it is a good idea, and that could be used in conjunction with Blob API perhaps, but it seems to be a separate functionality. It is also interesting to think of Blobs backed by some other objects, Canvas for example. Perhaps 'snapshotting' is not an ideal name, but I think discussion above means it as capture the state of the underlying object so the data can be read in the future but w/o a guarantee that the read operation will actually succeed - since there can not be a guarantee that underlying object is still there. On Thu, Jan 21, 2010 at 12:49 PM, Jonas Sicking jo...@sicking.cc wrote: One thing to remember here is that if we require snapshotting, that will mean paying potentially very high costs every time the snapshotting operation is used. Potetially copying hundreds of megabytes of data (think video). But if we don't require snapshotting, things will only break if the user takes the action to modify a file after giving the page access to it. Also, in general snapshotting is something that UAs can experiment with without requiring changes to the spec. Even though File.slice is a synchronous function, the UA can implement snapshotting without using synchronous IO. The UA could simply do a asynchronous file copy in the background. If any read operations are performed on the slice those could simply be stalled until the copy is finished since reads are always asynchronous. / Jonas On Thu, Jan 21, 2010 at 11:22 AM, Eric Uhrhane er...@google.com wrote: On Thu, Jan 21, 2010 at 11:15 AM, Jian Li jia...@chromium.org wrote: Treating blobs as snapshots sounds like a reasonable approach and it will make the life of the chunked upload and other scenarios easier. Now the problem is: how do we get the blob (snapshot) out of the file? 1) We can still keep the current relationship between File and Blob. When we slice a file by calling File.slice, a new blob that captures the current file size and modification time is returned. The following Blob operations, like slice, will simply inherit the cached size and modification time. When we access the underlying file data in XHR.send() or FileReader, the modification time will be verified and an exception could be thrown. This would require File.slice to do synchronous file IO, whereas Blob.slice doesn't do that. 2) We can remove the inheritance of Blob from File and introduce File.getAsBlob() as dimich suggested. This seems to be more elegant. However, it requires changing the File API spec a lot. On Wed, Jan 20, 2010 at 3:44 PM, Eric Uhrhane er...@google.com wrote: On Wed, Jan 20, 2010 at 3:23 PM, Dmitry Titov dim...@chromium.org wrote: On Wed, Jan 20, 2010 at 2:30 PM, Eric Uhrhane er...@google.com wrote: I think it could. Here's a third option: Make all blobs, file-based or not, just as async as the blobs in option 2. They never do sync IO, but could potentially fail future read operations if their metadata is out of date [e.g. reading beyond EOF]. However, expose the modification time on File via an async method and allow the user to pass it in to a read call to enforce fail if changed since this time. This keeps all file accesses async, but still allows for chunked uploads without mixing files accidentally. If we allow users to refresh the modification time asynchronously, it also allows for adding a file to a form, changing the file on disk, and then uploading the new file. The user would look up the mod time when starting the upload, rather than when the file's selected. It would be great to avoid sync file I/O on calls like Blob.size. They would simply return cached value. Actual mismatch would be detected during actual read operation. However then I'm not sure how to keep File derived from Blob, since: 1) Currently, in FF and WebKit File.fileSize is a sync I/O that returns current file size. The current spec says File is derived from Blob and Blob has Blob.size property that is likely going to co-exist with File.fileSize for a while, for compat reasons. It's weird for file.size and file.fileSize to return different things. True, but we'd probably want to deprecate file.fileSize anyway and then get rid of it, since it's synchronous. 2) Currently, xhr.send(file) does not fail and sends
Re: File API: Blob and underlying file changes.
Going a bit back to current spec and changing underlying files - here is an update on our thinking (and current implementation plan). We played with File/Blob ideas a little more and talked with some of our app developers. In regard to a problem of changing file, most folks feel the Blob is best to be though of as a 'snapshot of a byte range' with a delayed promise to deliver the actual bytes in that range from the underlying data storage. It is a 'delayed promise' because all the actual 'reading' methods are async. Basically, in terms of implementation, the Blob is not a 'container of bytes' but rather a 'reference' to the byte range. As such, the async read operations later may fail, for many reasons - the file can be deleted, renamed, modified, etc. It seems developers sometimes want to be oblivious to those problems, but in other scenarios they want to process them. Basically, it's app-specific choice. It appears that the following implementation goes along with the current edition of the spec but also provides the ability to detect the file change: 1. File derives from Blob, so there is a File.size that performs synchronous file I/O. Not ideal, but easy to use and compatible with current forms upload. 2. File.slice() also does a synchronous IO and captures the current size and modification time of the underlying file - and caches it in the resulting Blob. 3. Subsequent Blob.slice() and Blob.size calls do not do any file IO, but merely operate on cached values. So the only Blob methods that do sync IO are those on the File object. Subsequent slicing operates on the file information captured from File and propagate it to derived Blobs. 4. In xhr.send() and FileReader, if the UA discovers that the underlying file is changed, it behaves just like when other file errors are discovered - returning 'error' progress event and setting FileReader.error attribute for example. We might need another FileError code for that if existing ones do not feel adequate. This way, the folks who don't care about changing files could simply ignore the error results - because they likely do not worry about other errors as well (such as NOT_FOUND_ERR). At the same time, folks that worry about such things, could simply process the errors already specified. It also doesn't add new exceptions to the picture so no special code is needed in simple cases. One obvious difficulty here is the synchronous file IO on File.size and File.slice(). Trying to eliminate it requires some complexity in API that is not obviously better. It either leads to some strange APIs like a getSize() with a callback that delivers the size, or/and breaks behavior of currently implemented File (and most developer's expectations). In any case, an attempt to completely avoid sync IO and preserve correctness seems to be calling for a way more involved API. Considering that most uploaders which slice the file and send it in pieces will likely do it in a worker thread, sync IO in these places perhaps is a lesser evil then complicated (or dual) API... Thanks, Dmitry On Wed, Jan 27, 2010 at 4:40 AM, Juan Lanus juan.la...@gmail.com wrote: On Wed, Jan 27, 2010 at 01:16, Robert O'Callahan rob...@ocallahan.org wrote: On Wed, Jan 27, 2010 at 5:38 AM, Juan Lanus juan.la...@gmail.com wrote: Quite right Bob. But still the lock is the way to go. At least as of today. HTML5 might be mainstream for the next 10 years, starting rather soon. In the meanwhile OSs will also evolve, in a way that we can't tell now. But if there are common issues, like this one, somebody will come up with a smart solution maybe soon. For example feeding an image of the file as of the instant it was opened (like relational databases do to provide stable queries) by keeping a temporary map to the original disk segments that comprised the file before it was changed. For example Apple is encouraging advisory locks http://developer.apple.com/mac/library/technotes/tn/tn2037.html#OSSolutions asking developers to design in an environment-aware mood. In my experience, almost no code uses advisory locking unless it is being explicitly designed for some kind of concurrent usage, i.e., Apple's advice is not being followed. If that's not going to suddenly change --- and I see no evidence it will --- then asking the UA to apply a mandatory lock is asking the UA to do something impossible, which is generally not a good idea. Rob Right, not talking about locks any more because it would be telling HOW the UA should do it, and what is best for the UA developers is to be told WHAT to do. Not writing a tutorial but a specification. Let the developer find out how to do it, this year, and with the tools that will be available by 2020. Now, out of the locks subject, what I want to be sure of is that the specification does not specify the mutating blob, the origin of this thread. -- Juan He was pierced for our transgressions, he was crushed
Re: Notifications
I can't help but think the Growl issue is way overblown. I am the user who uses Growl and also a GoogleTalkLabsEdition for Mac that pop ups nice notifications about upcoming meetings, email and chat. Growl is connected to IRC and something else (don't even remember). They both use top-right corner of the screen to pop up their balloons and co-exist just fine. I don't remember having them ever overlap (or that being a problem). And snooze on meeting popups is great. As for less-capable devices like phones, a few years ago even having a real HTML displayed on them was out of the question. There are still successful companies out there that provide a service of translating any given HTML page into dumbed-down version for a particular cellphone model - for a fee per-translation. Sites that are serious about mobile internet on wide variety of currently-deployed devices often use this stuff to serve pages, it's easier then to build up expertise on all the variants of crippled 'browsers' out there. The progress in this field in a last few years is phenomenal and fast. It wouldn't be surprising if 'regular' HTML notifications were totally possible on those devices by the time the spec and implementations gain some maturity. There is no reason why user of a cell phone can not have a nice meeting reminder with a snooze button, or a chat invite with 'reply now', without the need for a native app. Dmitry On Thu, Feb 11, 2010 at 6:07 AM, Jeremy Orlow jor...@chromium.org wrote: On Thu, Feb 11, 2010 at 7:24 AM, Jonas Sicking jo...@sicking.cc wrote: On Wed, Feb 10, 2010 at 6:29 PM, Drew Wilson atwil...@google.com wrote: On Wed, Feb 10, 2010 at 5:49 PM, Jonas Sicking jo...@sicking.cc wrote: And I think the answer is yes. Any time someone talks about an optional web feature I get nervous. Can you give any examples of successful optional web features that exist today? I'd suggest Javascript and Images, but you've rejected them because you don't think they are examples of successful optional features (meaning that browsers that don't support them are not equally compatible with all web content) - and yet most browsers do support turning them off so there must be some value for a subset of users. Have you ever tried to browse the web with javascript or images turned off? It's not an experience most users would say is useful. I think there are some potentially conflicting goals for any of the HTML APIs: 1) Providing a single lowest-common-denominator API that we can support on every single platform to provide the maximum amount of compatibility. For notifications, pretty much every capable platform can display an icon and a single line of text, so if we wanted to be pedantic we could make that our API, but the currently proposed icon + header + body text is probably more reasonable. 2) Providing an API that is flexible enough to take advantage of the capabilities of more advanced platforms. 3) Future proofing the API (as capabilities of platforms grow, the API can continue to support them) I disagree with 2 and 3 being goals. Taking advantage of platform capabilities isn't a goal in and of itself, it's just a mean. Providing a better user experience is the goal IMHO. If users that want to use Growl can't get their browser notifications through growl because the browser was forced to use some other mechanism to implement HTML notifications, then we haven't improved that users experience. Even worse, if they don't get *any* notifications because the website didn't provide a non-html equivalent, then we certainly haven't helped that user. As has been brought up repeatedly, growl and the other notification engines are used by a SMALL FRACTION of all web users. I suspect a fraction of a percent. Why are we bending over backwards to make this system work on those platforms? Are there other examples where we've dumbed down an API to the least common denominator for a small fraction of users? Especially when there's no technical reason why these providers could not be made more advanced (for example, embed webkit to display fully functional notifications)? I really think this is a silly rathole that we've gotten ourselves into here. I'm sure that we can come up with a technical solution that gracefully degrades for those users who want html notifications to integrate with growl/etc but provides a robust experience for the rest of users. J
Re: FormData questions
On Fri, Feb 12, 2010 at 5:32 PM, Jonas Sicking jo...@sicking.cc wrote: Hi WebApps fans! Working on implementing FormData and ran into a couple of questions. First of all, I assume that it is intended that a FromData object can be submitted several times. I.e. that the following code is ok: fd = new FormData; fd.append(name1, foo); xhr1 = new XMLHttpRequest; xhr1.open(...); xhr1.send(fd); fd.append(name2, bar); xhr2 = new XMLHttpRequest; xhr2.open(...); xhr2.send(fd); where the first XHR will send 1 name/value pair, and the second XHR will send 2. I do think this should be allowed, but I wanted to make sure others agreed. What can be a reason to disallow this? FormData is just a collection of data objects. So assuming those XHR objects are sync, the code should work as you described. Interesting question though - what happens if XHR is async and the content of FormData changes while async operation is in progress. By analogy with scenario when underlying file of Blob object changes while async reading operation is in progress, would it be reasonable to fail the send and return 'error' ProgressEvent? Second, what encoding should be used when submitting a FromData object? A few options are: * Always use UTF-8 * Allow a mimetype to be set on the FormData object, using a property or constructor argument * Use the charset mime parameter specified on the content-type header set using xhr.setRequestHeader Having a way to specify encoding could be only useful for writing client code against legacy site that takes charset-encoded form data and ignores the charset parameter of content-type header of the request. That seems rare these days. It would be way simpler to only deal with UTF-8, imo. I think the last one would be a pain for authors and for implementors. Lastly, there is a bug in the spec where it says that the mimetype should be multipart/form-data. It needs to be multipart/form-data; boundary= plus the boundary used while encoding. This also brings up the question what to do if a Content-Type header has already been set. Should a boundary mime parameter be added, or is the server side simply out of luck and won't get to know what the boundary is? / Jonas
Re: FormData questions
On Sat, Feb 13, 2010 at 6:44 PM, Jonas Sicking jo...@sicking.cc wrote: On Sat, Feb 13, 2010 at 6:02 PM, Dmitry Titov dim...@chromium.org wrote: On Fri, Feb 12, 2010 at 5:32 PM, Jonas Sicking jo...@sicking.cc wrote: Hi WebApps fans! Working on implementing FormData and ran into a couple of questions. First of all, I assume that it is intended that a FromData object can be submitted several times. I.e. that the following code is ok: fd = new FormData; fd.append(name1, foo); xhr1 = new XMLHttpRequest; xhr1.open(...); xhr1.send(fd); fd.append(name2, bar); xhr2 = new XMLHttpRequest; xhr2.open(...); xhr2.send(fd); where the first XHR will send 1 name/value pair, and the second XHR will send 2. I do think this should be allowed, but I wanted to make sure others agreed. What can be a reason to disallow this? FormData is just a collection of data objects. So assuming those XHR objects are sync, the code should work as you described. It complicates implementation a tiny amount, but IMHO not enough to disallow it. Interesting question though - what happens if XHR is async and the content of FormData changes while async operation is in progress. By analogy with scenario when underlying file of Blob object changes while async reading operation is in progress, would it be reasonable to fail the send and return 'error' ProgressEvent? I don't think raising an 'error' event should be correct, no. In my example above I think the two requests should succeed successfully, and the first one should submit one name/value pairs, and the second should submit two. Does it mean that implementation should basically produce actual form data synchronously (do a deep copy) at the moment of xhr.send() even if the xhr is asynchronous? In case FormData includes Blobs backed by files on the disk it may be prohibitive. Second, what encoding should be used when submitting a FromData object? A few options are: * Always use UTF-8 * Allow a mimetype to be set on the FormData object, using a property or constructor argument * Use the charset mime parameter specified on the content-type header set using xhr.setRequestHeader Having a way to specify encoding could be only useful for writing client code against legacy site that takes charset-encoded form data and ignores the charset parameter of content-type header of the request. That seems rare these days. It would be way simpler to only deal with UTF-8, imo. Does any browser include a charset parameter for multipart/form-data submissions? Firefox does not and last we added it it broke a bunch of sites IIRC. That was a while ago though. / Jonas
Re: Notifications
On Fri, Feb 12, 2010 at 5:06 AM, Henri Sivonen hsivo...@iki.fi wrote: On Feb 10, 2010, at 20:35, John Gregg wrote: I agree that this is a good distinction, but I think even considering ambient notifications there is a question of how much interaction should be supported. NotifyOSD, for example, does not allow the user to take any action in response to a notification. Being able to acknowledge an ambient notification could be an optional feature that isn't supported on Ubuntu as long as NotifyOSD doesn't support acknowledging notifications. (If it's a problem to make acknowledgement optional, I think making HTML notification optional is going to be a bigger problem...) FWIW, Microsoft explicitly says notifications must be ignorable and don't persist. Notifications aren't modal and don't require user interaction, so users can freely ignore them. In Windows Vista® and later, notifications are displayed for a fixed duration of 9 seconds. http://msdn.microsoft.com/en-us/library/aa511497.aspx As such, it's always unsafe to design UI in a way that expects the users to be able to acknowledge a given notification. FWIW, the mentioned document is full of examples of Notifications that have text like Click here to ... on them. So Microsoft apparently differentiates between requires user dismissal and can be clicked for furhter action. Also, the absence of any hints that their notifications are actually clickable makes them have this text everywhere, which is unfortunate, IMO. Dmitry
Re: FormData with sliced Blob
To be even safer, I'd remove dashes from it... I never knew why GUIDs have those dashes - to make them easier to memorize? :-) Seriously though, it would be nice to have XHR2 spec to have these details spelled out, especially mime type (I think David meant application/octet-stream) Dmitry On Mon, Mar 22, 2010 at 5:26 PM, Jian Li jia...@google.com wrote: To be safe, probably UA can choose to create the unique name from the GUID, like blob-5597cb2e-74fb-479a-81e8-10679c523118. On Mon, Mar 22, 2010 at 4:43 PM, David Levin le...@google.com wrote: What about using a filename that is unique with repect to files sent in that FormData (but it is up to the UA)? For example, a UA may choose to do Blob1, Blob2, etc. For the content-type, application/octet-string seems most fitting. Here's the result applied to your example: --SomeBoundary... Content-Disposition: form-data; name=file; filename=Blob1 Content-Type: application/octet-string dave On Fri, Mar 19, 2010 at 6:25 PM, Jian Li jia...@google.com wrote: Hi, I have questions regarding sending FormData with sliced files. When we send a FormData with a regular file, we send out the multipart data for this file, like the following: --SomeBoundary... Content-Disposition: form-data; name=file; filename=test.js Content-Type: application/x-javascript ... However, when it is sliced into a blob, it does not have the file name and type information any more. I am wondering what we should send. Should we just not provide the filename and Content-Type information? Thanks, Jian
Re: [FileAPI] Blob.URN?
Blob would need a content-type for that, but it could probably easy be added as a property that is assignable. BTW if the Blob could have a urn and mime type, this info could be directly used to form the headers for the Blob when sending it in multipart form using FormData. Dmitry On Tue, Mar 23, 2010 at 2:23 PM, Darin Fisher da...@chromium.org wrote: Apologies if this has been discussed before, but I'm curious why URN is not a property of Blob. It seems like it would be useful to be able to load a slice of a File. For example, this could be used by an application to fetch all of its subresources out of a single file. -Darin
Re: [FileAPI] Blob.URN?
Those seem to open up so many edge cases... If we have a File constructor like this, now we have a new category of File objects that do have names but are not related to actual files on a local file system, and perhaps have different lifetime expectations. Ability to specify a name and content disposition also does not fall in naturally. For example, is what happens when a blob with 'inline' disposition used in anchor's href or iframe's src? What happens if one specifies the creation/modification time parameters? What would it mean to specify a size parameter in content disposition when underlying Blob also has size property? Even one step back, are we sure there is a use case for Blob.urn? If Blobs are sliced from the files on a local filesystem that user selected via a File Dialog, what would be a scenario for slice/load? There were requests to have a single network resource that can be slice/loaded on arrival, but was the slicing and loading of local files discussed? The most obvious use case for local files is to be uploaded, perhaps in slices. On Wed, Mar 24, 2010 at 1:58 AM, Anne van Kesteren ann...@opera.com wrote: On Wed, 24 Mar 2010 03:40:36 +0100, Michael Nordman micha...@google.com wrote: This has been discussed before, not sure what the conclusion was (if any) http://www.mail-archive.com/public-webapps@w3.org/msg06137.html http://www.mail-archive.com/public-webapps@w3.org/msg06345.htmlsnip In order for the URN to be useful, it would have to have a mediaType associated with it, and then there's content-disposition to think about, which then wants a file name as well...boy, that's a lot of baggage. However, since these aren't really inherent properties of the Blob, just of the way you want the browser to view the Blob, it would seem natural to me do to something like this: interface Blob { ... DOMString getURN(in DOMString mediaType, [Optional] in DOMString contentDisposition, [Optional] in DOMString name); }; /snip Wouldn't it be better to have a constructor for File. I.e. File(Blob, name, type, contentdisposition) or some such. (Maybe some of the attributes on File should be made mutable, i.e. name and mime...) Also, didn't we decide to change URN to URL? As far as I can tell that is how Gecko is implementing it. -- Anne van Kesteren http://annevankesteren.nl/
Re: [FileAPI] Blob.URN?
On Fri, Apr 2, 2010 at 5:34 PM, Eric Uhrhane er...@google.com wrote: On Tue, Mar 30, 2010 at 2:57 PM, Darin Fisher da...@chromium.org wrote: On Tue, Mar 30, 2010 at 12:22 AM, Jonas Sicking jo...@sicking.cc wrote: On Tue, Mar 23, 2010 at 2:23 PM, Darin Fisher da...@chromium.org wrote: Apologies if this has been discussed before, but I'm curious why URN is not a property of Blob. It seems like it would be useful to be able to load a slice of a File. For example, this could be used by an application to fetch all of its subresources out of a single file. IIRC originally it was placed on File since Blobs do not have a content type. However I think there is general agreement that it should be moved to Blob. However it would be great to be able to assign a content type to a Blob. Possibly slice() could take a optional argument. Adding an optional parameter to slice() sounds attractive indeed. BlobBuilder [1] should probably also have such an optional argument. -Darin [1] http://dev.w3.org/2009/dap/file-system/file-writer.html#the-blobbuilder-interface That seems reasonable. But if we move the content type and disposition to the Blob, and can get a URL from a Blob, then File is left with...just a name? I think being actually stored in the local file system is the biggest difference between Blob and File. For example, it can be found there again (assuming we'll get capability to store File, as a reference, in database), after the page closes. Or find it there if there is some name convention.
Re: Updates to File API
On Tue, May 18, 2010 at 2:56 PM, Arun Ranganathan a...@mozilla.com wrote: On 5/18/10 2:35 PM, Eric Uhrhane wrote: On Mon, May 17, 2010 at 3:37 PM, Dmitry Titovdim...@chromium.org wrote: I have couple of questions, mostly clarifications I think: 1. FileReader takes Blob but there are multiple hints that the blob should be actually a 'file'. As we see Blob concept grows in popularity with such specs as FileWriter that defines BlobBuilder. Other proposals include Image Resizing that returns a Blob with a compressed image data. Can all types of Blobs be 'read' using FileReader? If not, then it would be logical to only accept File parameter. If any type of Blob can be read (as I think the spirit of the spec assumes) then would it be less confusing to cange the name to BlobReader? I'd support that. I think we always want to allow reading of any type of Blob--it's the interchange container--so calling it BlobReader makes sense. Arun, how do you feel about that? The FileReader object accepts File objects for DataURL-reads, and Blob objects for binary string, text, and binary reads. I agree that having a name like FileReader is generally a bit confusing, given that we do allow Blobs to be read, including Blobs which aren't directly coined from files. Blob itself isn't a great name, though it's a stand-in for Binary Large Object. Aside from the slight bikeshed-ish nature of this discussion, there are implementations in circulation that already use the name FileReader (e.g. Firefox 3.6.3). This doesn't mean I'm against changing it, but I do wish the name change suggestion came earlier. Also, I'm keen that the main object name addresses the initial use case -- reading file objects. Perhaps in the future Blobs that are not files will be the norm; maybe then, Blob APIs will evolve, including implementations with ArrayBuffer and potential streaming use cases getting addressed better. Perhaps it is late to have a name change, and we've added to less-than-adequate naming on the Web (example: XMLHttpRequest). Ok, I can see how it can be late if FF already shipped it... Perhaps the spec could at least avoid using 'fileBlob' as names of arguments, since the naming currently may be interpreted as if only file-backed blobs are welcome :-) Would FileWriter ever be used to write anything other than a File? I think not, so it should probably stay as it is, despite the lack of symmetry. 2. The FileReader.result is a string. Actually, in my next draft, I will have FileReader.result be of type 'any' (WebILD's 'any') since it could also be an ArrayBuffer (using the readAsBinary method, which will function like the other asynchrous read methods, but read into ArrayBuffers across the ProgressEvent spectrum. Getting an ArrayBuffer on each ProgressEvent could be a cool idea indeed. I guess when we have ArrayBuffers we'll be able to use them in BlobBuilder as well. -- A*
Re: [File API] Recent Updates To Specification + Co-Editor
+1 to window.createBlobUrl(blob) and window.revokeBlobUrl(url) , they make lifetime of a blob url (which is different from lifetime of the Blob JS object) way more clear to me, since it attaches it explicitly to a window, and to a specific window in that. Multi-window web apps (like GMail or IM) have multiple windows that cross-script each other, so it's very easy to change the code a little and the 'spawning Document, as defined in the spec now, changes, since it's implicitly captured. Explicit is good. It also indeed makes it possible for a good-behaving app to prevent a memory leak in long-lived pages and potentially shared workers, since it gives an explicit 'revoke' method. Nice idea, lets see if it can be added to the spec. Dmitry On Wed, Jun 30, 2010 at 5:38 PM, Jian Li jia...@chromium.org wrote: Thanks for the update. We've some more questions regarding the blob URL. 1. The spec does not describe how blob and blob URL will work in the worker and shared worker scenarios. I think we should allow WorkerGlobalScope to be the binding context for the blob URL, like Document. In addition, we should define how a blob object can be passed to the worker via structured cloning. A new blob object should be expected to be created and it points to the same underlying data. 2. The current spec says that the lifetime of the blob URL is bound to the lifetime of the spawning context. What happens if we try to access the blob url from multiple contexts? Say, we call parent.blob.url, the lifetime of the url is bound to the parent context, not the current context, per the spec. This sounds a little bit unnatural. Could we explicitly provide the context while creating the blob URL, like window.createBlobUrl(blob)? 3. Since the lifetime of the blob URL is bound to a context, the blob URL (the underlying blob data) will get disposed only when the context dies. When we have long-live pages or shared workers, we could have leaked blob URLs that result in unclaimed blob storages. It will be nice if we can add the capability to revoke the blob URL pragmatically, like window.revokeBlobUrl(url), 4. It will be good if the spec could say more about the lifetime of the blob object and the blob URL since they're kind of orthogonal: the blob object will still be functional as long as it is not GC-ed even if the associated context dies. 5. The spec does not describe explicitly about the transient cases, like location.href = blob.url. Probably the spec could mention that the resource pointed by blob URL should be loaded successfully as long as the blob URL is valid at the time when the resource is starting to load. On Mon, Jun 28, 2010 at 2:20 PM, Arun Ranganathan a...@mozilla.comwrote: Greetings WebApps WG, I have made edits to the File API specification [1]. There are a few things of note that I'd like to call the WG's attention to. 1. There is a name change in effect. FileReader has been re-named BlobReader, upon request from Chrome team folks[2][3]. The name BlobReader won't win awards in a beauty pageant, but it tersely describes an object to read Blobs (which could originate from the underlying file system *or* be generated *within* a Web App). My present understanding is that FileWriter will also undergo a name change. Naming is really hard. Firefox already ships with FileReader, but I see the point of having an object named for what it does, which in this case is certainly more than file reading from the underlying file system. I also abhor bike shedding, especially over naming, but this is something that's exposed to the authors. I have not renamed FileError or FileException. In the case of errors and exceptions, I think *most* scenarios will occur as a result of issues with the underlying file system. These names should remain. 2. I've updated the URL scheme for Blobs using an ABNF that calls for an opaque string which is a term I define in the specification. There was much discussion about this aspect of the File API specification, and I think the existing scheme does allow for user agents to tack on origin information in the URL (this is not something the spec. says you should do). The actual choice of opaque string is left to implementations, though the specification suggests UUID in its canonical form (and provides an ABNF for this). I think this is the most any specification has said on the subject of URLs. 3. There is an additional asynchronous read method on BlobReader, and an additional synchronous read method on BlobReaderSync, namely readAsArrayBuffer. These use the TypedArrays definition initially defined by the WebGL WG [4]. 4. I am moving on from my full-time role at Mozilla to a part-time consulting role. I'll continue to be an editor of the File API, but I am stepping down as Chair of the WebGL WG. I'll continue to be active in standards communities, though :-) 5. I spoke to Jonas Sicking, who expressed
Re: Lifetime of Blob URL
Tying a 'lifetime' of a string url to a blob which is not even needed at the point of use seems to be creating a mechanism that doesn't generally work: function getImageUrl() { var a_blob = ... load a blob in some way, perhaps via XHR return a_blob.url; } ... // sometime during initialization var imageUrl = getImageUrl(); ... // sometime later anImage.src = imageUrl; This may work all the time on the developer's computer and fail all the time (or sometimes) in the field. It may be very frustrating. Tying lifetime explicitly to the Window (url dies when window closes or revoke() is called) does not fix all the issues but makes the mechanism less likely to shoot the user in the foot by making it more explicit. Dmitry On Tue, Jul 13, 2010 at 7:37 AM, David Levin le...@google.com wrote: On Tue, Jul 13, 2010 at 6:50 AM, Adrian Bateman adria...@microsoft.comwrote: On Monday, July 12, 2010 2:31 PM, Darin Fisher wrote: On Mon, Jul 12, 2010 at 9:59 AM, David Levin le...@google.com wrote: On Mon, Jul 12, 2010 at 9:54 AM, Adrian Bateman adria...@microsoft.com wrote: I read point #5 to be only about surviving the start of a navigation. As a web developer, how can I tell when a load has started for an img? Isn't this similarly indeterminate. As soon as img.src is set. the spec could mention that the resource pointed by blob URL should be loaded successfully as long as the blob URL is valid at the time when the resource is starting to load. Should apply to xhr (after send is called), img, and navigation. Right, it seems reasonable to say that ownership of the resource referenced by a Blob can be shared by a XHR, Image, or navigation once it is told to start loading the resource. -Darin It sounds like you are saying the following is guaranteed to work: img.src = blob.url; window.revokeBlobUrl(blob); return; If that is the case then the user agent is already making the guarantees I was talking about and so I still think having the lifetime mapped to the blob not the document is better. This means that in the general case I don't have to worry about lifetime management. Mapping lifetime to the blob exposes when the blob gets garbage collected which is a very indeterminate point in time (and is very browser version dependent -- it will set you up for compatibility issues when you update your javascript engine -- and there are also the cross browser issues of course). Specifically, a blob could go out of scope (to use your earlier phrase) and then one could do img.src = blobUrl (the url that was exposed from the blob but not using the blob object). This will work sometimes but not others (depending on whether garbage collection collected the blob). This is much more indeterminate than the current spec which maps the blob.url lifetime to the lifetime of the document where the blob was created. When thinking about blob.url lifetime, there are several problems to solve: 1. An AJAX style web application may never navigate the document and this means that every blob for which a URL is created must be kept around in some form for the lifetime of the application. 2. A blob passed to between documents would have its blob.url stop working as soon as the original document got closed. 3. Having a model that makes the url have a determinate lifetime which doesn't expose the web developer to indeterminate behaviors issues like we have discussed above. The current spec has issues #1 and #2. Binding the lifetime of blob.url to blob has issue #3. dave
Re: File URN lifetimes and SharedWorkers
On Fri, Jul 23, 2010 at 12:15 AM, Ian Hickson i...@hixie.ch wrote: On Tue, 23 Feb 2010, Drew Wilson wrote: This was recently brought to my attention by one of the web app developers in my office: http://dev.w3.org/2006/webapi/FileAPI/#lifeTime User agents MUST ensure that the lifetime of File URN #dfn-fileURNs is the same as the lifetime of the Document [HTML5 #HTML5] of the origin script which spawned the File #dfn-file object on which the urn #dfn-urn attribute was called. When this Document is destroyed, implementations MUST treat requests for File URN #dfn-fileURNs created within thisDocument as 404 Not Found.[Processing Model #processing-model-urn for File URN #dfn-fileURN s] I'm curious how this should work for SharedWorkers - let's imagine that I create a File object in a document and send it to a SharedWorker via postMessage() - the SharedWorker will receive a structured clone of that File object, which it can then access. What should the lifetime of the resulting URN for that file object be? I suspect the intent is that File objects ought to be tied to an owning script context rather than to a specific Document (so, in this case, the lifetime of the resulting URN would be the lifetime of the worker)? Was this ever addressed? Do I need to add something to the workers spec for this? Who is currently editing the File API specs? There is a relevant discussion here: http://lists.w3.org/Archives/Public/public-webapps/2010JulSep/0169.html Looks like adding an explicit createBlobUrl/revokeBlobUrl on global object, and tying the lifetime to this global object as well (implicit revoke) can be less confusing then current spec language. Arun Ranganathan is editor and Jonas Sicking seems to be a co-editor. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: Lifetime of Blob URL
Thanks Jonas, Just to clarify some details we had while discussing this, could you confirm if this matches with your thinking (or not): 1. If blob was created in window1, blob.url was queried, then passed (as JS object) to window2, and window1 was closed - then the url gets invalidated when window1 is closed, but immediately re-validated if window2 queries blob.url. The url string is going to be the same, only there will be a time interval between closing window1 and querying blob.url in window2, during which loading from the url returns 404. 2. If blob is sent to a Worker via worker.postMessage(blob), the 'structured clone' mechanism is used, so on the other side of postMessage a new blob object is created, backed by the same data, but having its own unique blob.url string (and separate lifetime). Dmitry On Mon, Jul 26, 2010 at 2:12 PM, Jonas Sicking jo...@sicking.cc wrote: On Tue, Jul 13, 2010 at 7:37 AM, David Levin le...@google.com wrote: On Tue, Jul 13, 2010 at 6:50 AM, Adrian Bateman adria...@microsoft.com wrote: On Monday, July 12, 2010 2:31 PM, Darin Fisher wrote: On Mon, Jul 12, 2010 at 9:59 AM, David Levin le...@google.com wrote: On Mon, Jul 12, 2010 at 9:54 AM, Adrian Bateman adria...@microsoft.com wrote: I read point #5 to be only about surviving the start of a navigation. As a web developer, how can I tell when a load has started for an img? Isn't this similarly indeterminate. As soon as img.src is set. the spec could mention that the resource pointed by blob URL should be loaded successfully as long as the blob URL is valid at the time when the resource is starting to load. Should apply to xhr (after send is called), img, and navigation. Right, it seems reasonable to say that ownership of the resource referenced by a Blob can be shared by a XHR, Image, or navigation once it is told to start loading the resource. -Darin It sounds like you are saying the following is guaranteed to work: img.src = blob.url; window.revokeBlobUrl(blob); return; If that is the case then the user agent is already making the guarantees I was talking about and so I still think having the lifetime mapped to the blob not the document is better. This means that in the general case I don't have to worry about lifetime management. Mapping lifetime to the blob exposes when the blob gets garbage collected which is a very indeterminate point in time (and is very browser version dependent -- it will set you up for compatibility issues when you update your javascript engine -- and there are also the cross browser issues of course). Specifically, a blob could go out of scope (to use your earlier phrase) and then one could do img.src = blobUrl (the url that was exposed from the blob but not using the blob object). This will work sometimes but not others (depending on whether garbage collection collected the blob). This is much more indeterminate than the current spec which maps the blob.url lifetime to the lifetime of the document where the blob was created. When thinking about blob.url lifetime, there are several problems to solve: 1. An AJAX style web application may never navigate the document and this means that every blob for which a URL is created must be kept around in some form for the lifetime of the application. 2. A blob passed to between documents would have its blob.url stop working as soon as the original document got closed. 3. Having a model that makes the url have a determinate lifetime which doesn't expose the web developer to indeterminate behaviors issues like we have discussed above. The current spec has issues #1 and #2. Binding the lifetime of blob.url to blob has issue #3. Indeed. I agree with others that have said that exposing GC behavior is a big problem. I think especially here where a very natural usage pattern is to grab a File object, extract its url, and then drop the reference to the File object on the floor. And I don't think specifying how GC is supposed to work is a workable solution. I doubt that any browser vendor will be willing to lock down their GC to that degree. GC implementations is a very active area of experimentation and has been for many many years. I see no reason to think that we'd be able to come up with a GC algorithm that wouldn't be obsolete very soon. However I also don't think #3 above is a huge problem. You can always flush a blob to disk, meaning that all that is leaked is an entry in a url-filename hash table. No actual data needs to be kept in memory. It's definitely still a problem, but I figured it's worth pointing out. Given that, I see no other significantly different solution than what is in the spec right now. Though there are definitely some problems that we should fix: 1. Add a function for destroying a url reference seems like a good idea. 2. #2 above can be
Re: Lifetime of Blob URL
As for wild ideas, it also could be something more generic, lets say DataReader which can take Blobs and Files (and perhaps something else in the future). Like XHR that has overloaded methods for xhr.open(..). It seems possible that web developers may not realize that File is actually a Blob and may be confused by using BlobReader to read File. (Do I need to make a Blob out of my File first?). They may be equally confused by using FileReader to read Blob though. On Mon, Aug 30, 2010 at 4:35 PM, Jonas Sicking jo...@sicking.cc wrote: On Mon, Aug 30, 2010 at 4:22 PM, Darin Fisher da...@chromium.org wrote: On Mon, Aug 30, 2010 at 1:08 PM, Jonas Sicking jo...@sicking.cc wrote: On Mon, Aug 30, 2010 at 9:59 AM, Arun Ranganathan a...@mozilla.com wrote: In addition, BlobError and BlobException sound better because these names are consistent with current Blob naming scheme in File API. So we're also going to adopt these new names in the WebKit implementation when we rename FileReader to BlobReader per the spec. *sigh. Naming continues to be hard. Not everyone's thrilled with the proliferation of Blob in the API [1] including other major implementors (my co-editor included ;-)) but I changed it mainly due to Darin/Jian/other objections. I suppose you folks are pretty adamant on the Blob* name? I feel pretty strongly that we should name this back to FileReader, for several reasons: 1. Most people that I talk to dislike the name Blob, much less having it spread to things like BlobReader. 2. My understanding is that the writer counterpart is going to be called FileWriter (is this correct?) Yes, that is what we are currently implementing in WebKit. 3. While it's certainly possible to read Blobs with this, it seems to me like the far most common case will be to read a real file, or part of a file (i.e. the result from myfile.slice()). 4. There is one shipping implementation of FileReader It just seems odd to use an interface named FileReader to read blobs, which may not correspond to files. Consider BlobBuilder, which can be used to construct a Blob from a string. I somewhat agree. But it seems equally strange to use BlobReader to read files, and I suspect that it will be vastly more common to read files than blobs-that-aren't-files. Yes, the File interface inherits Blob, so technically when you're reading a file you're also reading a blob, but I doubt that is the mental model most people will have. Like so many other things, there is no perfect solution here. Another idea (possibly a crazy one) would be to eliminate Blob, and just use File for everything. We could rename BlobBuilder to FileBuilder and have it return a File instead of a Blob. Same goes for Blob.slice(). Of course, the File would not necessarily correspond to a real physical file on disk for performance reasons. I've been thinking about this too. I can't say I feel strongly either way. It feels somewhat strange, but I can't come up with any solid technical reasons against it. / Jonas
Re: Discussion of File API at TPAC in Lyon
I have a clarifying question about how it would work: How, if at all, the lifetime of the generated urls will be defined in case of having those functions on URL interface object? If those methods are on a global object, the lifetime of the urls created would be gated by the lifetime of that global object, and in browser implementations that lifetime is usually defined well - and used for other things like lifetime of shared workers for example. There is certain times when the document/page/window are 'closed and detached', and while it varies in implementations and it is more complex then that, it provides a well-understood lifetime boundary. By having those methods on some static object, doesn't the lifetime becomes unclear? Do we grab 'current context of the call'? Dmitry On Tue, Nov 16, 2010 at 8:10 AM, Jonas Sicking jo...@sicking.cc wrote: On Tuesday, November 16, 2010, Anne van Kesteren ann...@opera.com wrote: On Tue, 16 Nov 2010 01:35:05 +0100, Jonas Sicking jo...@sicking.cc wrote: Ok, here is what I'll propose as the final solution: FileAPI will define the following WebIDL: [Supplemental] interface URL { static DOMString createObjectURL(in Blob blob); static void revokeObjectURL(in DOMString url); }; [...] Unless I hear otherwise from people, I'll assume that everyone is happy with this. This looks great. Will this make it into Firefox 4? Assuming we can get everyone to agree quickly enough, yes. / Jonas
Re: Discussion of File API at TPAC in Lyon
Thanks Michael, so the proposed change is this: window.createObjectURL - window.URL.createObjectURL and it means it's also possible to do something like this: var otherWindow = window.open(...) otherWindow.URL.createObjectURL(...) Is this correct understanding? Dmitry On Tue, Nov 16, 2010 at 11:57 AM, Michael Nordman micha...@google.comwrote: On Tue, Nov 16, 2010 at 10:42 AM, Dmitry Titov dim...@chromium.org wrote: I have a clarifying question about how it would work: How, if at all, the lifetime of the generated urls will be defined in case of having those functions on URL interface object? If those methods are on a global object, the lifetime of the urls created would be gated by the lifetime of that global object, and in browser implementations that lifetime is usually defined well - and used for other things like lifetime of shared workers for example. There is certain times when the document/page/window are 'closed and detached', and while it varies in implementations and it is more complex then that, it provides a well-understood lifetime boundary. By having those methods on some static object, doesn't the lifetime becomes unclear? Do we grab 'current context of the call'? The intent (as i understand it) was to not change the lifetime semantics that had been devised when these methods were defined at the global scope, just to put a 'namespace' around them (so to speak). The goal being a little less clutter the global namespace. Dmitry On Tue, Nov 16, 2010 at 8:10 AM, Jonas Sicking jo...@sicking.cc wrote: On Tuesday, November 16, 2010, Anne van Kesteren ann...@opera.com wrote: On Tue, 16 Nov 2010 01:35:05 +0100, Jonas Sicking jo...@sicking.cc wrote: Ok, here is what I'll propose as the final solution: FileAPI will define the following WebIDL: [Supplemental] interface URL { static DOMString createObjectURL(in Blob blob); static void revokeObjectURL(in DOMString url); }; [...] Unless I hear otherwise from people, I'll assume that everyone is happy with this. This looks great. Will this make it into Firefox 4? Assuming we can get everyone to agree quickly enough, yes. / Jonas
Re: Discussion of File API at TPAC in Lyon
On Tue, Nov 16, 2010 at 12:20 PM, Jonas Sicking jo...@sicking.cc wrote: On Tue, Nov 16, 2010 at 12:07 PM, Dmitry Titov dim...@chromium.org wrote: Thanks Michael, so the proposed change is this: window.createObjectURL - window.URL.createObjectURL and it means it's also possible to do something like this: var otherWindow = window.open(...) otherWindow.URL.createObjectURL(...) Is this correct understanding? If you do this, then the lifetime of the URL is the lifetime of the Document in otherWindow. Actually since at the time you're calling createObjectURL otherWindow still contains an about:blank document, as soon as the url passed to window.open is loaded, the returned URL will expire. That makes perfect sense, thanks!
Re: clipboard events
Sounds reasonable, and close to what IE and WebKit implement... Seems the clipboardData object may simply implement dataTransferhttp://dev.w3.org/html5/spec/dnd.html#the-datatransfer-interfaceinterface. This would give it legacy setData/getData as well as items http://dev.w3.org/html5/spec/dnd.html#datatransferitems list which can be used for blob-backed reads/writes. The list of formats that can be found in dataTransfer, although limited now, will probably grow in the future to enable better integration between applications (XML Spreadsheet or image for example). I can imagine a web app that wants to support copy/paste with popular products like MS Office... Many of those are not suitable for getData() that returns a string, because they are long/async in nature and/or binary. They will need to be transferred as blobs or files. Dmitry On Thu, Dec 23, 2010 at 7:35 AM, Hallvord R. M. Steen hallv...@opera.comwrote: Hi, looking at what Opera needs to support I drafted a specish text for clipboard events. Something for this WG? -- Hallvord R. M. Steen, Core Tester, Opera Software http://www.opera.com http://my.opera.com/hallvors/
Re: [FileAPI] File.slice spec bug
Taking back the claim about Safari :-) It doesn't have File.slice indeed. Sorry about that. On Tue, Apr 12, 2011 at 1:36 PM, Dmitry Titov dim...@chromium.org wrote: Indeed, it appeared in FF 4 which was shipped end of March, so if it was only FF API, it would be fine to change it since it's only been official for a couple of weeks. However in Chrome this was shipped August 2010, and in Safari sometime in 2010 I think. Oprah seems also support it, although I don't know for how long. This could give plenty of time to developers to start using the API, so I can see how it would give us a pause while considering such a change... Dmitry On Tue, Apr 12, 2011 at 1:15 PM, Kyle Huey m...@kylehuey.com wrote: First supported in Firefox in Firefox 4, if that is unclear. On Tue, Apr 12, 2011 at 1:14 PM, Kyle Huey m...@kylehuey.com wrote: File.slice was first supported in Firefox 4. - Kyle On Tue, Apr 12, 2011 at 1:08 PM, Jian Li jia...@chromium.org wrote: The biggest concern is that this is a breaking change and quite a few web applications have already been using it. As far as I know, File.slice(start, length) has been supported as early as Chrome 6 and Safari 5. Also Firefox 3 is supporting it. How do we communicate with web developers about this breaking change if we decide to make the change? Jian On Tue, Apr 12, 2011 at 11:34 AM, Arun Ranganathan a...@mozilla.comwrote: On 4/12/11 2:24 PM, Jonas Sicking wrote: Hi All, It was recently (yesterday) pointed out to me that we let a bad spec-bug slip through for File.slice. It doesn't match the argument semantics of Array.slice which can be very confusing for developers. In Array.slice the second argument is the index of the last item to be included in the returned slice. In File.slice the second argument is the number of bytes included in the returned slices. In other words, it's Array.slice(start, end), but File.slice(start, length). Additionally, in Array.slice the second argument is optional. File.slice is currently shipped by Chrome and Firefox 4. I would be fine with fixing this in Firefox 4.0.1, however that only makes sense if the chrome folks are fine with fixing it in their implementation. So consider this an official request, would chrome be ok with changing the spec here? / Jonas I'm bummed that we collectively let this slip through the cracks, and personally think it's early enough to fix it. But we should also decide how closely to match Array.slice. Should we allow code of the sort file.slice(-80)? Code of that sort is allowed with Array.slice. MDC has good developer docs about what's in Firefox for Array.slice: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice Developers may have already discovered file.slice (e.g. see http://hacks.mozilla.org/2011/04/resumeupload/), so fixing this will involve some messaging. -- A*
Re: [FileAPI] File.slice spec bug
It can be more then it looks though - if site detects File.slice and then uses it, it will automatically pick up FF and Opera now because the method now is defined. But the code is assuming the 'length' semantics of the second parameter. So if the site is using recommended method of detection, the fact that it is only Chrome that implemented it so far does not necessarily reduce the scope of compat issue. For example, there is an open-source JS library that uses file.slice: http://www.plupload.com/index.php. They detect it by checking File.prototype.slice. So essentially, they are cross-browser. File.slice is probably going to be used by minority of advanced web developers (for offline apps or async upload kind of scenarios) and those care less about similarity with string.slice() perhaps. They routinely fight the subtle differences between browsers though. They already do detection for slice(), if FF will implement some newSlice(begin, end) - they probably will just add another line to detection, a piece of different math and curse the browser developers :-) On Tue, Apr 12, 2011 at 4:55 PM, Jonas Sicking jo...@sicking.cc wrote: On Tue, Apr 12, 2011 at 4:25 PM, Darin Fisher da...@chromium.org wrote: On Tue, Apr 12, 2011 at 4:02 PM, Mike Taylor miketa...@gmail.com wrote: On 4/12/11 2:05 PM, Jonas Sicking wrote: It appears that Opera too implements File.slice. Would be great to know for how long it's been implemented. The first public build [1] with File.slice was made available last week. It's only been officially supported as of today, however, with the release of 11.10. [1] http://my.opera.com/desktopteam/blog/2011/04/05/stability-gmail-socks - Mike As Jian mentioned earlier, File.slice has been available in Chrome since version 6, which was released Sept 2, 2010: http://googlechromereleases.blogspot.com/2010/09/stable-and-beta-channel-updates.html It seems like too much time has passed with this feature baked into Chrome for us to be able to change its behavior now. While I agree that it would be nice for .slice(...) to work the same way in all contexts, I'm just not sure that this is something we can remove from Chrome at this point or even change. I'm very concerned about breaking existing web content. A new name for this function might be nice, but once you do that then I'm not sure that its arguments should really be any different than the current arguments for Blob.slice(). What's wrong with start and length other than that the fact that it differs from the parameters to Array.slice? Why should Blob.createSubBlob favor the argument style of Array.slice over Blob.slice? I don't really care much about which style a new function would take. I just think it's a really bad idea to have File.slice and Array.slice which basically do exactly the same thing but take subtly different arguments. I guess I'm leaning toward no change at all and just taking our lumps for having created an inconsistent API :-/ Given that only chrome has supported File.slice up until last week, I doubt there are that many sites that rely on it. Do you know of any? Any non-google ones (and thus would be harder to update)? / Jonas