2
 * Default text - jQuery plugin for html5 dragging files from desktop to browser
 
 
6
 * Email: [Firstname][Lastname]@gmail.com
 
 
8
 * Copyright (c) 2010 Resopollution
 
 
10
 * Licensed under the MIT license:
 
 
11
 *   http://www.opensource.org/licenses/mit-license.php
 
 
14
 *   http://www.github.com/weixiyen/jquery-filedrop
 
 
19
 *      Allows sending of extra parameters with file.
 
 
20
 *      Works with Firefox 3.6+
 
 
21
 *      Future-compliant with HTML5 spec (will work with Webkit browsers and IE9)
 
 
23
 *      See README at project homepage
 
 
28
        jQuery.event.props.push("dataTransfer");
 
 
33
                        paramname: 'userfile',
 
 
35
                        maxfilesize: 1, // MBs
 
 
47
                        error: function(err, file, i){alert(err);},
 
 
49
                        uploadFinished: empty,
 
 
50
                        progressUpdated: empty,
 
 
53
                errors = ["BrowserNotSupported", "TooManyFiles", "FileTooLarge"],
 
 
59
        $.fn.filedrop = function(options) {
 
 
60
                opts = $.extend( {}, default_opts, options );
 
 
62
                this.bind('drop', drop).bind('dragenter', dragEnter).bind('dragover', dragOver).bind('dragleave', dragLeave);
 
 
63
                $(document).bind('drop', docDrop).bind('dragenter', docEnter).bind('dragover', docOver).bind('dragleave', docLeave);
 
 
68
                files = e.dataTransfer.files;
 
 
69
                if (files === null || files === undefined) {
 
 
70
                        opts.error(errors[0]);
 
 
74
                files_count = files.length;
 
 
80
        function getBuilder(filename, filedata, boundary) {
 
 
85
                $.each(opts.data, function(i, val) {
 
 
86
                if (typeof val === 'function') val = val();
 
 
90
                        builder += 'Content-Disposition: form-data; name="'+i+'"';
 
 
100
                builder += 'Content-Disposition: form-data; name="'+opts.paramname+'"';
 
 
101
                builder += '; filename="' + filename + '"';
 
 
104
                builder += 'Content-Type: application/octet-stream';
 
 
118
        function progress(e) {
 
 
119
                if (e.lengthComputable) {
 
 
120
                        var percentage = Math.round((e.loaded * 100) / e.total);
 
 
121
                        if (this.currentProgress != percentage) {
 
 
123
                                this.currentProgress = percentage;
 
 
124
                                opts.progressUpdated(this.index, this.file, this.currentProgress);
 
 
126
                                var elapsed = new Date().getTime();
 
 
127
                                var diffTime = elapsed - this.currentStart;
 
 
128
                                if (diffTime >= opts.refresh) {
 
 
129
                                        var diffData = e.loaded - this.startData;
 
 
130
                                        var speed = diffData / diffTime; // KB per second
 
 
131
                                        opts.speedUpdated(this.index, this.file, speed);
 
 
132
                                        this.startData = e.loaded;
 
 
133
                                        this.currentStart = elapsed;
 
 
144
                        opts.error(errors[0]);
 
 
150
                if (files_count > opts.maxfiles) {
 
 
151
                    opts.error(errors[1]);
 
 
155
                for (var i=0; i<files_count; i++) {
 
 
156
                        if (stop_loop) return false;
 
 
158
                                if (beforeEach(files[i]) != false) {
 
 
159
                                        if (i === files_count) return;
 
 
160
                                        var reader = new FileReader(),
 
 
161
                                                max_file_size = 1048576 * opts.maxfilesize;
 
 
164
                                        if (files[i].size > max_file_size) {
 
 
165
                                                opts.error(errors[2], files[i], i);
 
 
170
                                        reader.onloadend = send;
 
 
171
                                        reader.readAsBinaryString(files[i]);
 
 
176
                                opts.error(errors[0]);
 
 
182
                        // Sometimes the index is not attached to the
 
 
183
                        // event object. Find it by size. Hack for sure.
 
 
184
                        if (e.target.index == undefined) {
 
 
185
                                e.target.index = getIndexBySize(e.total);
 
 
188
                        var xhr = new XMLHttpRequest(),
 
 
190
                                file = files[e.target.index],
 
 
191
                                index = e.target.index,
 
 
192
                                start_time = new Date().getTime(),
 
 
193
                                boundary = '------multipartformboundary' + (new Date).getTime(),
 
 
196
                        newName = rename(file.name);
 
 
197
                        if (typeof newName === "string") {
 
 
198
                                builder = getBuilder(newName, e.target.result, boundary);
 
 
200
                                builder = getBuilder(file.name, e.target.result, boundary);
 
 
203
                        upload.index = index;
 
 
205
                        upload.downloadStartTime = start_time;
 
 
206
                        upload.currentStart = start_time;
 
 
207
                        upload.currentProgress = 0;
 
 
208
                        upload.startData = 0;
 
 
209
                        upload.addEventListener("progress", progress, false);
 
 
211
                        xhr.open("POST", opts.url, true);
 
 
212
                        xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' 
 
 
215
                        xhr.sendAsBinary(builder);  
 
 
217
                        opts.uploadStarted(index, file, files_count);  
 
 
219
                        xhr.onload = function() { 
 
 
220
                            if (xhr.responseText) {
 
 
221
                                var now = new Date().getTime(),
 
 
222
                                    timeDiff = now - start_time,
 
 
223
                                    result = opts.uploadFinished(index, file, jQuery.parseJSON(xhr.responseText), timeDiff);
 
 
225
                                        if (filesDone == files_count - filesRejected) {
 
 
228
                            if (result === false) stop_loop = true;
 
 
234
        function getIndexBySize(size) {
 
 
235
                for (var i=0; i < files_count; i++) {
 
 
236
                        if (files[i].size == size) {
 
 
244
        function rename(name) {
 
 
245
                return opts.rename(name);
 
 
248
        function beforeEach(file) {
 
 
249
                return opts.beforeEach(file);
 
 
252
        function afterAll() {
 
 
253
                return opts.afterAll();
 
 
256
        function dragEnter(e) {
 
 
257
                clearTimeout(doc_leave_timer);
 
 
262
        function dragOver(e) {
 
 
263
                clearTimeout(doc_leave_timer);
 
 
269
        function dragLeave(e) {
 
 
270
                clearTimeout(doc_leave_timer);
 
 
275
        function docDrop(e) {
 
 
281
        function docEnter(e) {
 
 
282
                clearTimeout(doc_leave_timer);
 
 
288
        function docOver(e) {
 
 
289
                clearTimeout(doc_leave_timer);
 
 
295
        function docLeave(e) {
 
 
296
                doc_leave_timer = setTimeout(function(){
 
 
304
                if (XMLHttpRequest.prototype.sendAsBinary) return;
 
 
305
                XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
 
 
306
                    function byteValue(x) {
 
 
307
                        return x.charCodeAt(0) & 0xff;
 
 
309
                    var ords = Array.prototype.map.call(datastr, byteValue);
 
 
310
                    var ui8a = new Uint8Array(ords);
 
 
311
                    this.send(ui8a.buffer);
 
 
 
b'\\ No newline at end of file'