Directory download API


#1

More info at https://github.com/drufball/directory-download

Proposal

Directory download functionality could be added using existing primitives with relatively little additional API surface area.

webkitRelativePath

File.webkitRelativePath is supported by most major browsers and enables a flattened view of directory structure. Currently, though, this path can only be populated when the user uploads a directory. Adding a path property to the File constructor would allow sites to create their own directory structure without introducing any new primitives to the web platform.

DirectoryEntry

DirectoryEntry recently has been supported by all major browsers. This primitive already enables construction of a tree-view directory structure.

Navigator.saveDirectory()

The primary missing piece is a way to save the constructed directory objects. Calling Navigator.saveDirectory() would behave the same way as saving a file does in browsers today. A “Save as…” dialog could be opened, the directory could be automatically saved to Downloads, the user could rename the directory, etc.

Navigator.saveDirectory() could accept a list of File objects, a DirectoryEntry, or both.

Example code

Using webkitRelativePath

file1 = new File([contents1], 'myFile.txt');
file2 = new File([contents2], 'pic.jpg', { path: 'images' });
navigator.saveDirectory([file1, file2], 'dirName');

Using DirectoryEntry

let myDir = fs.root.getDirectory('dirName', {create:true}, dir => {
    dir.getDirectory('images', {create:true}, subDir => {
        subDir.getFile('pic.jpg', {create:true}, file => {
            myDir.getFile('myFile.txt', {create:true} otherFile => {
                navigator.saveDirectory(myDir, 'dirName');
            });
        });
    });
});

#2

Actually, DirectoryEntry is only supported by Chrome and Opera. http://caniuse.com/#feat=filesystem


#3

This only lets you get write access to a directory. If the user wants to work with a folder of files in a web app, this means repeated import and export steps using directory drag-and-drop followed by directory download to the same place. So what if instead of this the user could simply grant read-write access to a folder on their system? Then you could automatically read the files without user input, and write updated versions back automatically (like this suggestion but without user intervention). However for security reasons browsers would probably want to sandbox these folders… and then it sounds pretty much like we’ve reinvented the filesystem API (which never took off).

There are still serious security concerns with this suggestion - what if a page nags them to choose C:\Windows? Or their documents folder? Is the web app allowed to overwrite files? If not what happens? Must they choose a new folder? If so can they not choose the same folder they used last time?

Also, what about mobile devices where the file system isn’t used like desktop systems traditionally have? If you bring up a “save to directory” dialog on iOS, what should it show? How would the user access files after writing them?

TBH, I think simply writing everything to browser storage (IndexedDB) and then allowing the user to manually download a .zip from time to time neatly avoids all these problems…


#4

I tend to agree that IDB might be the way to go. With the Storage API, it should also be possible to indicate that those “files” should be persistent.

“Sharing” them with other applications, or simply exporting those things out, will then become a separate concern.


#5

@DanielHerr - Good catch! Updated.

@AshleyScirra - We’re investigating that use case with writable-files. Does that look like it covers your use cases?

I believe @sicking has expressed interest in this API from Mozilla as well.


#6

If the function accepts files and folders, perhaps it should be renamed to self.save()


#7

@DanielHerr that’s an interesting idea! You should open an issue for it :slight_smile: