Not really officially yet, but there will probably be, available for us mere web-developers* through the Files and Directory API which specs are still in the process of being written, even though chrome and Firefox already implement something similar through a webkit-API*, which allows us to access and navigate dropped directories.
So if we try to use this webkit-API, we could write something like this:
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
*chrome code (extensions and plugins) generally already have access to a FileSystem API.
*"webkit-API" here means experimental, i.e which behavior may change any time and may not be the same on every browsers.