gevorg gevorg - 6 months ago 14
Javascript Question

How can I filter out directories from upload handler in Firefox?

I have following code snippet that is used to get file information during file drag and drop upload:

var files = event.dataTransfer.files;

for (var i = 0; i < files.length; i++) {
var file = files[i];

// I need notDirectory(file) function.
notDirectory(file).then(function(file) {
output.innerHTML +=
`<p>
Name: ${file.name}</br>
Size: ${file.size} bytes</br>
Type: ${file.type}</br>
Modified Date: ${file.lastModifiedDate}
</p>`;
});
}


I did research and found that Firefox does not support directory uploads, but allows client to drag and drop them to drop area.

Question is how can I filter out directories from upload handler in Firefox?

You can find working sample here: https://jsfiddle.net/gevorgha/exs3ta25/

UPDATE

Please consider that I need it to work on the latest stable Firefox version -
46.0.1
without enabling extra preferences from browser, because I don't want to ask users to enable preference to make upload work properly.

Answer

I came up with following dirty workaround that works on the latest Firefox version - 46.0.1

function notDirectory(file) {
    return new Promise(function(resolve, reject) {
        var reader = new FileReader(file);

        // Can read files, but not directories.
        reader.onprogress = function(event) {
            if ('progress' === event.type) {
                resolve(file);
                reader.abort();
            }
        };

        // Wait for result.
        reader.readAsDataURL(file);
    });
}

I use FileReader API to check if uploaded file is directory or not. Not sure if this is the best solution, but it is the only 100% working solution that I was able to find.

My Solution

var dropArea = document.getElementById("dropArea");
var output = document.getElementById("result");

function dragHandler(event) {
    event.stopPropagation();
    event.preventDefault();

    dropArea.className = "area drag";
}

// To be defined.
function notDirectory(file) {
    return new Promise(function(resolve, reject) {
        var reader = new FileReader(file);

        // Can read files, but not directories.
        reader.onprogress = function(event) {
            if ('progress' === event.type) {
                resolve(file);
                reader.abort();
            }
        };

        // Wait for result.
        reader.readAsDataURL(file);
    });
}

function filesDroped(event) {
    event.stopPropagation();
    event.preventDefault();

    dropArea.className = "area";
    output.innerHTML = "";

    var files = event.dataTransfer.files;

    for (var i = 0; i < files.length; i++) {
        var file = files[i];

        // I need notDirectory(file) function.
        notDirectory(file).then(function(file) {
            output.innerHTML += `<p>
                            Name: ${file.name}</br> 
                            Size: ${file.size} bytes</br> 
                            Type: ${file.type}</br> 
                            Modified Date: ${file.lastModifiedDate}
                          </p>`;
        });
    }
}


dropArea.addEventListener("dragover", dragHandler);
dropArea.addEventListener("drop", filesDroped);
.area {
    border: 5px dotted #ccc;    
    padding: 50px;    
    text-align: center;    
}

.drag {
    border: 5px dotted green;            
    background-color: yellow;
}
<div id="dropArea" class="area">Drop your files here!</div>
<output id="result" />

Comments