Blame view

public/js/home/jquery.upload.js 42.1 KB
zhangxiaoru authored
1 2 3 4 5 6
/*
UploadiFive 1.2.2
Copyright (c) 2012 Reactive Apps, Ronnie Garcia
Released under the UploadiFive Standard License <http://www.uploadify.com/uploadifive-standard-license>
*/
lijing authored
7
let jQuery = require('yoho-jquery');
zhangxiaoru authored
8
zhangxiaoru authored
9
(function($) {
zhangxiaoru authored
10
lijing authored
11
    let methods = {
zhangxiaoru authored
12
zhangxiaoru authored
13 14
        init: function(options) {
zhangxiaoru authored
15 16 17
            return this.each(function() {

                // Create a reference to the jQuery DOM object
lijing authored
18
                let $this = $(this);
ccbikai(👎🏻🍜) authored
19
zhangxiaoru authored
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
                $this.data('uploadifive', {
                    inputs: {}, // The object that contains all the file inputs
                    inputCount: 0,  // The total number of file inputs created
                    fileID: 0,
                    queue: {
                        count: 0, // Total number of files in the queue
                        selected: 0, // Number of files selected in the last select operation
                        replaced: 0, // Number of files replaced in the last select operation
                        errors: 0, // Number of files that returned an error in the last select operation
                        queued: 0, // Number of files added to the queue in the last select operation
                        cancelled: 0  // Total number of files that have been cancelled or removed from the queue
                    },
                    uploads: {
                        current: 0, // Number of files currently being uploaded
                        attempts: 0, // Number of file uploads attempted in the last upload operation
                        successful: 0, // Number of files successfully uploaded in the last upload operation
                        errors: 0, // Number of files returning errors in the last upload operation
                        count: 0  // Total number of files uploaded successfully
                    }
                });
lijing authored
40
                let $data = $this.data('uploadifive');
zhangxiaoru authored
41 42

                // Set the default options
lijing authored
43
                let settings = $data.settings = $.extend({
沈志敏 authored
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
                    auto: true,               // Automatically upload a file when it's added to the queue
                    buttonClass: false,              // A class to add to the UploadiFive button
                    buttonText: 'Select Files',     // The text that appears on the UploadiFive button
                    checkScript: false,              // Path to the script that checks for existing file names
                    dnd: true,               // Allow drag and drop into the queue
                    dropTarget: false,              // Selector for the drop target
                    fileObjName: 'Filedata',         // The name of the file object to use in your server-side script
                    fileSizeLimit: 0,                  // Maximum allowed size of files to upload
                    fileType: false,              // Type of files allowed (image, etc), separate with a pipe character |
                    formData: {},                 // Additional data to send to the upload script
                    height: 30,                 // The height of the button
                    itemTemplate: false,              // The HTML markup for the item in the queue
                    method: 'post',             // The method to use when submitting the upload
                    multi: true,               // Set to true to allow multiple file selections
                    overrideEvents: [],                 // An array of events to override
                    queueID: false,              // The ID of the file queue
                    queueSizeLimit: 0,                  // The maximum number of files that can be in the queue
                    removeCompleted: false,              // Set to true to remove files that have completed uploading
                    simUploadLimit: 0,                  // The maximum number of files to upload at once
                    truncateLength: 0,                  // The length to truncate the file names to
                    uploadLimit: 0,                  // The maximum number of files you can upload
                    uploadScript: 'uploadifive.php',  // The path to the upload script
                    width: 100                 // The width of the button
zhangxiaoru authored
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

                    /*
                    // Events
                    'onAddQueueItem'   : function(file) {},                        // Triggered for each file that is added to the queue
                    'onCancel'         : function(file) {},                        // Triggered when a file is cancelled or removed from the queue
                    'onCheck'          : function(file, exists) {},                // Triggered when the server is checked for an existing file
                    'onClearQueue'     : function(queue) {},                       // Triggered during the clearQueue function
                    'onDestroy'        : function() {}                             // Triggered during the destroy function
                    'onDrop'           : function(files, numberOfFilesDropped) {}, // Triggered when files are dropped into the file queue
                    'onError'          : function(file, fileType, data) {},        // Triggered when an error occurs
                    'onFallback'       : function() {},                            // Triggered if the HTML5 File API is not supported by the browser
                    'onInit'           : function() {},                            // Triggered when UploadiFive if initialized
                    'onQueueComplete'  : function() {},                            // Triggered once when an upload queue is done
                    'onProgress'       : function(file, event) {},                 // Triggered during each progress update of an upload
                    'onSelect'         : function() {},                            // Triggered once when files are selected from a dialog box
                    'onUpload'         : function(file) {},                        // Triggered when an upload queue is started
                    'onUploadComplete' : function(file, data) {},                  // Triggered when a file is successfully uploaded
                    'onUploadFile'     : function(file) {},                        // Triggered for each file being uploaded
                    */
                }, options);

                // Calculate the file size limit
                if (isNaN(settings.fileSizeLimit)) {
lijing authored
90
                    let fileSizeLimitBytes = parseInt(settings.fileSizeLimit) * 1.024;
ccbikai(👎🏻🍜) authored
91
zhangxiaoru authored
92 93 94 95 96 97 98 99 100 101 102 103 104
                    if (settings.fileSizeLimit.indexOf('KB') > -1) {
                        settings.fileSizeLimit = fileSizeLimitBytes * 1000;
                    } else if (settings.fileSizeLimit.indexOf('MB') > -1) {
                        settings.fileSizeLimit = fileSizeLimitBytes * 1000000;
                    } else if (settings.fileSizeLimit.indexOf('GB') > -1) {
                        settings.fileSizeLimit = fileSizeLimitBytes * 1000000000;
                    }
                } else {
                    settings.fileSizeLimit = settings.fileSizeLimit * 1024;
                }

                // Create a template for a file input
                $data.inputTemplate = $('<input type="file">')
zhangxiaoru authored
105 106
                    .css({
                        'font-size': settings.height + 'px',
沈志敏 authored
107 108 109 110
                        opacity: 0,
                        position: 'absolute',
                        right: '-3px',
                        top: '-3px',
zhangxiaoru authored
111 112
                        'z-index': 999
                    });
zhangxiaoru authored
113 114 115 116 117

                // Create a new input
                $data.createInput = function() {

                    // Create a clone of the file input
lijing authored
118
                    let input = $data.inputTemplate.clone();
zhangxiaoru authored
119
zhangxiaoru authored
120
                    // Create a unique name for the input item
lijing authored
121
                    let inputName = input.name = 'input' + $data.inputCount++;
zhangxiaoru authored
122
zhangxiaoru authored
123 124 125 126
                    // Set the multiple attribute
                    if (settings.multi) {
                        input.attr('multiple', true);
                    }
zhangxiaoru authored
127
zhangxiaoru authored
128 129 130 131
                    // Set the accept attribute on the input
                    if (settings.fileType) {
                        input.attr('accept', settings.fileType);
                    }
zhangxiaoru authored
132
zhangxiaoru authored
133 134 135 136
                    // Set the onchange event for the input
                    input.bind('change', function() {
                        $data.queue.selected = 0;
                        $data.queue.replaced = 0;
zhangxiaoru authored
137 138 139
                        $data.queue.errors = 0;
                        $data.queue.queued = 0;
zhangxiaoru authored
140
                        // Add a queue item to the queue for each file
lijing authored
141
                        let limit = this.files.length;
ccbikai(👎🏻🍜) authored
142
zhangxiaoru authored
143 144 145 146 147
                        $data.queue.selected = limit;
                        if (($data.queue.count + limit) > settings.queueSizeLimit && settings.queueSizeLimit !== 0) {
                            if ($.inArray('onError', settings.overrideEvents) < 0) {
                                alert('The maximum number of queue items has been reached (' + settings.queueSizeLimit + ').  Please select fewer files.');
                            }
zhangxiaoru authored
148
zhangxiaoru authored
149 150 151 152 153
                            // Trigger the error event
                            if (typeof settings.onError === 'function') {
                                settings.onError.call($this, 'QUEUE_LIMIT_EXCEEDED');
                            }
                        } else {
lijing authored
154 155
                            for (let n = 0; n < limit; n++) {
                                let file = this.files[n];
ccbikai(👎🏻🍜) authored
156
zhangxiaoru authored
157 158 159 160 161
                                $data.addQueueItem(file);
                            }
                            $data.inputs[inputName] = this;
                            $data.createInput();
                        }
zhangxiaoru authored
162
zhangxiaoru authored
163 164 165 166
                        // Upload the file if auto-uploads are enabled
                        if (settings.auto) {
                            methods.upload.call($this);
                        }
zhangxiaoru authored
167
zhangxiaoru authored
168 169 170 171 172
                        // Trigger the select event
                        if (typeof settings.onSelect === 'function') {
                            settings.onSelect.call($this, $data.queue);
                        }
                    });
zhangxiaoru authored
173
zhangxiaoru authored
174 175 176 177 178 179
                    // Hide the existing current item and add the new one
                    if ($data.currentInput) {
                        $data.currentInput.hide();
                    }
                    $data.button.append(input);
                    $data.currentInput = input;
zhangxiaoru authored
180
                };
zhangxiaoru authored
181 182 183 184 185 186

                // Remove an input
                $data.destroyInput = function(key) {
                    $($data.inputs[key]).remove();
                    delete $data.inputs[key];
                    $data.inputCount--;
zhangxiaoru authored
187
                };
zhangxiaoru authored
188 189 190 191 192

                // Drop a file into the queue
                $data.drop = function(e) {
                    $data.queue.selected = 0;
                    $data.queue.replaced = 0;
zhangxiaoru authored
193 194
                    $data.queue.errors = 0;
                    $data.queue.queued = 0;
zhangxiaoru authored
195
lijing authored
196
                    let fileData = e.dataTransfer;
zhangxiaoru authored
197
lijing authored
198
                    let inputName = fileData.name = 'input' + $data.inputCount++;
zhangxiaoru authored
199
zhangxiaoru authored
200
                    // Add a queue item to the queue for each file
lijing authored
201
                    let limit = fileData.files.length;
ccbikai(👎🏻🍜) authored
202
zhangxiaoru authored
203 204 205 206 207 208
                    $data.queue.selected = limit;
                    if (($data.queue.count + limit) > settings.queueSizeLimit && settings.queueSizeLimit !== 0) {
                        // Check if the queueSizeLimit was reached
                        if ($.inArray('onError', settings.overrideEvents) < 0) {
                            alert('The maximum number of queue items has been reached (' + settings.queueSizeLimit + ').  Please select fewer files.');
                        }
zhangxiaoru authored
209
zhangxiaoru authored
210 211 212 213 214 215
                        // Trigger the onError event
                        if (typeof settings.onError === 'function') {
                            settings.onError.call($this, 'QUEUE_LIMIT_EXCEEDED');
                        }
                    } else {
                        // Add a queue item for each file
lijing authored
216
                        for (let n = 0; n < limit; n++) {
zhangxiaoru authored
217 218 219
                            file = fileData.files[n];
                            $data.addQueueItem(file);
                        }
zhangxiaoru authored
220
zhangxiaoru authored
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
                        // Save the data to the inputs object
                        $data.inputs[inputName] = fileData;
                    }

                    // Upload the file if auto-uploads are enabled
                    if (settings.auto) {
                        methods.upload.call($this);
                    }

                    // Trigger the onDrop event
                    if (typeof settings.onDrop === 'function') {
                        settings.onDrop.call($this, fileData.files, fileData.files.length);
                    }

                    // Stop FireFox from opening the dropped file(s)
                    e.preventDefault();
                    e.stopPropagation();
zhangxiaoru authored
238
                };
zhangxiaoru authored
239 240 241

                // Check if a filename exists in the queue
                $data.fileExistsInQueue = function(file) {
lijing authored
242
                    for (let key in $data.inputs) {
zhangxiaoru authored
243 244
                        input = $data.inputs[key];
                        limit = input.files.length;
lijing authored
245
                        for (let n = 0; n < limit; n++) {
zhangxiaoru authored
246
                            existingFile = input.files[n];
zhangxiaoru authored
247
zhangxiaoru authored
248 249 250 251 252 253 254
                            // Check if the filename matches
                            if (existingFile.name == file.name && !existingFile.complete) {
                                return true;
                            }
                        }
                    }
                    return false;
zhangxiaoru authored
255
                };
zhangxiaoru authored
256 257 258

                // Remove an existing file in the queue
                $data.removeExistingFile = function(file) {
lijing authored
259 260 261
                    for (let key in $data.inputs) {
                        let input = $data.inputs[key];
                        let limit = input.files.length;
ccbikai(👎🏻🍜) authored
262
lijing authored
263 264
                        for (let n = 0; n < limit; n++) {
                            let existingFile = input.files[n];
zhangxiaoru authored
265
zhangxiaoru authored
266 267 268 269 270 271 272
                            // Check if the filename matches
                            if (existingFile.name == file.name && !existingFile.complete) {
                                $data.queue.replaced++;
                                methods.cancel.call($this, existingFile, true);
                            }
                        }
                    }
zhangxiaoru authored
273
                };
zhangxiaoru authored
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292

                // Create the file item template
                if (settings.itemTemplate == false) {
                    $data.queueItem = $('<div class="uploadifive-queue-item">\
                        <a class="close" href="#">X</a>\
                        <div><span class="filename"></span><span class="fileinfo"></span></div>\
                        <div class="progress">\
                            <div class="progress-bar"></div>\
                        </div>\
                    </div>');
                } else {
                    $data.queueItem = $(settings.itemTemplate);
                }

                // Add an item to the queue
                $data.addQueueItem = function(file) {
                    if ($.inArray('onAddQueueItem', settings.overrideEvents) < 0) {
                        // Check if the filename already exists in the queue
                        $data.removeExistingFile(file);
zhangxiaoru authored
293
zhangxiaoru authored
294 295
                        // Create a clone of the queue item template
                        file.queueItem = $data.queueItem.clone();
zhangxiaoru authored
296
zhangxiaoru authored
297 298
                        // Add an ID to the queue item
                        file.queueItem.attr('id', settings.id + '-file-' + $data.fileID++);
zhangxiaoru authored
299
zhangxiaoru authored
300 301
                        // Bind the close event to the close button
                        file.queueItem.find('.close').bind('click', function() {
zhangxiaoru authored
302 303
                            methods.cancel.call($this, file);
                            return false;
zhangxiaoru authored
304
                        });
lijing authored
305
                        let fileName = file.name;
ccbikai(👎🏻🍜) authored
306
zhangxiaoru authored
307 308 309 310
                        if (fileName.length > settings.truncateLength && settings.truncateLength != 0) {
                            fileName = fileName.substring(0, settings.truncateLength) + '...';
                        }
                        file.queueItem.find('.filename').html(fileName);
zhangxiaoru authored
311
zhangxiaoru authored
312 313 314 315
                        // Add a reference to the file
                        file.queueItem.data('file', file);
                        $data.queueEl.append(file.queueItem);
                    }
zhangxiaoru authored
316
zhangxiaoru authored
317 318 319 320
                    // Trigger the addQueueItem event
                    if (typeof settings.onAddQueueItem === 'function') {
                        settings.onAddQueueItem.call($this, file);
                    }
zhangxiaoru authored
321
zhangxiaoru authored
322 323 324 325 326 327 328
                    // Check the filesize
                    if (file.size > settings.fileSizeLimit && settings.fileSizeLimit != 0) {
                        $data.error('FILE_SIZE_LIMIT_EXCEEDED', file);
                    } else {
                        $data.queue.queued++;
                        $data.queue.count++;
                    }
zhangxiaoru authored
329
                };
zhangxiaoru authored
330 331 332 333

                // Remove an item from the queue
                $data.removeQueueItem = function(file, instant, delay) {
                    // Set the default delay
ccbikai(👎🏻🍜) authored
334 335 336
                    if (!delay) {
                        delay = 0;
                    }
lijing authored
337
                    let fadeTime = instant ? 0 : 500;
ccbikai(👎🏻🍜) authored
338
zhangxiaoru authored
339 340 341 342 343 344
                    if (file.queueItem) {
                        if (file.queueItem.find('.fileinfo').html() != ' - Completed') {
                            file.queueItem.find('.fileinfo').html(' - Cancelled');
                        }
                        file.queueItem.find('.progress-bar').width(0);
                        file.queueItem.delay(delay).fadeOut(fadeTime, function() {
zhangxiaoru authored
345
                            $(this).remove();
zhangxiaoru authored
346 347 348 349
                        });
                        delete file.queueItem;
                        $data.queue.count--;
                    }
zhangxiaoru authored
350
                };
zhangxiaoru authored
351 352 353

                // Count the number of files that need to be uploaded
                $data.filesToUpload = function() {
lijing authored
354
                    let filesToUpload = 0;
ccbikai(👎🏻🍜) authored
355
lijing authored
356 357 358
                    for (let key in $data.inputs) {
                        let input = $data.inputs[key];
                        let limit = input.files.length;
ccbikai(👎🏻🍜) authored
359
lijing authored
360 361
                        for (let n = 0; n < limit; n++) {
                            let file = input.files[n];
ccbikai(👎🏻🍜) authored
362
zhangxiaoru authored
363 364 365 366 367 368
                            if (!file.skip && !file.complete) {
                                filesToUpload++;
                            }
                        }
                    }
                    return filesToUpload;
zhangxiaoru authored
369
                };
zhangxiaoru authored
370 371 372 373 374 375

                // Check if a file exists
                $data.checkExists = function(file) {
                    if ($.inArray('onCheck', settings.overrideEvents) < 0) {
                        // This request needs to be synchronous
                        $.ajaxSetup({
沈志敏 authored
376
                            async: false
zhangxiaoru authored
377
                        });
zhangxiaoru authored
378
zhangxiaoru authored
379
                        // Send the filename to the check script
lijing authored
380
                        let checkData = $.extend(settings.formData, {filename: file.name});
ccbikai(👎🏻🍜) authored
381
zhangxiaoru authored
382 383 384 385 386 387 388 389 390 391 392
                        $.post(settings.checkScript, checkData, function(fileExists) {
                            file.exists = parseInt(fileExists);
                        });
                        if (file.exists) {
                            if (!confirm('A file named ' + file.name + ' already exists in the upload folder.\nWould you like to replace it?')) {
                                // If not replacing the file, cancel the upload
                                methods.cancel.call($this, file);
                                return true;
                            }
                        }
                    }
zhangxiaoru authored
393
zhangxiaoru authored
394 395 396 397 398
                    // Trigger the check event
                    if (typeof settings.onCheck === 'function') {
                        settings.onCheck.call($this, file, file.exists);
                    }
                    return false;
zhangxiaoru authored
399
                };
zhangxiaoru authored
400 401 402 403 404 405 406 407 408

                // Upload a single file
                $data.uploadFile = function(file, uploadAll) {
                    if (!file.skip && !file.complete && !file.uploading) {
                        file.uploading = true;
                        $data.uploads.current++;
                        $data.uploads.attempted++;

                        // Create a new AJAX request
lijing authored
409
                        let xhr = file.xhr = new XMLHttpRequest();
zhangxiaoru authored
410 411 412 413 414 415

                        // Start the upload
                        // Use the faster FormData if it exists
                        if (typeof FormData === 'function' || typeof FormData === 'object') {

                            // Create a new FormData object
lijing authored
416
                            let formData = new FormData();
zhangxiaoru authored
417 418 419 420 421

                            // Add the form data
                            formData.append(settings.fileObjName, file);

                            // Add the rest of the formData
lijing authored
422
                            for (let i in settings.formData) {
zhangxiaoru authored
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
                                formData.append(i, settings.formData[i]);
                            }

                            // Open the AJAX call
                            xhr.open(settings.method, settings.uploadScript, true);

                            // On progress function
                            xhr.upload.addEventListener('progress', function(e) {
                                if (e.lengthComputable) {
                                    $data.progress(e, file);
                                }
                            }, false);

                            // On complete function
                            xhr.addEventListener('load', function(e) {
                                if (this.readyState == 4) {
                                    file.uploading = false;
                                    if (this.status == 200) {
                                        if (file.xhr.responseText !== 'Invalid file type.') {
                                            $data.uploadComplete(e, file, uploadAll);
                                        } else {
                                            $data.error(file.xhr.responseText, file, uploadAll);
                                        }
                                    } else if (this.status == 404) {
                                        $data.error('404_FILE_NOT_FOUND', file, uploadAll);
                                    } else if (this.status == 403) {
                                        $data.error('403_FORBIDDEN', file, uploadAll);
                                    } else {
                                        $data.error('Unknown Error', file, uploadAll);
                                    }
                                }
                            });

                            // Send the form data (multipart/form-data)
                            xhr.send(formData);

                        } else {

                            // Send as binary
lijing authored
462
                            let reader = new FileReader();
ccbikai(👎🏻🍜) authored
463
zhangxiaoru authored
464 465 466
                            reader.onload = function(e) {

                                // Set some file builder variables
lijing authored
467
                                let boundary = '-------------------------' + (new Date()).getTime(),
zhangxiaoru authored
468 469 470
                                    dashes = '--',
                                    eol = '\r\n',
                                    binFile = '';
zhangxiaoru authored
471
zhangxiaoru authored
472
                                // Build an RFC2388 String
zhangxiaoru authored
473
                                binFile += dashes + boundary + eol;
zhangxiaoru authored
474
zhangxiaoru authored
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
                                // Generate the headers
                                binFile += 'Content-Disposition: form-data; name="' + settings.fileObjName + '"';
                                if (file.name) {
                                    binFile += '; filename="' + file.name + '"';
                                }
                                binFile += eol;
                                binFile += 'Content-Type: application/octet-stream' + eol + eol;
                                binFile += e.target.result + eol;

                                for (key in settings.formData) {
                                    binFile += dashes + boundary + eol;
                                    binFile += 'Content-Disposition: form-data; name="' + key + '"' + eol + eol;
                                    binFile += settings.formData[key] + eol;
                                }

                                binFile += dashes + boundary + dashes + eol;

                                // On progress function
                                xhr.upload.addEventListener('progress', function(e) {
                                    $data.progress(e, file);
                                }, false);

                                // On complete function
                                xhr.addEventListener('load', function(e) {
                                    file.uploading = false;
lijing authored
500
                                    let status = this.status;
ccbikai(👎🏻🍜) authored
501
zhangxiaoru authored
502 503 504
                                    if (status == 404) {
                                        $data.error('404_FILE_NOT_FOUND', file, uploadAll);
                                    } else {
zhangxiaoru authored
505
                                        if (file.xhr.responseText != 'Invalid file type.') {
zhangxiaoru authored
506 507 508
                                            $data.uploadComplete(e, file, uploadAll);
                                        } else {
                                            $data.error(file.xhr.responseText, file, uploadAll);
zhangxiaoru authored
509
                                        }
zhangxiaoru authored
510 511 512 513
                                    }
                                }, false);

                                // Open the ajax request
lijing authored
514
                                let url = settings.uploadScript;
ccbikai(👎🏻🍜) authored
515
zhangxiaoru authored
516
                                if (settings.method == 'get') {
lijing authored
517
                                    let params = $(settings.formData).param();
ccbikai(👎🏻🍜) authored
518
zhangxiaoru authored
519 520 521
                                    url += params;
                                }
                                xhr.open(settings.method, settings.uploadScript, true);
zhangxiaoru authored
522
                                xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
zhangxiaoru authored
523 524 525 526 527 528 529 530

                                // Trigger the uploadFile event
                                if (typeof settings.onUploadFile === 'function') {
                                    settings.onUploadFile.call($this, file);
                                }

                                // Send the file for upload
                                xhr.sendAsBinary(binFile);
zhangxiaoru authored
531
                            };
zhangxiaoru authored
532 533 534 535
                            reader.readAsBinaryString(file);

                        }
                    }
zhangxiaoru authored
536
                };
zhangxiaoru authored
537 538 539 540 541

                // Update a file upload's progress
                $data.progress = function(e, file) {
                    if ($.inArray('onProgress', settings.overrideEvents) < 0) {
                        if (e.lengthComputable) {
lijing authored
542
                            let percent = Math.round((e.loaded / e.total) * 100);
zhangxiaoru authored
543 544 545 546
                        }
                        file.queueItem.find('.fileinfo').html(' - ' + percent + '%');
                        file.queueItem.find('.progress-bar').css('width', percent + '%');
                    }
zhangxiaoru authored
547
zhangxiaoru authored
548 549 550 551
                    // Trigger the progress event
                    if (typeof settings.onProgress === 'function') {
                        settings.onProgress.call($this, file, e);
                    }
zhangxiaoru authored
552
                };
zhangxiaoru authored
553 554 555 556 557

                // Trigger an error
                $data.error = function(errorType, file, uploadAll) {
                    if ($.inArray('onError', settings.overrideEvents) < 0) {
                        // Get the error message
zhangxiaoru authored
558
                        switch (errorType) {
zhangxiaoru authored
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
                            case '404_FILE_NOT_FOUND':
                                errorMsg = '404 Error';
                                break;
                            case '403_FORBIDDEN':
                                errorMsg = '403 Forbidden';
                                break;
                            case 'FORBIDDEN_FILE_TYPE':
                                errorMsg = 'Forbidden File Type';
                                break;
                            case 'FILE_SIZE_LIMIT_EXCEEDED':
                                errorMsg = 'File Too Large';
                                break;
                            default:
                                errorMsg = 'Unknown Error';
                                break;
                        }

                        // Add the error class to the queue item
                        file.queueItem.addClass('error')
zhangxiaoru authored
578
zhangxiaoru authored
579
                        // Output the error in the queue item
zhangxiaoru authored
580 581 582
                            .find('.fileinfo').html(' - ' + errorMsg);

                        // Hide the
zhangxiaoru authored
583 584
                        file.queueItem.find('.progress').remove();
                    }
zhangxiaoru authored
585
zhangxiaoru authored
586 587 588 589 590 591 592 593 594 595 596 597 598
                    // Trigger the error event
                    if (typeof settings.onError === 'function') {
                        settings.onError.call($this, errorType, file);
                    }
                    file.skip = true;
                    if (errorType == '404_FILE_NOT_FOUND') {
                        $data.uploads.errors++;
                    } else {
                        $data.queue.errors++;
                    }
                    if (uploadAll) {
                        methods.upload.call($this, null, true);
                    }
zhangxiaoru authored
599
                };
zhangxiaoru authored
600 601 602 603 604 605 606 607 608

                // Trigger when a single file upload is complete
                $data.uploadComplete = function(e, file, uploadAll) {
                    if ($.inArray('onUploadComplete', settings.overrideEvents) < 0) {
                        file.queueItem.find('.progress-bar').css('width', '100%');
                        file.queueItem.find('.fileinfo').html(' - Completed');
                        file.queueItem.find('.progress').slideUp(250);
                        file.queueItem.addClass('complete');
                    }
zhangxiaoru authored
609
zhangxiaoru authored
610 611 612 613 614
                    // Trigger the complete event
                    if (typeof settings.onUploadComplete === 'function') {
                        settings.onUploadComplete.call($this, file, file.xhr.responseText);
                    }
                    if (settings.removeCompleted) {
ccbikai(👎🏻🍜) authored
615 616 617
                        setTimeout(function() {
                            methods.cancel.call($this, file);
                        }, 3000);
zhangxiaoru authored
618 619 620 621 622 623 624 625 626
                    }
                    file.complete = true;
                    $data.uploads.successful++;
                    $data.uploads.count++;
                    $data.uploads.current--;
                    delete file.xhr;
                    if (uploadAll) {
                        methods.upload.call($this, null, true);
                    }
zhangxiaoru authored
627
                };
zhangxiaoru authored
628 629 630 631 632 633 634

                // Trigger when all the files are done uploading
                $data.queueComplete = function() {
                    // Trigger the queueComplete event
                    if (typeof settings.onQueueComplete === 'function') {
                        settings.onQueueComplete.call($this, $data.uploads);
                    }
zhangxiaoru authored
635
                };
zhangxiaoru authored
636 637 638 639 640 641 642 643 644 645 646 647

                // ----------------------
                // Initialize UploadiFive
                // ----------------------

                // Check if HTML5 is available
                if (window.File && window.FileList && window.Blob && (window.FileReader || window.FormData)) {
                    // Assign an ID to the object
                    settings.id = 'uploadifive-' + $this.attr('id');

                    // Wrap the file input in a div with overflow set to hidden
                    $data.button = $('<div id="' + settings.id + '" class="uploadifive-button">' + settings.buttonText + '</div>');
ccbikai(👎🏻🍜) authored
648 649 650
                    if (settings.buttonClass) {
                        $data.button.addClass(settings.buttonClass);
                    }
zhangxiaoru authored
651 652 653

                    // Style the button wrapper
                    $data.button.css({
沈志敏 authored
654
                        height: settings.height,
zhangxiaoru authored
655
                        'line-height': settings.height + 'px',
沈志敏 authored
656 657
                        overflow: 'hidden',
                        position: 'relative',
zhangxiaoru authored
658
                        'text-align': 'center',
沈志敏 authored
659
                        width: settings.width
zhangxiaoru authored
660 661 662 663
                    });

                    // Insert the button above the file input
                    $this.before($data.button)
zhangxiaoru authored
664
zhangxiaoru authored
665
                    // Add the file input to the button
zhangxiaoru authored
666 667
                        .appendTo($data.button)
zhangxiaoru authored
668
                    // Modify the styles of the file input
zhangxiaoru authored
669
                        .hide();
zhangxiaoru authored
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684

                    // Create a new input
                    $data.createInput.call($this);

                    // Create the queue container
                    if (!settings.queueID) {
                        settings.queueID = settings.id + '-queue';
                        $data.queueEl = $('<div id="' + settings.queueID + '" class="uploadifive-queue" />');
                        $data.button.after($data.queueEl);
                    } else {
                        $data.queueEl = $('#' + settings.queueID);
                    }

                    // Add drag and drop functionality
                    if (settings.dnd) {
lijing authored
685
                        let $dropTarget = settings.dropTarget ? $(settings.dropTarget) : $data.queueEl.get(0);
ccbikai(👎🏻🍜) authored
686
zhangxiaoru authored
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710
                        $dropTarget.addEventListener('dragleave', function(e) {
                            // Stop FireFox from opening the dropped file(s)
                            e.preventDefault();
                            e.stopPropagation();
                        }, false);
                        $dropTarget.addEventListener('dragenter', function(e) {
                            // Stop FireFox from opening the dropped file(s)
                            e.preventDefault();
                            e.stopPropagation();
                        }, false);
                        $dropTarget.addEventListener('dragover', function(e) {
                            // Stop FireFox from opening the dropped file(s)
                            e.preventDefault();
                            e.stopPropagation();
                        }, false);
                        $dropTarget.addEventListener('drop', $data.drop, false);
                    }

                    // Send as binary workaround for Chrome
                    if (!XMLHttpRequest.prototype.sendAsBinary) {
                        XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
                            function byteValue(x) {
                                return x.charCodeAt(0) & 0xff;
                            }
lijing authored
711 712
                            let ords = Array.prototype.map.call(datastr, byteValue);
                            let ui8a = new Uint8Array(ords);
ccbikai(👎🏻🍜) authored
713
zhangxiaoru authored
714
                            this.send(ui8a.buffer);
zhangxiaoru authored
715
                        };
zhangxiaoru authored
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
                    }

                    // Trigger the oninit event
                    if (typeof settings.onInit === 'function') {
                        settings.onInit.call($this);
                    }

                } else {

                    // Trigger the fallback event
                    if (typeof settings.onFallback === 'function') {
                        settings.onFallback.call($this);
                    }
                    return false;

                }

            });

        },


        // Write some data to the console
zhangxiaoru authored
739
        debug: function() {
zhangxiaoru authored
740 741 742 743 744 745 746 747 748 749

            return this.each(function() {

                console.log($(this).data('uploadifive'));

            });

        },

        // Clear all the items from the queue
zhangxiaoru authored
750
        clearQueue: function() {
zhangxiaoru authored
751 752 753

            this.each(function() {
lijing authored
754
                let $this = $(this),
zhangxiaoru authored
755
                    $data = $this.data('uploadifive'),
zhangxiaoru authored
756 757
                    settings = $data.settings;
lijing authored
758
                for (let key in $data.inputs) {
zhangxiaoru authored
759 760 761 762 763 764 765
                    input = $data.inputs[key];
                    limit = input.files.length;
                    for (i = 0; i < limit; i++) {
                        file = input.files[i];
                        methods.cancel.call($this, file);
                    }
                }
zhangxiaoru authored
766
zhangxiaoru authored
767 768 769 770 771 772 773 774 775 776
                // Trigger the onClearQueue event
                if (typeof settings.onClearQueue === 'function') {
                    settings.onClearQueue.call($this, $('#' + $data.settings.queueID));
                }

            });

        },

        // Cancel a file upload in progress or remove a file from the queue
zhangxiaoru authored
777
        cancel: function(file, fast) {
zhangxiaoru authored
778 779 780

            this.each(function() {
lijing authored
781
                let $this = $(this),
zhangxiaoru authored
782
                    $data = $this.data('uploadifive'),
zhangxiaoru authored
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
                    settings = $data.settings;

                // If user passed a queue item ID instead of file...
                if (typeof file === 'string') {
                    if (!isNaN(file)) {
                        fileID = 'uploadifive-' + $(this).attr('id') + '-file-' + file;
                    }
                    file = $('#' + fileID).data('file');
                }

                file.skip = true;
                $data.filesCancelled++;
                if (file.uploading) {
                    $data.uploads.current--;
                    file.uploading = false;
                    file.xhr.abort();
                    delete file.xhr;
                    methods.upload.call($this);
                }
                if ($.inArray('onCancel', settings.overrideEvents) < 0) {
                    $data.removeQueueItem(file, fast);
                }

                // Trigger the cancel event
                if (typeof settings.onCancel === 'function') {
                    settings.onCancel.call($this, file);
                }
zhangxiaoru authored
810
zhangxiaoru authored
811
            });
zhangxiaoru authored
812
zhangxiaoru authored
813 814 815
        },

        // Upload the files in the queue
zhangxiaoru authored
816
        upload: function(file, keepVars) {
zhangxiaoru authored
817 818 819

            this.each(function() {
lijing authored
820
                let $this = $(this),
zhangxiaoru authored
821
                    $data = $this.data('uploadifive'),
zhangxiaoru authored
822 823 824 825 826 827 828 829 830 831 832
                    settings = $data.settings;

                if (file) {

                    $data.uploadFile.call($this, file);

                } else {

                    // Check if the upload limit was reached
                    if (($data.uploads.count + $data.uploads.current) < settings.uploadLimit || settings.uploadLimit == 0) {
                        if (!keepVars) {
zhangxiaoru authored
833
                            $data.uploads.attempted = 0;
zhangxiaoru authored
834
                            $data.uploads.successsful = 0;
zhangxiaoru authored
835
                            $data.uploads.errors = 0;
lijing authored
836
                            let filesToUpload = $data.filesToUpload();
zhangxiaoru authored
837
zhangxiaoru authored
838 839 840 841 842 843 844 845
                            // Trigger the onUpload event
                            if (typeof settings.onUpload === 'function') {
                                settings.onUpload.call($this, filesToUpload);
                            }
                        }

                        // Loop through the files
                        $('#' + settings.queueID).find('.uploadifive-queue-item').not('.error, .complete').each(function() {
lijing authored
846
                            let _file = $(this).data('file');
zhangxiaoru authored
847
zhangxiaoru authored
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873
                            // Check if the simUpload limit was reached
                            if (($data.uploads.current >= settings.simUploadLimit && settings.simUploadLimit !== 0) || ($data.uploads.current >= settings.uploadLimit && settings.uploadLimit !== 0) || ($data.uploads.count >= settings.uploadLimit && settings.uploadLimit !== 0)) {
                                return false;
                            }
                            if (settings.checkScript) {
                                // Let the loop know that we're already processing this file
                                _file.checking = true;
                                skipFile = $data.checkExists(_file);
                                _file.checking = false;
                                if (!skipFile) {
                                    $data.uploadFile(_file, true);
                                }
                            } else {
                                $data.uploadFile(_file, true);
                            }
                        });
                        if ($('#' + settings.queueID).find('.uploadifive-queue-item').not('.error, .complete').size() == 0) {
                            $data.queueComplete();
                        }
                    } else {
                        if ($data.uploads.current == 0) {
                            if ($.inArray('onError', settings.overrideEvents) < 0) {
                                if ($data.filesToUpload() > 0 && settings.uploadLimit != 0) {
                                    alert('The maximum upload limit has been reached.');
                                }
                            }
zhangxiaoru authored
874
zhangxiaoru authored
875 876 877 878 879 880 881 882 883 884 885 886 887 888
                            // Trigger the onError event
                            if (typeof settings.onError === 'function') {
                                settings.onError.call($this, 'UPLOAD_LIMIT_EXCEEDED', $data.filesToUpload());
                            }
                        }
                    }

                }

            });

        },

        // Destroy an instance of UploadiFive
zhangxiaoru authored
889
        destroy: function() {
zhangxiaoru authored
890 891 892

            this.each(function() {
lijing authored
893
                let $this = $(this),
zhangxiaoru authored
894
                    $data = $this.data('uploadifive'),
zhangxiaoru authored
895
                    settings = $data.settings;
zhangxiaoru authored
896
zhangxiaoru authored
897 898
                // Clear the queue
                methods.clearQueue.call($this);
zhangxiaoru authored
899
zhangxiaoru authored
900
                // Destroy the queue if it was created
ccbikai(👎🏻🍜) authored
901 902 903
                if (!settings.queueID) {
                    $('#' + settings.queueID).remove();
                }
zhangxiaoru authored
904
zhangxiaoru authored
905 906
                // Remove extra inputs
                $this.siblings('input').remove();
zhangxiaoru authored
907
zhangxiaoru authored
908 909
                // Show the original file input
                $this.show()
zhangxiaoru authored
910
zhangxiaoru authored
911
                // Move the file input out of the button
zhangxiaoru authored
912 913
                    .insertBefore($data.button);
zhangxiaoru authored
914 915
                // Delete the button
                $data.button.remove();
zhangxiaoru authored
916
zhangxiaoru authored
917 918 919 920 921 922 923 924 925
                // Trigger the destroy event
                if (typeof settings.onDestroy === 'function') {
                    settings.onDestroy.call($this);
                }

            });

        }
zhangxiaoru authored
926
    };
zhangxiaoru authored
927 928 929 930 931 932 933 934 935 936 937

    $.fn.upload = function(method) {

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('The method ' + method + ' does not exist in $.uploadify');
        }
zhangxiaoru authored
938
    };
zhangxiaoru authored
939
zhangxiaoru authored
940
}(jQuery));