cybermatatu / dnd-file-upload

Automatically exported from code.google.com/p/dnd-file-upload
0 stars 0 forks source link

The code simply sucks (sorry) #11

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I've been reviewing the code and...no wonder there are numerous issues...

First of, there's a grave use of global variables to store event callbacks (eg; 
$.fn.dropzone.uploadStarted = ...), which is why multiple dropzones CANNOT work.

Secondly, there's a good amount of superfluous and faulty code such as:

    var id = this.attr("id");
    var dropzone = document.getElementById(id);

What if the dropzone element doesn't have an id attribute? This is a very 
stupid requirement. The code should instead be:

    var dropzone = this[0]; // DOM elements can be selected
                            // through jQuery by array index.

I'm working on a patch to fix these issues...

Original issue reported on code.google.com by uuf6...@gmail.com on 16 Dec 2011 at 9:35

GoogleCodeExporter commented 9 years ago
// This is my proposed patch. It works with multiple dropzones and has some 
minor adjustments here and there.

(function($) {
    // unchangeable event handlers
    function dragenter(event) {
        event.stopPropagation();
        event.preventDefault();
        return false;
    }
    function dragover(event) {
        event.stopPropagation();
        event.preventDefault();
        return false;
    }
    $.fn.dropzone = function(options) {
        // load options and preprocess
        var opts = $.extend( {}, $.fn.dropzone.defaults, options);
        if(!this.length)return;
        var dropzone = this[0];
        // define event handlers
        function drop(event) {
            var dt = event.dataTransfer;
            var files = dt.files;
            event.preventDefault();
            uploadFiles(files);
            return false;
        }
        function uploadFiles(files) {
            opts.onFilesDropped(files);
            for ( var i = 0; i < files.length; i++) {
                var file = files[i];
                var xhr = new XMLHttpRequest();
                var upload = xhr.upload;
                upload.fileIndex = i;
                upload.fileObj = file;
                upload.downloadStartTime = new Date().getTime();
                upload.currentStart = upload.downloadStartTime;
                upload.currentProgress = 0;
                upload.startData = 0;
                upload.addEventListener("progress", progress, false);
                upload.addEventListener("load", load, false);
                xhr.open(opts.method, opts.url);
                xhr.setRequestHeader("Cache-Control", "no-cache");
                xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                xhr.setRequestHeader("X-File-Name", file.fileName);
                xhr.setRequestHeader("X-File-Size", file.fileSize);
                xhr.setRequestHeader("Content-Type", "multipart/form-data");
                xhr.send(file);
                opts.onUploadStarted(i, file);
            }
        }
        function load(event) {
            var now = new Date().getTime();
            var timeDiff = now - this.downloadStartTime;
            opts.onUploadFinished(this.fileIndex, this.fileObj, timeDiff);
        }
        function progress(event) {
            if (event.lengthComputable) {
                var percentage = Math.round((event.loaded * 100) / event.total);
                if (this.currentProgress != percentage) {
                    this.currentProgress = percentage;
                    opts.onUploadProgressChanged(this.fileIndex, this.fileObj, this.currentProgress);
                    var elapsed = new Date().getTime();
                    var diffTime = elapsed - this.currentStart;
                    if (diffTime >= opts.uploadRateRefreshTime) {
                        var diffData = event.loaded - this.startData;
                        var speed = diffData / diffTime; // in KB/sec
                        opts.onUploadSpeedChanged(this.fileIndex, this.fileObj, speed);
                        this.startData = event.loaded;
                        this.currentStart = elapsed;
                    }
                }
            }
        }
        function change(event) {
            event.preventDefault();
            var files = this.files;
            uploadFiles(files);
        }
        // bind event handlers
        /*if ($.client.browser == "Safari" && $.client.os == "Windows") {
            var fileInput = $("<input>");
            fileInput.attr( {
                type : "file"
            });
            fileInput.bind("change", change);
            fileInput.css( {
                'opacity' : '0',
                'width' : '100%',
                'height' : '100%'
            });
            fileInput.attr("multiple", "multiple");
            fileInput.click(function() {
                return false;
            });
            this.append(fileInput);
        } else {*/
            dropzone.addEventListener("drop", drop, true);
            this.bind("dragenter", dragenter)
                .bind("dragover", dragover);
        /*}*/
        return this;
    };
    // default options
    $.fn.dropzone.defaults = {
        url : "",
        method : "POST",
        numConcurrentUploads : 3,
        uploadRateRefreshTime : 10,
        onFilesDropped: function(files) { console.log('onFilesDropped',arguments); },
        onUploadStarted: function(fileIndex, file) { console.log('onUploadStarted',arguments); },
        onUploadFinished: function(fileIndex, file, time) { console.log('onUploadFinished',arguments); },
        onUploadProgressChanged: function(fileIndex, file, newProgress) { console.log('onUploadProgressChanged',arguments); },
        onUploadSpeedChanged: function(fileIndex, file, KBperSecond) { console.log('onUploadSpeedChanged',arguments); }
    };
})(jQuery);

Original comment by uuf6...@gmail.com on 16 Dec 2011 at 10:40

GoogleCodeExporter commented 9 years ago
It has been tested against jQuery 1.7 and Chrome 16 (Windows 7 x64).

I'm sorry to have removed a lot of comments and empty lines, they should be 
added back.

Original comment by uuf6...@gmail.com on 16 Dec 2011 at 10:43