Re: [whatwg] Using requestFileSystem to setup mounts

2011-12-21 Thread Bronislav Klučka

Hi,
what about

window.MOUNT_ONCE
- mount only for current session
- would open select folder dialog

window.MOUNT_ALWAYS
- mount for all time (or to be more precise for the time of life time of 
IndexDB, cookies, etc).
- user have to give explicit permission for this and only after this permission 
is given, select folder dialog is opened
- delete browser data (IndexDB, cookies, etc) would only remove permission to 
access such folder, not it's content

FileSystem interface has property name, so programmers could distinguish among 
several FileSystem object and could store those somewhere (e.g. LocalStorage).

if folder, which is already mounted, was selected from select directory dialog, than 
already existing FileSystem object would be returned corresponding with that directory (e.g. 
fs.name = '123-456-abc' is created once c:/tmp is requested and that FileSystem object 
would be always returned if the same folder is requested). Name property would than probably have 
to be some kind of hash of the original directory path (so it's unique across users desktop file 
system)

This could be very important feature, because currently there is no (real) 
persistent storage, even when window.PERSISTENT file system is created, data 
can be removed by just users desire to delete cookies (browser generally do not 
allow to specifie what kind data should be removed [cookies/indexdb/websql/app 
cache/local storage/etc.] At this point, it's quite a pain to e.g. create 
export file from data you already have in browser without accessing server...


The only problem I see with this approach is that it does not allow very common 
screnario: save file as in regular desktop app way:
1/ user clicks save
2/ save as dialog is opened and file (file name with path) is returned
3/ app creates file based on that path
4/ app writes data to file

having only FS mounted to directory would require:
1/ have someinput type=text  where user writes file name
2/ user types file name to that input
3/ user clicks save
4/ select folder dialog is opened, FileSystem is returned in callback
5/ app creates file based on returned FileSystem and file name from step 1
6/ app writes data to file

in desktop app scenario user specifies whole file path, in requestFileSystem 
scenario, user would have to specifie file name and then path... quite a 
different behaviour from what users are used to (users are used to desktop app 
behaviour even in browser when downloading file from internet)...

B.

On 21.11.2011 15:10, Kinuko Yasuda wrote:



Additionally, I might pass window.MOUNT into rFS, which may prompt the user
to select a mount point, bypassinginputaltogether.

This sounds cool, and I think eventually we want to have some explicit way
to mount an arbitrary directory in a way this (requestFileSystem(MOUNT)),
but what concerns me most in this generalized API is how we should
define the lifetime of the mount'ed filesystem.



-Charles







Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-28 Thread Glenn Maynard
On Mon, Nov 28, 2011 at 9:18 AM, Kinuko Yasuda kin...@chromium.org wrote:

 On Wed, Nov 23, 2011 at 1:58 AM, Glenn Maynard gl...@zewt.org wrote:

 This would lead to interop problems if it's not consistent, though.  For
 example, if my application creates ZIP files, and the user drags two files
 into the root directory of the ZIP, he wants to put those files at the top
 of the ZIP:

 /file1.txt
 /file2.txt

 If the UA creates a virtual directory for that drag, then it'd end up
 putting the files in a subdirectory with the name of the virtual directory,
 as if a directory was dragged:

 /drag-and-drop/file1.txt
 /drag-and-drop/file2.txt


 The UA can simply puts the file1.txt and file2.txt in the virtual 'root'
 directory if Entry.fullPath matters.


The problem is that a drop event with two separate files will probably be
treated differently by some software than one with a single directory
containing two files.  That'll be true no matter what Entry.fullPath is set
to.  That's why it'd be an interop problem if some browsers do this and
some don't.

(I don't think the value of Entry.fullPath is very important for drops.  It
can probably just be /.)

-- 
Glenn Maynard


Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-22 Thread Kinuko Yasuda
On Tue, Nov 22, 2011 at 7:30 AM, Glenn Maynard gl...@zewt.org wrote:
 On Mon, Nov 21, 2011 at 4:33 PM, Charles Pritchard ch...@jumis.com wrote:

 Multiple directories still have a shared file system root. Their relative
 paths are exposed in webkitdirectory files already.
 The benefit is neutered .files object while maintaining compatibility with
 existing code bases.

 It would be strange to drag in multiple directories and to have it exposed
 as a virtual directory containing the dragged files.  It could be done, but
 it's inconsistent with the design of DataTransfer, and it feels unnatural.

 I don't know what you mean by compatibility with existing code bases; the
 compatibility is no different than a getAsEntry/getAsWritableEntry API would
 be.

Putting aside the API discussion, actually I like the idea having one shared
isolated filesystem that contains multiple directories/files being dropped in,
as in that way both the UA and script can easily distinguish the set of
dropped files/directories as a single group sharing the same filesystem
object.  I don't think that must be enforced as a part of spec or
recommendation, but I don't think it's strange having multiple
files/directories being dropped in the same virtual root directory either.
(I'm not saying we should weigh rFS approach more than .entries
or getAsEntry)

 Also, remember that DataTransfer objects can be filled in programmatically.
 You can do, for example:

 dt.items.add(hello world, text/plain); // already supported
 dt.items.add(myFile); // already supported
 dt.items.add(myFileEntry); // new DataTransferItemList.add(Entry data)
 method
 dt.items.add(myDirectoryEntry);

 The requestFileSystem approach doesn't fit with DataTransfer's design very
 naturally.

 (Adding a File would be equivalent to adding a FileEntry containing the
 File; both would just create a DataTransferItem with a kind of file.)

 What values will Entry.filesystem and Entry.fullpath have?

 Each Entry would have a dummy FileSystem object attached to it, in order to
 fill out the Entry.filesystem API, but all it would contain is the file
 itself.

Again I think this could be left to the UA's implementation decision.

 Entry.fullPath would be the same as Entry.name, prefixed with /.

 As synchronous methods, won't these block the user if they need to confirm
 permission to mount a directory?
 As async methods, these might add a lot of calls to the stack.

 Async methods (eg. theoretically getAsWritableEntry) is adding no more calls
 than would be added by a similar async requestFileSystem call, which is also
 async.

 getAsEntry gives read-only access; as with getAsFile, there's no additional
 permission prompt.  Both methods could be async if we really want to allow
 for separate permissions prompting even for read-only access (though that's
 awkward UI, especially *during* a drag).  Either way, it's no more code for
 users than a requestFileSystem call.

 Recursing directories is the current behavior of webkitdirectory.

 Yes, this should go away if possible, or at least not be propagated to other
 browsers.  It's not a scalable approach, as we discussed earlier.
 --
 Glenn Maynard




Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-22 Thread Glenn Maynard
 On Tue, Nov 22, 2011 at 6:06 AM, Kinuko Yasuda kin...@chromium.org wrote:

 Putting aside the API discussion, actually I like the idea having one
 shared
 isolated filesystem that contains multiple directories/files being dropped
 in,
 as in that way both the UA and script can easily distinguish the set of
 dropped files/directories as a single group sharing the same filesystem
 object.  I don't think that must be enforced as a part of spec or
 recommendation, but I don't think it's strange having multiple
 files/directories being dropped in the same virtual root directory either.
 (I'm not saying we should weigh rFS approach more than .entries
 or getAsEntry)


This would lead to interop problems if it's not consistent, though.  For
example, if my application creates ZIP files, and the user drags two files
into the root directory of the ZIP, he wants to put those files at the top
of the ZIP:

/file1.txt
/file2.txt

If the UA creates a virtual directory for that drag, then it'd end up
putting the files in a subdirectory with the name of the virtual directory,
as if a directory was dragged:

/drag-and-drop/file1.txt
/drag-and-drop/file2.txt

 Each Entry would have a dummy FileSystem object attached to it, in order
 to
  fill out the Entry.filesystem API, but all it would contain is the file
  itself.

 Again I think this could be left to the UA's implementation decision.


The main point is just that a FileSystem object will always be available,
even if the UA is only exposing one file in a directory which contains
other (inaccessible) files.  Most of the time it wouldn't be used, it just
avoids exceptional cases in the API.  (In other words, Entry.filesystem
would not become nullable.)

-- 
Glenn Maynard


Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-21 Thread Kinuko Yasuda
Hi, thanks for your comment!

On Sun, Nov 20, 2011 at 5:54 AM, Charles Pritchard ch...@jumis.com wrote:
 Kinuko Yasuda, I saw your post to whatwg regarding drag-and-drop directory
 mounts.

 I'm sure you've seen the various concerns people have with the proposal..
 Like others, I'm also concerned about the security implications of
 traversing a directory and sealing the action upon drop, or otherwise
 setting up a mount point.

 That said, directory is still an extension and open to change:
 http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-April/025764.html
 http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#file-upload-state

 I'd like to consider your proposal in light of the existing
 requestFileSystem method.

 requestFileSystem is still very much open and under experiment with
 Chromium.

 For example:
 // Typical use of rFS:
 window.requestFileSystem(window.PERSISTENT, 1*1024*1024, cb);

 // Proposal, using DataTransfer with rFS:
 input.ondrop = function(e) {
  window.requestFileSystem(e.dataTransfer, 0, cb);
 }

This looks neat, though this would do almost same as what I was
assuming the internal implementation would do.  One clear benefit
I found in your proposal is the code would make the fact that the UA
is actually instantiating a new filesystem per drop clearer.
On the other hand I'm afraid this may slightly complicate the API
by overloading the requestFileSystem.

 There's some slight room for delaying the population of
 e.dataTransfer.files, by using a long-running for loop, or something of that
 sort.  Otherwise,
 if rFS is used, .files will not be populated. This avoids directory
 traversal overhead while using rFS for permissions management.

I may not be quite following this point.  I might be missing
something but isn't it same with the case where the app script
just checks the existence of the new field like .entries and then
falls back to .files if the field doesn't exist?
If .entries is supported the script doesn't need to touch the
.files field thus the UA does not need to populate the .files
field (though I guess if the UA supports .files field it'd start
populating the field before it is actually accessed).

 Authors can pass in 0 for the requested size to give the UA a hint that
 they have no intention of writing to disk.
 This gives authors a chance to use FileEntry instead of File, in addition to
 mounting directories which helps with copyTo.

 Might add a new constant, where we have window.PERSISTENT, we could add
 window.MOUNT or EXTERNAL.

 That way, I can run:   if(window.MOUNT) to detect the feature, and otherwise
 fall back to .files.

 Additionally, I might pass window.MOUNT into rFS, which may prompt the user
 to select a mount point, bypassinginput  altogether.

This sounds cool, and I think eventually we want to have some explicit way
to mount an arbitrary directory in a way this (requestFileSystem(MOUNT)),
but what concerns me most in this generalized API is how we should
define the lifetime of the mount'ed filesystem.

In the original thread I proposed the mounting feature in a very limited
context, i.e. input and drag-and-drop context, mainly because I hoped
limiting the scoped and usage would have much smaller security and lifetime
issues (though it still needs a serious consideration).
In the drag-and-drop context it's clear that the permission and namespace
must go away once the context goes away.  But for more generic and
extended usage (I assume requestFileSystem(window.MOUNT) would
imply more generic usage) probably we should be more careful about how
long and when the filesystem lifetime should expire.  Maybe we could collect
real usage with the limited mount support and then move things forward
incrementally.  Wdyt?

 -Charles




Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-21 Thread Glenn Maynard
I wish people wouldn't randomly split threads.  This isn't a different
conversation.

On Mon, Nov 21, 2011 at 9:10 AM, Kinuko Yasuda kin...@chromium.org wrote:

 On Sun, Nov 20, 2011 at 5:54 AM, Charles Pritchard ch...@jumis.com
 wrote:
  input.ondrop = function(e) {
   window.requestFileSystem(e.dataTransfer, 0, cb);
  }

 This looks neat, though this would do almost same as what I was
 assuming the internal implementation would do.  One clear benefit
 I found in your proposal is the code would make the fact that the UA
 is actually instantiating a new filesystem per drop clearer.
 On the other hand I'm afraid this may slightly complicate the API
 by overloading the requestFileSystem.


This API doesn't work, because you can drop multiple directories at once;
you'd need to pass the DataTransferItem.  I don't really see the benefit to
this approach, though.

I didn't look closely enough at the DataTransferItem API before.  It looks
like Entry can be fully supported without removing anything currently
specced.  Add a getAsEntry method, which returns FileEntry (for kind ==
file) or DirectoryEntry (for a new kind == directory).

getAsFile would be unchanged, returning File for kind == file and null
for anything else (including kind == directory).

This is also a convenient way to expose access (a bit later on).  Add an
async method getAsWritableEntry(onsuccess, ondenied) method.  On success,
the callback supplies a new FileEntry or DirectoryEntry which allows write
access.  Note that while this needs to be async, since it may ask the user
for permission, the read-only method can be synchronous like getFile.  (In
practice the UA would probably ask do you want to allow the page to write
to these files, not ask for each individual file, so it doesn't ask over
and over if the caller is requesting write access to several
simultaneously-dropped files.)

If .entries is supported the script doesn't need to touch the
 .files field thus the UA does not need to populate the .files
 field (though I guess if the UA supports .files field it'd start
 populating the field before it is actually accessed).


I don't think .files should ever recurse directories, which makes this
problem go away.

In the drag-and-drop context it's clear that the permission and namespace
 must go away once the context goes away.


The permission should be attached to the Entry object, not the browsing
context.  If you send an Entry to a SharedWorker, the SharedWorker should
still have access to the file if the context that sent it is closed.  If
*all* contexts attached to the SharedWorker go away, then the worker will
be terminated, and that's when you'll lose the permission as a side-effect
of losing the object.

This is clear and consistent, and scales cleanly to future APIs (in both
Window and Worker) exposing Entry objects from various sources.

But for more generic and
 extended usage (I assume requestFileSystem(window.MOUNT) would
 imply more generic usage) probably we should be more careful about how
 long and when the filesystem lifetime should expire.  Maybe we could
 collect
 real usage with the limited mount support and then move things forward
 incrementally.  Wdyt?


I think drag-and-drop is a good next step for the API.

-- 
Glenn Maynard


Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-21 Thread Charles Pritchard

On 11/21/11 6:10 AM, Kinuko Yasuda wrote:

Hi, thanks for your comment!

On Sun, Nov 20, 2011 at 5:54 AM, Charles Pritchardch...@jumis.com  wrote:


// Proposal, using DataTransfer with rFS:
input.ondrop = function(e) {
  window.requestFileSystem(e.dataTransfer, 0, cb);
}



There's some slight room for delaying the population of
e.dataTransfer.files, by using a long-running for loop, or something of that
sort.  Otherwise,
if rFS is used, .files will not be populated. This avoids directory
traversal overhead while using rFS for permissions management.

I may not be quite following this point.  I might be missing
something but isn't it same with the case where the app script
just checks the existence of the new field like .entries and then
falls back to .files if the field doesn't exist?
If .entries is supported the script doesn't need to touch the
.files field thus the UA does not need to populate the .files
field (though I guess if the UA supports .files field it'd start
populating the field before it is actually accessed).


Neuter the .files object early in the event loop so that FileList does 
not need to be populated


// .files is neutered after rFS.
 window.requestFileSystem(e.dataTransfer, 0, cb);
 e.dataTransfer.files; /* this will throw an error. */


Additionally, I might pass window.MOUNT into rFS, which may prompt the user
to select a mount point, bypassinginputaltogether.

This sounds cool, and I think eventually we want to have some explicit way
to mount an arbitrary directory in a way this (requestFileSystem(MOUNT)),
but what concerns me most in this generalized API is how we should
define the lifetime of the mount'ed filesystem.


Conservatively have Entry.toURL return undefined, or a new prefixed value.

Undefined is fairly safe and is the default case for file:/// with 
webkitURL.createObjectURL

Users can still run .file and create a blob url.

An extended Entry.toURL returns the filesystem: url prefix:
filesystem:blob:random:/path/.

The lifetime of the filesystem is undefined and may expire at any time.

In the drag-and-drop context it's clear that the permission and namespace
must go away once the context goes away.  But for more generic and
extended usage (I assume requestFileSystem(window.MOUNT) would
imply more generic usage) probably we should be more careful about how
long and when the filesystem lifetime should expire.  Maybe we could collect
real usage with the limited mount support and then move things forward
incrementally.  Wdyt?
Afaik, the requestFileSystem API is used by extension developers and 
browser extensions are a good place to carefully roll out new APIs.


requestFileSystem(window.MOUNT) could simply trigger directory selection.

// Basic polyfill for requestFileSystem(window.MOUNT)
var input = document.createElement('input');
input.type = 'file';
input.setAttribute('webkitdirectory', '');
input.click();

// HTML polyfill of input type=file and mount points:
input type=file onclick=requestFileSystem(window.MOUNT); return 
false; /



-Charles



Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-21 Thread Charles Pritchard

On 11/21/11 8:45 AM, Glenn Maynard wrote:
On Mon, Nov 21, 2011 at 9:10 AM, Kinuko Yasuda kin...@chromium.org 
mailto:kin...@chromium.org wrote:


On Sun, Nov 20, 2011 at 5:54 AM, Charles Pritchard
ch...@jumis.com mailto:ch...@jumis.com wrote:
 input.ondrop = function(e) {
  window.requestFileSystem(e.dataTransfer, 0, cb);
 }

This looks neat, though this would do almost same as what I was
assuming the internal implementation would do.  One clear benefit
I found in your proposal is the code would make the fact that the UA
is actually instantiating a new filesystem per drop clearer.
On the other hand I'm afraid this may slightly complicate the API
by overloading the requestFileSystem.


This API doesn't work, because you can drop multiple directories at 
once; you'd need to pass the DataTransferItem.  I don't really see the 
benefit to this approach, though.


Multiple directories still have a shared file system root. Their 
relative paths are exposed in webkitdirectory files already.
The benefit is neutered .files object while maintaining compatibility 
with existing code bases.


I didn't look closely enough at the DataTransferItem API before.  It 
looks like Entry can be fully supported without removing anything 
currently specced.  Add a getAsEntry method, which returns FileEntry 
(for kind == file) or DirectoryEntry (for a new kind == directory).


What values will Entry.filesystem and Entry.fullpath have?

As synchronous methods, won't these block the user if they need to 
confirm permission to mount a directory?

As async methods, these might add a lot of calls to the stack.


If .entries is supported the script doesn't need to touch the
.files field thus the UA does not need to populate the .files
field (though I guess if the UA supports .files field it'd start
populating the field before it is actually accessed).


I don't think .files should ever recurse directories, which makes this 
problem go away.


Recursing directories is the current behavior of webkitdirectory.



But for more generic and
extended usage (I assume requestFileSystem(window.MOUNT) would
imply more generic usage) probably we should be more careful about how
long and when the filesystem lifetime should expire.  Maybe we
could collect
real usage with the limited mount support and then move things forward
incrementally.  Wdyt?


I think drag-and-drop is a good next step for the API.


I think addressing the issues with FileList and webkitdirectory is a 
good first step.



-Charles



Re: [whatwg] Using requestFileSystem to setup mounts

2011-11-21 Thread Glenn Maynard
On Mon, Nov 21, 2011 at 4:33 PM, Charles Pritchard ch...@jumis.com wrote:

 **
 Multiple directories still have a shared file system root. Their relative
 paths are exposed in webkitdirectory files already.
 The benefit is neutered .files object while maintaining compatibility with
 existing code bases.


It would be strange to drag in multiple directories and to have it exposed
as a virtual directory containing the dragged files.  It could be done, but
it's inconsistent with the design of DataTransfer, and it feels unnatural.
I don't know what you mean by compatibility with existing code bases; the
compatibility is no different than a getAsEntry/getAsWritableEntry API
would be.

Also, remember that DataTransfer objects can be filled in
programmatically.  You can do, for example:

dt.items.add(hello world, text/plain); // already supported
dt.items.add(myFile); // already supported
dt.items.add(myFileEntry); // new DataTransferItemList.add(Entry data)
method
dt.items.add(myDirectoryEntry);

The requestFileSystem approach doesn't fit with DataTransfer's design very
naturally.

(Adding a File would be equivalent to adding a FileEntry containing the
File; both would just create a DataTransferItem with a kind of file.)

 What values will Entry.filesystem and Entry.fullpath have?


Each Entry would have a dummy FileSystem object attached to it, in order to
fill out the Entry.filesystem API, but all it would contain is the file
itself.

Entry.fullPath would be the same as Entry.name, prefixed with /.

As synchronous methods, won't these block the user if they need to confirm
 permission to mount a directory?
 As async methods, these might add a lot of calls to the stack.


Async methods (eg. theoretically getAsWritableEntry) is adding no more
calls than would be added by a similar async requestFileSystem call, which
is also async.

getAsEntry gives read-only access; as with getAsFile, there's no additional
permission prompt.  Both methods could be async if we really want to allow
for separate permissions prompting even for read-only access (though that's
awkward UI, especially *during* a drag).  Either way, it's no more code for
users than a requestFileSystem call.

 Recursing directories is the current behavior of webkitdirectory.


Yes, this should go away if possible, or at least not be propagated to
other browsers.  It's not a scalable approach, as we discussed earlier.

-- 
Glenn Maynard