A user account is required in order to edit this wiki, but we've had to disable public user registrations due to spam.

To request an account, ask an autoconfirmed user on Chat (such as one of these permanent autoconfirmed members).

DragAndDropEntries: Difference between revisions

From WHATWG Wiki
Jump to navigation Jump to search
(Created page with 'Proposing exposing dropped files/folders as {File,Directory}Entry defined in FileSystem API [1] for better folders/files drag-and-drop support. [1] File API: Directories and Sys...')
 
Line 9: Line 9:
== Proposal ==
== Proposal ==


Add a new field 'entries' to <input type=files> element and a new accessor method 'getAsEntry()' to DataTransferItem object, and populate the field with or return a file or directory 'Entry' defined in FileSystem API [1] upon file selection or drop events.
Add a new field 'entries' to <input type=files> element [1] and a new accessor method 'getAsEntry()' to DataTransferItem object [2].  Populate the field with or return an 'Entry' object defined in FileSystem API upon file selection or drop events.
 
Since FileSystem API naturally supports tree-structured folder hierarchy, Entry object exposes handy fields like 'isFile' and 'isDirectory', and allows webapps to recursively walk over the nested entries in subfolders via ReadDirectory() method.
 
This approach allows webapps to directly interact with the local folder structure, and also allows them to control the enumerating part so that the apps can show nice progress meter if they want.


   interface HTMLInputElement : HTMLElement {
   interface HTMLInputElement : HTMLElement {
Line 22: Line 18:
     readonly attribute Entry[] entries;
     readonly attribute Entry[] entries;
   }
   }
http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#file-upload-state-(type=file)


   interface DataTransferItem {
   interface DataTransferItem {
Line 33: Line 27:
   };
   };


http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitem-interface
[1] http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#file-upload-state-(type=file)
[2] http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitem-interface
 
Since FileSystem API naturally supports tree-structured folder hierarchy, Entry object exposes handy fields like 'isFile' and 'isDirectory', and allows webapps to recursively walk over the nested entries in subfolders via ReadDirectory() method.
 
This approach allows webapps to directly interact with the local folder structure, and also allows them to control the enumerating part so that the apps can show nice progress meter if they want.


