uppie.js
function newDirectoryApi(input, opts, cb) {
    var fd = new FormData(), files = [];
    var iterate = function(entries, path, resolve) {
      var promises = [];
      entries.forEach(function(entry) {
        promises.push(new Promise(function(resolve) {
          if ("getFilesAndDirectories" in entry) {
            entry.getFilesAndDirectories().then(function(entries) {
              iterate(entries, entry.path + "/", resolve);
            });
          } else {
            if (entry.name) {
              var p = (path + entry.name).replace(/^[/\\]/, "");
              fd.append(opts.name, entry, p);
              files.push(p);
            }
            resolve();
          }
        }));
      });
      Promise.all(promises).then(resolve);
    };
    input.getFilesAndDirectories().then(function(entries) {
      new Promise(function(resolve) {
        iterate(entries, "/", resolve);
      }).then(cb.bind(null, fd, files));
    });
  }
function newDirectoryApi(input, opts, cb) {
    var fd = new FormData(), files = [];
    var iterate = function(entries, path, resolve) {
      var promises = [];
      entries.forEach(function(entry) {
        promises.push(new Promise(function(resolve) {
          if ("getFilesAndDirectories" in entry) {
            entry.getFilesAndDirectories().then(function(entries) {
              iterate(entries, entry.path + "/", resolve);
            });
          } else {
            if (entry.name) {
              var p = (path + entry.name).replace(/^[/\\]/, "");
              fd.append(opts.name, entry, p);
              files.push(p);
            }
            resolve();
          }
        }));
      });
      Promise.all(promises).then(resolve);
    };
    input.getFilesAndDirectories().then(function(entries) {
      new Promise(function(resolve) {
        iterate(entries, "/", resolve);
      }).then(cb.bind(null, fd, files));
    });
  }
function newDirectoryApi ( input , opts , cb ) { var fd = new FormData ( ) , files = [ ] ; var iterate = function ( entries , path , resolve ) { var promises = [ ] ; entries . forEach ( function ( entry ) { promises . push ( new Promise ( function ( resolve ) { if ( "getFilesAndDirectories" in entry ) { entry . getFilesAndDirectories ( ) . then ( function ( entries ) { iterate ( entries , entry . path + "/" , resolve ) ; } ) ; } else { if ( entry . name ) { var p = ( path + entry . name ) . replace ( / ^[/\\] / , "" ) ; fd . append ( opts . name , entry , p ) ; files . push ( p ) ; } resolve ( ) ; } } ) ) ; } ) ; Promise . all ( promises ) . then ( resolve ) ; } ; input . getFilesAndDirectories ( ) . then ( function ( entries ) { new Promise ( function ( resolve ) { iterate ( entries , "/" , resolve ) ; } ) . then ( cb . bind ( null , fd , files ) ) ; } ) ; }
API implemented in Firefox 42+ and Edge
API implemented in Firefox 42 + and Edge