Drag and Drop File Browser

https://html5-demos.appspot.com/static/dnd/all_types_of_import.html

HTML

<body class="centerall ascolumn">

<details>
  <summary>What's this?</summary>
  <div>
    <p>An image gallery app showing the different ways to import files and
      folder contents using drag and drop and <code>&lt;input type="file"&gt;</code>. Chrome 21 includes drag and drop support for dropping a folder. This is done with hooks into the <a href="http://www.html5rocks.com/en/tutorials/file/filesystem/" target="_blank">HTML5 FileSystem API</a>. For more info, see 
    <a href="http://wiki.whatwg.org/wiki/DragAndDropEntries" target="_blank">wiki.whatwg.org/wiki/DragAndDropEntries</a>.</p>
    <p><b>Support:</b> Chrome 21 supports folder drop reading DataTransferItems as files (<code>.webkitGetAsEntry()</code>)
      <code>input[type="file"].webkitEntries</code> support landed in Chrome 22.</p>
  </div>
</details>

<aside class="green">Working...</aside>

<section id="droparea">
  <div dropzone webkitdropzone="copy file:image/png file:image/gif file:image/jpeg" class="centerall">
    Drop images or a folder of them
    <div class="arrow left centerall ascolumn">
      <img src="http://s25.postimg.org/x0zyu6xzj/curved_arrow.png">
      <span>Drag and drop files/folders from your desktop</span>
    </div>
  </div>
</section>
<section class="separator">OR</section>
<section id="fileinput">
  <div>
    <input type="file" accept="image/*" multiple>
    <div class="arrow up centerall ascolumn">
      <img src="http://s25.postimg.org/x0zyu6xzj/curved_arrow.png">
      <span>Select file(s), or drag and drop files/folders on to me</span>
    </div>
  </div>
</section>

<footer class="centerall"></footer>
    </body>

CSS

::selection {
  color: #eee;
  background: darkred;
}
body ::-webkit-scrollbar {
  height: 16px;
  overflow: visible;
  width: 16px;
}
body ::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, .1);
  background-clip: padding-box;
  border: solid transparent;
  min-height: 28px;
  padding: 100px 0 0;
  box-shadow: inset 1px 1px 0 rgba(0,0,0,.1),inset 0 -1px 0 rgba(0,0,0,.07);
  border-width: 1px 1px 1px 6px;
}
body ::-webkit-scrollbar-thumb:hover {
  background-color: rgba(0, 0, 0, 0.5);
}
body ::-webkit-scrollbar-button {
  height: 0;
  width: 0;
}
::-webkit-scrollbar-track {
  background-clip: padding-box;
  border: solid transparent;
  border-width: 0 0 0 4px;
}
body ::-webkit-scrollbar-corner {
  background: transparent;
}
html, body {
  height: 100%;
  overflow: hidden;
  margin: 0;
  padding: 0;
}
body {
  color: #222;
  font-family: 'Open Sans', arial, sans-serif;
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
  padding: 2em;
  background: -webkit-gradient(radial, center center, 500, center center, 1400, from(rgba(0,0,0,0)), to(rgba(0,0,0,0.6))) #fff;
  background: -moz-radial-gradient(farthest-side, rgba(0,0,0,0) 90%, rgba(0,0,0,0.2) 150%) #fff;
  background: -webkit-radial-gradient(farthest-side, rgba(0,0,0,0) 90%, rgba(0,0,0,0.2) 150%) #fff;
  background: -ms-radial-gradient(farthest-side, rgba(0,0,0,0) 90%, rgba(0,0,0,0.2) 150%) #fff;
  background: -o-radial-gradient(farthest-side, rgba(0,0,0,0) 90%, rgba(0,0,0,0.2) 150%) #fff;
  background: radial-gradient(farthest-side, rgba(0,0,0,0) 90%, rgba(0,0,0,0.2) 150%) #fff;
  box-sizing: border-box;
}
a {
  color: navy;
}
details {
  position: absolute;
  top: 0;
  left: 1em;
  margin: 1em 0;
  padding: 10px;
  background: #fff;
  border: 1px solid rgba(0,0,0,0.3);
  border-radius: 5px;
  max-width: 600px;
  font-size: 10pt;
  z-index: 100;
  background: #F7F7F7;
}
details > div {
  margin: 10px 0;
}
details > summary {
  cursor: pointer;
  white-space: nowrap;
}
button {
  display:...

JavaScript

window.requestFileSystem = window.requestFileSystem ||
                           window.webkitRequestFileSystem;
window.resolveLocalFileSystemURL = window.webkitResolveLocalFileSystemURL ||
    window.webkitResolveLocalFileSystemURL;

var fs = null;
var cwd = null;
var DONE_MSG = 'Donezo';
var NOT_IMG_MSG = 'One or more files is not an image.';
var footer = document.querySelector('footer');

function setLoadingTxt(obj) {
  var el = document.querySelector('aside');
  if (obj && obj.txt) {
    var stayOpen = obj.stayOpen || false;
    var isError = obj.error || false;

    if (isError) {
      el.classList.add('red');
    }

    el.textContent = obj.txt;
    el.classList.add('show');

    if (!stayOpen) {
      window.setTimeout(setLoadingTxt, 3000);
    }
  } else {
    el.classList.remove('show');
    el.classList.remove('red');
  }
}

function writeFile(file, dirEntry, callback) {
  dirEntry.getFile(file.name, {create: true}, function(fileEntry) {
    fileEntry.createWriter(function(writer) {
      writer.onwriteend = callback;
      writer.onerror = callback;
      writer.write(file);
    }, onError);
  }, onError);
}

function onError(e) {
  switch (e.code) {
    case FileError.INVALID_MODIFICATION_ERR:
      setLoadingTxt({
        txt: 'Error: that directory path already exists',
        error: true
      });
      break;
    default:
      setLoadingTxt({txt: 'Error code: ' + e.code, error: true});
      break;
  }
}

function toArray(list) {
  return Array.prototype.slice.call(list || [], 0);
}

function readDirectory(dirEntry, callback) {
  var dirReader = dirEntry.createReader();
  var entries = [];

  // Call the reader.readEntries() until no more results are returned.
  var readEntries = function() {
     dirReader.readEntries (function(results) {
      if (!results.length) {
        callback(entries);
      } else {
        entries = entries.concat(toArray(results));
        readEntries();
      }
    }, onError);
  };

  readEntries(); // Start...