=== Isolated FileSystem ===
=== Isolated FileSystem ===
Line 41: Line 40:
The Entry does not support toURL() or is not resolvable by resolveFileSystemURL(), since its filesystem is transient and has limited life time (while toURL URL's do not work as live references like Blob URLs).
The Entry does not support toURL() or is not resolvable by resolveFileSystemURL(), since its filesystem is transient and has limited life time (while toURL URL's do not work as live references like Blob URLs).


=== Example ===
=== Usage Scenario ===


Assume a user has following files and folders in his/her 'Photos' folder:
Assume a user has following files and folders in his/her 'Photos' folder:
Line 64: Line 63:
We can think of similar interesting usage scenarios like local-cloud sync app or bulk 'importer', e.g. importing local source directory to cloud IDE etc.
We can think of similar interesting usage scenarios like local-cloud sync app or bulk 'importer', e.g. importing local source directory to cloud IDE etc.


=== Example Code ===
=== Example Code (Drag and Drop) ===
 
  var droptarget = document.getElementById('droptarget');
 
  droptarget.addEventListener('dop', function (e) {
    e.stopPropagation();
    e.preventDefault();
    var items = e.dataTransfer.items;
    for (var i = 0; i < items.length; ++i) {
      if (items[i].kind != "file")
          continue;
      var entry = items[i].getAsEntry();
      if (entry.isDirectory) {
        traverseDirectoryTree(entry);
      } else {
        showFileEntry(entry);
      }
  });
 
=== Example Code (Input) ===
 
  <input type="file" multiple />
 
  var input = document.querySelector("input[type='file']");
  input.addEventListener('change', function (e) {
    e.stopPropagation();
    e.preventDefault();
    var entries = e.target.entries;
    for (var i = 0; i < entries.length; ++i) {
      if (entries[i].isDirectory) {
        traverseDirectoryTree(entry);
      } else {
        showFileEntry(entries[i]);
      }
  });
 


(coming soon)


[[Category:Proposals]]
[[Category:Proposals]]

Revision as of 18:45, 15 June 2012

Proposing exposing dropped files/folders as {File,Directory}Entry defined in FileSystem API [1] for better folders/files drag-and-drop support.

[1] File API: Directories and System http://www.w3.org/TR/file-system-api/

Background

Many sites have 'upload your files' feature, like for your photo images. HTML5 allows you to do this via <input type="file" multiple> or drag-and-drop feature, but the current solution does not provide clean solution for cases with folders, files/folder mixed cases, or folders with subfolders cases.

Proposal

Add a new field 'entries' to <input type=files> element [1] and a new accessor method 'getAsEntry()' to DataTransferItem object [2]. Populate the field with or return an 'Entry' object defined in FileSystem API upon file selection or drop events.

 interface HTMLInputElement : HTMLElement {
    // allows scripts to access the element's selected files as an array of Entry defined in FileSystem API.
    // On getting, if the IDL attribute applies, it must return a Entry array that represents the current selected files and/or folders.
    // If the IDL attribute does not apply, then it must instead return null.
    // Unless the multiple attribute is set, there must be no more than one file in the list of selected files.
    readonly attribute Entry[] entries;
 }
 interface DataTransferItem {
   // Like DataTransferItem.getAsFile(), getAsEntry() method runs following steps:
   // 1. If the DataTransferItem object is not in the read/write mode or the read-only mode, return null and abort these steps.
   // 2. If the drag data item kind is not File, then return null and abort these steps.
   // 3. Return a new Entry object representing the actual file or directory represented by the DataTransferItem object.
   Entry getAsEntry();
 };

[1] http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#file-upload-state-(type=file) [2] http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitem-interface

Since FileSystem API naturally supports tree-structured folder hierarchy, Entry object exposes handy fields like 'isFile' and 'isDirectory', and allows webapps to recursively walk over the nested entries in subfolders via ReadDirectory() method.

This approach allows webapps to directly interact with the local folder structure, and also allows them to control the enumerating part so that the apps can show nice progress meter if they want.

Isolated FileSystem

The Entry exposed by this feature is created in an Isolated filesystem, which is read-only, isolated and transient. The filesystem only contains the dropped items and can only be accessed by the site where the drag-and-drop event has happened. Webapps cannot access any other files or folders outside the filesystem.

The Entry does not support toURL() or is not resolvable by resolveFileSystemURL(), since its filesystem is transient and has limited life time (while toURL URL's do not work as live references like Blob URLs).

Usage Scenario

Assume a user has following files and folders in his/her 'Photos' folder:

   /Users/username/Photos/trip/1.jpg
   /Users/username/Photos/trip/2.jpg
   /Users/username/Photos/trip/3.jpg
   /Users/username/Photos/halloween/2011/a.jpg
   /Users/username/Photos/halloween/2011/b.jpg
   /Users/username/Photos/halloween/2012/plan.jpg
   /Users/username/Photos/tokyo/1.jpg
   /Users/username/Photos/tokyo/2.jpg

When the user drag-and-drops or selects the two folders, trip, halloween and one photo file tokyo/1.jpg, the webapp will get following entries via 'entries' field of the input element or via DataTransferItem.getAsEntry():

   DirectoryEntry for 'trip',
   DirectoryEntry for 'halloween'
   FileEntry for '1.jpg'

Via the new 'entries' field the app can access children files or subfolders in the selected entries, and can properly organize and process pictures using the local folder structure. Even if the dropped directory is on a slow removable media, or it contains tons of subdirectories and files, the app can recursively traverse each of them while showing a nice progress information, or can show an interactive file tree which lets the user freely expand or select some of the contents.

We can think of similar interesting usage scenarios like local-cloud sync app or bulk 'importer', e.g. importing local source directory to cloud IDE etc.

Example Code (Drag and Drop)

  var droptarget = document.getElementById('droptarget');
  droptarget.addEventListener('dop', function (e) {
    e.stopPropagation();
    e.preventDefault();
    var items = e.dataTransfer.items;
    for (var i = 0; i < items.length; ++i) { 
      if (items[i].kind != "file")
         continue;
      var entry = items[i].getAsEntry();
      if (entry.isDirectory) {
        traverseDirectoryTree(entry);
      } else {
        showFileEntry(entry);
      }
  });

Example Code (Input)

 <input type="file" multiple />
  var input = document.querySelector("input[type='file']");
  input.addEventListener('change', function (e) {
    e.stopPropagation();
    e.preventDefault();
    var entries = e.target.entries;
    for (var i = 0; i < entries.length; ++i) { 
      if (entries[i].isDirectory) {
        traverseDirectoryTree(entry);
      } else {
        showFileEntry(entries[i]);
      }
  });