jquery-fileupload-rails 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +7 -4
- data/lib/jquery/fileupload/rails/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js +18 -17
- data/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js +72 -77
- data/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js +179 -143
- data/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js +363 -117
- metadata +3 -3
    
        data/README.md
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # jQuery File Upload for Rails | 
| 1 | 
            +
            # jQuery File Upload for Rails
         | 
| 2 2 |  | 
| 3 3 | 
             
            [jQuery-File-Plugin](https://github.com/blueimp/jQuery-File-Upload) is a file upload plugin written by [Sebastian Tschan](https://github.com/blueimp). jQuery File Upload features multiple file selection, drag&drop support, progress bars and preview images for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing.
         | 
| 4 4 |  | 
| @@ -6,9 +6,9 @@ jquery-fileupload-rails is a library that integrates jQuery File Upload for Rail | |
| 6 6 |  | 
| 7 7 | 
             
            ## Plugin versions
         | 
| 8 8 |  | 
| 9 | 
            -
            * jQuery File Upload User Interface Plugin 6. | 
| 10 | 
            -
            * jQuery File Upload Plugin 5. | 
| 11 | 
            -
            * jQuery UI Widget 1. | 
| 9 | 
            +
            * jQuery File Upload User Interface Plugin 6.11
         | 
| 10 | 
            +
            * jQuery File Upload Plugin 5.19.2
         | 
| 11 | 
            +
            * jQuery UI Widget 1.9.1+amd
         | 
| 12 12 |  | 
| 13 13 | 
             
            ## Installing Gem
         | 
| 14 14 |  | 
| @@ -51,6 +51,9 @@ Require the stylesheet file to app/assets/stylesheets/application.css | |
| 51 51 | 
             
            ## [Example app](https://github.com/tors/jquery-fileupload-rails-paperclip-example)
         | 
| 52 52 | 
             
            This app uses paperclip and twitter-bootstrap-rails
         | 
| 53 53 |  | 
| 54 | 
            +
            You can also check out Ryan Bate's RailsCast [jQuery File Upload episode](http://railscasts.com/episodes/381-jquery-file-upload). You will
         | 
| 55 | 
            +
            need a pro account to watch it though.
         | 
| 56 | 
            +
             | 
| 54 57 |  | 
| 55 58 | 
             
            ## Thanks
         | 
| 56 59 | 
             
            Thanks to [Sebastian Tschan](https://github.com/blueimp) for writing an awesome file upload plugin.
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            /*
         | 
| 2 | 
            -
             * jQuery File Upload File Processing Plugin 1. | 
| 2 | 
            +
             * jQuery File Upload File Processing Plugin 1.2
         | 
| 3 3 | 
             
             * https://github.com/blueimp/jQuery-File-Upload
         | 
| 4 4 | 
             
             *
         | 
| 5 5 | 
             
             * Copyright 2012, Sebastian Tschan
         | 
| @@ -32,9 +32,9 @@ | |
| 32 32 | 
             
            }(function ($, loadImage) {
         | 
| 33 33 | 
             
                'use strict';
         | 
| 34 34 |  | 
| 35 | 
            -
                // The File Upload  | 
| 35 | 
            +
                // The File Upload FP version extends the fileupload widget
         | 
| 36 36 | 
             
                // with file processing functionality:
         | 
| 37 | 
            -
                $.widget(' | 
| 37 | 
            +
                $.widget('blueimp.fileupload', $.blueimp.fileupload, {
         | 
| 38 38 |  | 
| 39 39 | 
             
                    options: {
         | 
| 40 40 | 
             
                        // The list of file processing actions:
         | 
| @@ -70,7 +70,7 @@ | |
| 70 70 |  | 
| 71 71 | 
             
                    processActions: {
         | 
| 72 72 | 
             
                        // Loads the image given via data.files and data.index
         | 
| 73 | 
            -
                        // as  | 
| 73 | 
            +
                        // as img element if the browser supports canvas.
         | 
| 74 74 | 
             
                        // Accepts the options fileTypes (regular expression)
         | 
| 75 75 | 
             
                        // and maxFileSize (integer) to limit the files to load:
         | 
| 76 76 | 
             
                        load: function (data, options) {
         | 
| @@ -85,28 +85,29 @@ | |
| 85 85 | 
             
                                        options.fileTypes.test(file.type))) {
         | 
| 86 86 | 
             
                                loadImage(
         | 
| 87 87 | 
             
                                    file,
         | 
| 88 | 
            -
                                    function ( | 
| 89 | 
            -
                                        data. | 
| 88 | 
            +
                                    function (img) {
         | 
| 89 | 
            +
                                        data.img = img;
         | 
| 90 90 | 
             
                                        dfd.resolveWith(that, [data]);
         | 
| 91 | 
            -
                                    } | 
| 92 | 
            -
                                    {canvas: true}
         | 
| 91 | 
            +
                                    }
         | 
| 93 92 | 
             
                                );
         | 
| 94 93 | 
             
                            } else {
         | 
| 95 94 | 
             
                                dfd.rejectWith(that, [data]);
         | 
| 96 95 | 
             
                            }
         | 
| 97 96 | 
             
                            return dfd.promise();
         | 
| 98 97 | 
             
                        },
         | 
| 99 | 
            -
                        // Resizes the image given as data. | 
| 100 | 
            -
                        // data.canvas with the resized image.
         | 
| 98 | 
            +
                        // Resizes the image given as data.img and updates
         | 
| 99 | 
            +
                        // data.canvas with the resized image as canvas element.
         | 
| 101 100 | 
             
                        // Accepts the options maxWidth, maxHeight, minWidth and
         | 
| 102 101 | 
             
                        // minHeight to scale the given image:
         | 
| 103 102 | 
             
                        resize: function (data, options) {
         | 
| 104 | 
            -
                             | 
| 105 | 
            -
                                 | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 103 | 
            +
                            var img = data.img,
         | 
| 104 | 
            +
                                canvas;
         | 
| 105 | 
            +
                            options = $.extend({canvas: true}, options);
         | 
| 106 | 
            +
                            if (img) {
         | 
| 107 | 
            +
                                canvas = loadImage.scale(img, options);
         | 
| 108 | 
            +
                                if (canvas.width !== img.width ||
         | 
| 109 | 
            +
                                        canvas.height !== img.height) {
         | 
| 108 110 | 
             
                                    data.canvas = canvas;
         | 
| 109 | 
            -
                                    data.processed = true;
         | 
| 110 111 | 
             
                                }
         | 
| 111 112 | 
             
                            }
         | 
| 112 113 | 
             
                            return data;
         | 
| @@ -115,7 +116,7 @@ | |
| 115 116 | 
             
                        // inplace at data.index of data.files:
         | 
| 116 117 | 
             
                        save: function (data, options) {
         | 
| 117 118 | 
             
                            // Do nothing if no processing has happened:
         | 
| 118 | 
            -
                            if (!data.canvas | 
| 119 | 
            +
                            if (!data.canvas) {
         | 
| 119 120 | 
             
                                return data;
         | 
| 120 121 | 
             
                            }
         | 
| 121 122 | 
             
                            var that = this,
         | 
| @@ -208,7 +209,7 @@ | |
| 208 209 | 
             
                    },
         | 
| 209 210 |  | 
| 210 211 | 
             
                    _create: function () {
         | 
| 211 | 
            -
                         | 
| 212 | 
            +
                        this._super();
         | 
| 212 213 | 
             
                        this._processing = 0;
         | 
| 213 214 | 
             
                        this._processingQueue = $.Deferred().resolveWith(this)
         | 
| 214 215 | 
             
                            .promise();
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            /*
         | 
| 2 | 
            -
             * jQuery File Upload User Interface Plugin 6. | 
| 2 | 
            +
             * jQuery File Upload User Interface Plugin 6.11
         | 
| 3 3 | 
             
             * https://github.com/blueimp/jQuery-File-Upload
         | 
| 4 4 | 
             
             *
         | 
| 5 5 | 
             
             * Copyright 2010, Sebastian Tschan
         | 
| @@ -10,7 +10,7 @@ | |
| 10 10 | 
             
             */
         | 
| 11 11 |  | 
| 12 12 | 
             
            /*jslint nomen: true, unparam: true, regexp: true */
         | 
| 13 | 
            -
            /*global define, window,  | 
| 13 | 
            +
            /*global define, window, URL, webkitURL, FileReader */
         | 
| 14 14 |  | 
| 15 15 | 
             
            (function (factory) {
         | 
| 16 16 | 
             
                'use strict';
         | 
| @@ -33,10 +33,9 @@ | |
| 33 33 | 
             
            }(function ($, tmpl, loadImage) {
         | 
| 34 34 | 
             
                'use strict';
         | 
| 35 35 |  | 
| 36 | 
            -
                // The UI version extends the  | 
| 37 | 
            -
                //  | 
| 38 | 
            -
                 | 
| 39 | 
            -
                $.widget('blueimpUI.fileupload', parentWidget, {
         | 
| 36 | 
            +
                // The UI version extends the file upload widget
         | 
| 37 | 
            +
                // and adds complete user interface interaction:
         | 
| 38 | 
            +
                $.widget('blueimp.fileupload', $.blueimp.fileupload, {
         | 
| 40 39 |  | 
| 41 40 | 
             
                    options: {
         | 
| 42 41 | 
             
                        // By default, files added to the widget are uploaded as soon
         | 
| @@ -144,7 +143,8 @@ | |
| 144 143 | 
             
                            if (data.context) {
         | 
| 145 144 | 
             
                                data.context.each(function (index) {
         | 
| 146 145 | 
             
                                    var file = ($.isArray(data.result) &&
         | 
| 147 | 
            -
                                            data.result[index]) || | 
| 146 | 
            +
                                            data.result[index]) ||
         | 
| 147 | 
            +
                                                {error: 'Empty file upload result'};
         | 
| 148 148 | 
             
                                    if (file.error) {
         | 
| 149 149 | 
             
                                        that._adjustMaxNumberOfFiles(1);
         | 
| 150 150 | 
             
                                    }
         | 
| @@ -398,22 +398,22 @@ | |
| 398 398 | 
             
                        // maxNumberOfFiles before validation, so we check if
         | 
| 399 399 | 
             
                        // maxNumberOfFiles is below 0 (instead of below 1):
         | 
| 400 400 | 
             
                        if (this.options.maxNumberOfFiles < 0) {
         | 
| 401 | 
            -
                            return ' | 
| 401 | 
            +
                            return 'Maximum number of files exceeded';
         | 
| 402 402 | 
             
                        }
         | 
| 403 403 | 
             
                        // Files are accepted if either the file type or the file name
         | 
| 404 404 | 
             
                        // matches against the acceptFileTypes regular expression, as
         | 
| 405 405 | 
             
                        // only browsers with support for the File API report the type:
         | 
| 406 406 | 
             
                        if (!(this.options.acceptFileTypes.test(file.type) ||
         | 
| 407 407 | 
             
                                this.options.acceptFileTypes.test(file.name))) {
         | 
| 408 | 
            -
                            return ' | 
| 408 | 
            +
                            return 'Filetype not allowed';
         | 
| 409 409 | 
             
                        }
         | 
| 410 410 | 
             
                        if (this.options.maxFileSize &&
         | 
| 411 411 | 
             
                                file.size > this.options.maxFileSize) {
         | 
| 412 | 
            -
                            return ' | 
| 412 | 
            +
                            return 'File is too big';
         | 
| 413 413 | 
             
                        }
         | 
| 414 414 | 
             
                        if (typeof file.size === 'number' &&
         | 
| 415 415 | 
             
                                file.size < this.options.minFileSize) {
         | 
| 416 | 
            -
                            return ' | 
| 416 | 
            +
                            return 'File is too small';
         | 
| 417 417 | 
             
                        }
         | 
| 418 418 | 
             
                        return null;
         | 
| 419 419 | 
             
                    },
         | 
| @@ -457,7 +457,7 @@ | |
| 457 457 | 
             
                                that._transition(node).done(function () {
         | 
| 458 458 | 
             
                                    dfd.resolveWith(node);
         | 
| 459 459 | 
             
                                });
         | 
| 460 | 
            -
                                if (!$.contains(document.body, node[0])) {
         | 
| 460 | 
            +
                                if (!$.contains(that.document[0].body, node[0])) {
         | 
| 461 461 | 
             
                                    // If the element is not part of the DOM,
         | 
| 462 462 | 
             
                                    // transition events are not triggered,
         | 
| 463 463 | 
             
                                    // so we have to resolve manually:
         | 
| @@ -510,7 +510,7 @@ | |
| 510 510 |  | 
| 511 511 | 
             
                    _startHandler: function (e) {
         | 
| 512 512 | 
             
                        e.preventDefault();
         | 
| 513 | 
            -
                        var button = $( | 
| 513 | 
            +
                        var button = $(e.currentTarget),
         | 
| 514 514 | 
             
                            template = button.closest('.template-upload'),
         | 
| 515 515 | 
             
                            data = template.data('data');
         | 
| 516 516 | 
             
                        if (data && data.submit && !data.jqXHR && data.submit()) {
         | 
| @@ -520,11 +520,11 @@ | |
| 520 520 |  | 
| 521 521 | 
             
                    _cancelHandler: function (e) {
         | 
| 522 522 | 
             
                        e.preventDefault();
         | 
| 523 | 
            -
                        var template = $( | 
| 523 | 
            +
                        var template = $(e.currentTarget).closest('.template-upload'),
         | 
| 524 524 | 
             
                            data = template.data('data') || {};
         | 
| 525 525 | 
             
                        if (!data.jqXHR) {
         | 
| 526 526 | 
             
                            data.errorThrown = 'abort';
         | 
| 527 | 
            -
                             | 
| 527 | 
            +
                            this._trigger('fail', e, data);
         | 
| 528 528 | 
             
                        } else {
         | 
| 529 529 | 
             
                            data.jqXHR.abort();
         | 
| 530 530 | 
             
                        }
         | 
| @@ -532,13 +532,12 @@ | |
| 532 532 |  | 
| 533 533 | 
             
                    _deleteHandler: function (e) {
         | 
| 534 534 | 
             
                        e.preventDefault();
         | 
| 535 | 
            -
                        var button = $( | 
| 536 | 
            -
                         | 
| 535 | 
            +
                        var button = $(e.currentTarget);
         | 
| 536 | 
            +
                        this._trigger('destroy', e, $.extend({
         | 
| 537 537 | 
             
                            context: button.closest('.template-download'),
         | 
| 538 | 
            -
                             | 
| 539 | 
            -
                             | 
| 540 | 
            -
             | 
| 541 | 
            -
                        });
         | 
| 538 | 
            +
                            type: 'DELETE',
         | 
| 539 | 
            +
                            dataType: this.options.dataType
         | 
| 540 | 
            +
                        }, button.data()));
         | 
| 542 541 | 
             
                    },
         | 
| 543 542 |  | 
| 544 543 | 
             
                    _forceReflow: function (node) {
         | 
| @@ -569,75 +568,63 @@ | |
| 569 568 |  | 
| 570 569 | 
             
                    _initButtonBarEventHandlers: function () {
         | 
| 571 570 | 
             
                        var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
         | 
| 572 | 
            -
                            filesList = this.options.filesContainer | 
| 573 | 
            -
             | 
| 574 | 
            -
             | 
| 575 | 
            -
                            .bind('click.' + ns, function (e) {
         | 
| 571 | 
            +
                            filesList = this.options.filesContainer;
         | 
| 572 | 
            +
                        this._on(fileUploadButtonBar.find('.start'), {
         | 
| 573 | 
            +
                            click: function (e) {
         | 
| 576 574 | 
             
                                e.preventDefault();
         | 
| 577 575 | 
             
                                filesList.find('.start button').click();
         | 
| 578 | 
            -
                            } | 
| 579 | 
            -
                         | 
| 580 | 
            -
             | 
| 576 | 
            +
                            }
         | 
| 577 | 
            +
                        });
         | 
| 578 | 
            +
                        this._on(fileUploadButtonBar.find('.cancel'), {
         | 
| 579 | 
            +
                            click: function (e) {
         | 
| 581 580 | 
             
                                e.preventDefault();
         | 
| 582 581 | 
             
                                filesList.find('.cancel button').click();
         | 
| 583 | 
            -
                            } | 
| 584 | 
            -
                         | 
| 585 | 
            -
             | 
| 582 | 
            +
                            }
         | 
| 583 | 
            +
                        });
         | 
| 584 | 
            +
                        this._on(fileUploadButtonBar.find('.delete'), {
         | 
| 585 | 
            +
                            click: function (e) {
         | 
| 586 586 | 
             
                                e.preventDefault();
         | 
| 587 587 | 
             
                                filesList.find('.delete input:checked')
         | 
| 588 588 | 
             
                                    .siblings('button').click();
         | 
| 589 589 | 
             
                                fileUploadButtonBar.find('.toggle')
         | 
| 590 590 | 
             
                                    .prop('checked', false);
         | 
| 591 | 
            -
                            } | 
| 592 | 
            -
                         | 
| 593 | 
            -
             | 
| 591 | 
            +
                            }
         | 
| 592 | 
            +
                        });
         | 
| 593 | 
            +
                        this._on(fileUploadButtonBar.find('.toggle'), {
         | 
| 594 | 
            +
                            change: function (e) {
         | 
| 594 595 | 
             
                                filesList.find('.delete input').prop(
         | 
| 595 596 | 
             
                                    'checked',
         | 
| 596 | 
            -
                                    $( | 
| 597 | 
            +
                                    $(e.currentTarget).is(':checked')
         | 
| 597 598 | 
             
                                );
         | 
| 598 | 
            -
                            } | 
| 599 | 
            +
                            }
         | 
| 600 | 
            +
                        });
         | 
| 599 601 | 
             
                    },
         | 
| 600 602 |  | 
| 601 603 | 
             
                    _destroyButtonBarEventHandlers: function () {
         | 
| 602 | 
            -
                        this. | 
| 603 | 
            -
                            . | 
| 604 | 
            -
             | 
| 605 | 
            -
             | 
| 604 | 
            +
                        this._off(
         | 
| 605 | 
            +
                            this.element.find('.fileupload-buttonbar button'),
         | 
| 606 | 
            +
                            'click'
         | 
| 607 | 
            +
                        );
         | 
| 608 | 
            +
                        this._off(
         | 
| 609 | 
            +
                            this.element.find('.fileupload-buttonbar .toggle'),
         | 
| 610 | 
            +
                            'change.'
         | 
| 611 | 
            +
                        );
         | 
| 606 612 | 
             
                    },
         | 
| 607 613 |  | 
| 608 614 | 
             
                    _initEventHandlers: function () {
         | 
| 609 | 
            -
                         | 
| 610 | 
            -
                         | 
| 611 | 
            -
             | 
| 612 | 
            -
                            . | 
| 613 | 
            -
             | 
| 614 | 
            -
             | 
| 615 | 
            -
                                eventData,
         | 
| 616 | 
            -
                                this._startHandler
         | 
| 617 | 
            -
                            )
         | 
| 618 | 
            -
                            .delegate(
         | 
| 619 | 
            -
                                '.cancel button',
         | 
| 620 | 
            -
                                'click.' + this.options.namespace,
         | 
| 621 | 
            -
                                eventData,
         | 
| 622 | 
            -
                                this._cancelHandler
         | 
| 623 | 
            -
                            )
         | 
| 624 | 
            -
                            .delegate(
         | 
| 625 | 
            -
                                '.delete button',
         | 
| 626 | 
            -
                                'click.' + this.options.namespace,
         | 
| 627 | 
            -
                                eventData,
         | 
| 628 | 
            -
                                this._deleteHandler
         | 
| 629 | 
            -
                            );
         | 
| 615 | 
            +
                        this._super();
         | 
| 616 | 
            +
                        this._on(this.options.filesContainer, {
         | 
| 617 | 
            +
                            'click .start button': this._startHandler,
         | 
| 618 | 
            +
                            'click .cancel button': this._cancelHandler,
         | 
| 619 | 
            +
                            'click .delete button': this._deleteHandler
         | 
| 620 | 
            +
                        });
         | 
| 630 621 | 
             
                        this._initButtonBarEventHandlers();
         | 
| 631 622 | 
             
                    },
         | 
| 632 623 |  | 
| 633 624 | 
             
                    _destroyEventHandlers: function () {
         | 
| 634 | 
            -
                        var options = this.options;
         | 
| 635 625 | 
             
                        this._destroyButtonBarEventHandlers();
         | 
| 636 | 
            -
                        options.filesContainer
         | 
| 637 | 
            -
             | 
| 638 | 
            -
                            .undelegate('.cancel button', 'click.' + options.namespace)
         | 
| 639 | 
            -
                            .undelegate('.delete button', 'click.' + options.namespace);
         | 
| 640 | 
            -
                        parentWidget.prototype._destroyEventHandlers.call(this);
         | 
| 626 | 
            +
                        this._off(this.options.filesContainer, 'click');
         | 
| 627 | 
            +
                        this._super();
         | 
| 641 628 | 
             
                    },
         | 
| 642 629 |  | 
| 643 630 | 
             
                    _enableFileInputButton: function () {
         | 
| @@ -654,7 +641,7 @@ | |
| 654 641 |  | 
| 655 642 | 
             
                    _initTemplates: function () {
         | 
| 656 643 | 
             
                        var options = this.options;
         | 
| 657 | 
            -
                        options.templatesContainer = document.createElement(
         | 
| 644 | 
            +
                        options.templatesContainer = this.document[0].createElement(
         | 
| 658 645 | 
             
                            options.filesContainer.prop('nodeName')
         | 
| 659 646 | 
             
                        );
         | 
| 660 647 | 
             
                        if (tmpl) {
         | 
| @@ -698,20 +685,20 @@ | |
| 698 685 | 
             
                    },
         | 
| 699 686 |  | 
| 700 687 | 
             
                    _initSpecialOptions: function () {
         | 
| 701 | 
            -
                         | 
| 688 | 
            +
                        this._super();
         | 
| 702 689 | 
             
                        this._initFilesContainer();
         | 
| 703 690 | 
             
                        this._initTemplates();
         | 
| 704 691 | 
             
                        this._initRegExpOptions();
         | 
| 705 692 | 
             
                    },
         | 
| 706 693 |  | 
| 707 694 | 
             
                    _create: function () {
         | 
| 708 | 
            -
                         | 
| 695 | 
            +
                        this._super();
         | 
| 709 696 | 
             
                        this._refreshOptionsList.push(
         | 
| 710 697 | 
             
                            'filesContainer',
         | 
| 711 698 | 
             
                            'uploadTemplateId',
         | 
| 712 699 | 
             
                            'downloadTemplateId'
         | 
| 713 700 | 
             
                        );
         | 
| 714 | 
            -
                        if ( | 
| 701 | 
            +
                        if (!this._processingQueue) {
         | 
| 715 702 | 
             
                            this._processingQueue = $.Deferred().resolveWith(this).promise();
         | 
| 716 703 | 
             
                            this.process = function () {
         | 
| 717 704 | 
             
                                return this._processingQueue;
         | 
| @@ -720,15 +707,23 @@ | |
| 720 707 | 
             
                    },
         | 
| 721 708 |  | 
| 722 709 | 
             
                    enable: function () {
         | 
| 723 | 
            -
                         | 
| 724 | 
            -
                        this. | 
| 725 | 
            -
             | 
| 710 | 
            +
                        var wasDisabled = false;
         | 
| 711 | 
            +
                        if (this.options.disabled) {
         | 
| 712 | 
            +
                            wasDisabled = true;
         | 
| 713 | 
            +
                        }
         | 
| 714 | 
            +
                        this._super();
         | 
| 715 | 
            +
                        if (wasDisabled) {
         | 
| 716 | 
            +
                            this.element.find('input, button').prop('disabled', false);
         | 
| 717 | 
            +
                            this._enableFileInputButton();
         | 
| 718 | 
            +
                        }
         | 
| 726 719 | 
             
                    },
         | 
| 727 720 |  | 
| 728 721 | 
             
                    disable: function () {
         | 
| 729 | 
            -
                        this. | 
| 730 | 
            -
             | 
| 731 | 
            -
             | 
| 722 | 
            +
                        if (!this.options.disabled) {
         | 
| 723 | 
            +
                            this.element.find('input, button').prop('disabled', true);
         | 
| 724 | 
            +
                            this._disableFileInputButton();
         | 
| 725 | 
            +
                        }
         | 
| 726 | 
            +
                        this._super();
         | 
| 732 727 | 
             
                    }
         | 
| 733 728 |  | 
| 734 729 | 
             
                });
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            /*
         | 
| 2 | 
            -
             * jQuery File Upload Plugin 5. | 
| 2 | 
            +
             * jQuery File Upload Plugin 5.19.2
         | 
| 3 3 | 
             
             * https://github.com/blueimp/jQuery-File-Upload
         | 
| 4 4 | 
             
             *
         | 
| 5 5 | 
             
             * Copyright 2010, Sebastian Tschan
         | 
| @@ -44,17 +44,16 @@ | |
| 44 44 | 
             
                $.widget('blueimp.fileupload', {
         | 
| 45 45 |  | 
| 46 46 | 
             
                    options: {
         | 
| 47 | 
            -
                        // The  | 
| 48 | 
            -
                        //  | 
| 49 | 
            -
                        // If not set, the name of the widget ("fileupload") is used.
         | 
| 50 | 
            -
                        namespace: undefined,
         | 
| 51 | 
            -
                        // The drop target collection, by the default the complete document.
         | 
| 52 | 
            -
                        // Set to null or an empty collection to disable drag & drop support:
         | 
| 47 | 
            +
                        // The drop target element(s), by the default the complete document.
         | 
| 48 | 
            +
                        // Set to null to disable drag & drop support:
         | 
| 53 49 | 
             
                        dropZone: $(document),
         | 
| 54 | 
            -
                        // The  | 
| 50 | 
            +
                        // The paste target element(s), by the default the complete document.
         | 
| 51 | 
            +
                        // Set to null to disable paste support:
         | 
| 52 | 
            +
                        pasteZone: $(document),
         | 
| 53 | 
            +
                        // The file input field(s), that are listened to for change events.
         | 
| 55 54 | 
             
                        // If undefined, it is set to the file input fields inside
         | 
| 56 55 | 
             
                        // of the widget element on plugin initialization.
         | 
| 57 | 
            -
                        // Set to null  | 
| 56 | 
            +
                        // Set to null to disable the change listener.
         | 
| 58 57 | 
             
                        fileInput: undefined,
         | 
| 59 58 | 
             
                        // By default, the file input field is replaced with a clone after
         | 
| 60 59 | 
             
                        // each input field change event. This is required for iframe transport
         | 
| @@ -159,13 +158,13 @@ | |
| 159 158 | 
             
                        // start: function (e) {}, // .bind('fileuploadstart', func);
         | 
| 160 159 | 
             
                        // Callback for uploads stop, equivalent to the global ajaxStop event:
         | 
| 161 160 | 
             
                        // stop: function (e) {}, // .bind('fileuploadstop', func);
         | 
| 162 | 
            -
                        // Callback for change events of the fileInput | 
| 161 | 
            +
                        // Callback for change events of the fileInput(s):
         | 
| 163 162 | 
             
                        // change: function (e, data) {}, // .bind('fileuploadchange', func);
         | 
| 164 | 
            -
                        // Callback for paste events to the  | 
| 163 | 
            +
                        // Callback for paste events to the pasteZone(s):
         | 
| 165 164 | 
             
                        // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
         | 
| 166 | 
            -
                        // Callback for drop events of the dropZone | 
| 165 | 
            +
                        // Callback for drop events of the dropZone(s):
         | 
| 167 166 | 
             
                        // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
         | 
| 168 | 
            -
                        // Callback for dragover events of the dropZone | 
| 167 | 
            +
                        // Callback for dragover events of the dropZone(s):
         | 
| 169 168 | 
             
                        // dragover: function (e) {}, // .bind('fileuploaddragover', func);
         | 
| 170 169 |  | 
| 171 170 | 
             
                        // The plugin options are used as settings object for the ajax calls.
         | 
| @@ -177,9 +176,9 @@ | |
| 177 176 |  | 
| 178 177 | 
             
                    // A list of options that require a refresh after assigning a new value:
         | 
| 179 178 | 
             
                    _refreshOptionsList: [
         | 
| 180 | 
            -
                        'namespace',
         | 
| 181 | 
            -
                        'dropZone',
         | 
| 182 179 | 
             
                        'fileInput',
         | 
| 180 | 
            +
                        'dropZone',
         | 
| 181 | 
            +
                        'pasteZone',
         | 
| 183 182 | 
             
                        'multipart',
         | 
| 184 183 | 
             
                        'forceIframeTransport'
         | 
| 185 184 | 
             
                    ],
         | 
| @@ -301,29 +300,16 @@ | |
| 301 300 | 
             
                            // Ignore non-multipart setting if not supported:
         | 
| 302 301 | 
             
                            multipart = options.multipart || !$.support.xhrFileUpload,
         | 
| 303 302 | 
             
                            paramName = options.paramName[0];
         | 
| 304 | 
            -
                         | 
| 305 | 
            -
             | 
| 306 | 
            -
                             | 
| 307 | 
            -
                            // so we transmit this data as part of the HTTP headers.
         | 
| 308 | 
            -
                            // For cross domain requests, these headers must be allowed
         | 
| 309 | 
            -
                            // via Access-Control-Allow-Headers or removed using
         | 
| 310 | 
            -
                            // the beforeSend callback:
         | 
| 311 | 
            -
                            options.headers = $.extend(options.headers, {
         | 
| 312 | 
            -
                                'X-File-Name': file.name,
         | 
| 313 | 
            -
                                'X-File-Type': file.type,
         | 
| 314 | 
            -
                                'X-File-Size': file.size
         | 
| 315 | 
            -
                            });
         | 
| 316 | 
            -
                            if (!options.blob) {
         | 
| 317 | 
            -
                                // Non-chunked non-multipart upload:
         | 
| 318 | 
            -
                                options.contentType = file.type;
         | 
| 319 | 
            -
                                options.data = file;
         | 
| 320 | 
            -
                            } else if (!multipart) {
         | 
| 321 | 
            -
                                // Chunked non-multipart upload:
         | 
| 322 | 
            -
                                options.contentType = 'application/octet-stream';
         | 
| 323 | 
            -
                                options.data = options.blob;
         | 
| 324 | 
            -
                            }
         | 
| 303 | 
            +
                        options.headers = options.headers || {};
         | 
| 304 | 
            +
                        if (options.contentRange) {
         | 
| 305 | 
            +
                            options.headers['Content-Range'] = options.contentRange;
         | 
| 325 306 | 
             
                        }
         | 
| 326 | 
            -
                        if (multipart | 
| 307 | 
            +
                        if (!multipart) {
         | 
| 308 | 
            +
                            options.headers['Content-Disposition'] = 'attachment; filename="' +
         | 
| 309 | 
            +
                                encodeURI(file.name) + '"';
         | 
| 310 | 
            +
                            options.contentType = file.type;
         | 
| 311 | 
            +
                            options.data = options.blob || file;
         | 
| 312 | 
            +
                        } else if ($.support.xhrFormDataFileUpload) {
         | 
| 327 313 | 
             
                            if (options.postMessage) {
         | 
| 328 314 | 
             
                                // window.postMessage does not allow sending FormData
         | 
| 329 315 | 
             
                                // objects, so we just add the File/Blob objects to
         | 
| @@ -353,6 +339,9 @@ | |
| 353 339 | 
             
                                    });
         | 
| 354 340 | 
             
                                }
         | 
| 355 341 | 
             
                                if (options.blob) {
         | 
| 342 | 
            +
                                    options.headers['Content-Disposition'] = 'attachment; filename="' +
         | 
| 343 | 
            +
                                        encodeURI(file.name) + '"';
         | 
| 344 | 
            +
                                    options.headers['Content-Description'] = encodeURI(file.type);
         | 
| 356 345 | 
             
                                    formData.append(paramName, options.blob, file.name);
         | 
| 357 346 | 
             
                                } else {
         | 
| 358 347 | 
             
                                    $.each(options.files, function (index, file) {
         | 
| @@ -436,6 +425,11 @@ | |
| 436 425 | 
             
                        // associated form, if available:
         | 
| 437 426 | 
             
                        if (!options.form || !options.form.length) {
         | 
| 438 427 | 
             
                            options.form = $(options.fileInput.prop('form'));
         | 
| 428 | 
            +
                            // If the given file input doesn't have an associated form,
         | 
| 429 | 
            +
                            // use the default widget file input's form:
         | 
| 430 | 
            +
                            if (!options.form.length) {
         | 
| 431 | 
            +
                                options.form = $(this.options.fileInput.prop('form'));
         | 
| 432 | 
            +
                            }
         | 
| 439 433 | 
             
                        }
         | 
| 440 434 | 
             
                        options.paramName = this._getParamName(options);
         | 
| 441 435 | 
             
                        if (!options.url) {
         | 
| @@ -483,6 +477,16 @@ | |
| 483 477 | 
             
                        return this._enhancePromise(promise);
         | 
| 484 478 | 
             
                    },
         | 
| 485 479 |  | 
| 480 | 
            +
                    // Parses the Range header from the server response
         | 
| 481 | 
            +
                    // and returns the uploaded bytes:
         | 
| 482 | 
            +
                    _getUploadedBytes: function (jqXHR) {
         | 
| 483 | 
            +
                        var range = jqXHR.getResponseHeader('Range'),
         | 
| 484 | 
            +
                            parts = range && range.split('-'),
         | 
| 485 | 
            +
                            upperBytesPos = parts && parts.length > 1 &&
         | 
| 486 | 
            +
                                parseInt(parts[1], 10);
         | 
| 487 | 
            +
                        return upperBytesPos && upperBytesPos + 1;
         | 
| 488 | 
            +
                    },
         | 
| 489 | 
            +
             | 
| 486 490 | 
             
                    // Uploads a file in multiple, sequential requests
         | 
| 487 491 | 
             
                    // by splitting the file up in multiple blob chunks.
         | 
| 488 492 | 
             
                    // If the second parameter is true, only tests if the file
         | 
| @@ -494,13 +498,11 @@ | |
| 494 498 | 
             
                            fs = file.size,
         | 
| 495 499 | 
             
                            ub = options.uploadedBytes = options.uploadedBytes || 0,
         | 
| 496 500 | 
             
                            mcs = options.maxChunkSize || fs,
         | 
| 497 | 
            -
                             | 
| 498 | 
            -
                             | 
| 499 | 
            -
                             | 
| 500 | 
            -
                            upload,
         | 
| 501 | 
            -
                            n,
         | 
| 501 | 
            +
                            slice = file.slice || file.webkitSlice || file.mozSlice,
         | 
| 502 | 
            +
                            dfd = $.Deferred(),
         | 
| 503 | 
            +
                            promise = dfd.promise(),
         | 
| 502 504 | 
             
                            jqXHR,
         | 
| 503 | 
            -
                             | 
| 505 | 
            +
                            upload;
         | 
| 504 506 | 
             
                        if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
         | 
| 505 507 | 
             
                                options.data) {
         | 
| 506 508 | 
             
                            return false;
         | 
| @@ -509,66 +511,70 @@ | |
| 509 511 | 
             
                            return true;
         | 
| 510 512 | 
             
                        }
         | 
| 511 513 | 
             
                        if (ub >= fs) {
         | 
| 512 | 
            -
                            file.error = ' | 
| 514 | 
            +
                            file.error = 'Uploaded bytes exceed file size';
         | 
| 513 515 | 
             
                            return this._getXHRPromise(
         | 
| 514 516 | 
             
                                false,
         | 
| 515 517 | 
             
                                options.context,
         | 
| 516 518 | 
             
                                [null, 'error', file.error]
         | 
| 517 519 | 
             
                            );
         | 
| 518 520 | 
             
                        }
         | 
| 519 | 
            -
                        //  | 
| 520 | 
            -
                        // calculated via filesize, uploaded bytes and max chunk size:
         | 
| 521 | 
            -
                        n = Math.ceil((fs - ub) / mcs);
         | 
| 522 | 
            -
                        // The chunk upload method accepting the chunk number as parameter:
         | 
| 521 | 
            +
                        // The chunk upload method:
         | 
| 523 522 | 
             
                        upload = function (i) {
         | 
| 524 | 
            -
                             | 
| 525 | 
            -
             | 
| 526 | 
            -
                             | 
| 527 | 
            -
             | 
| 528 | 
            -
             | 
| 529 | 
            -
                                 | 
| 530 | 
            -
             | 
| 531 | 
            -
             | 
| 532 | 
            -
             | 
| 533 | 
            -
             | 
| 534 | 
            -
             | 
| 535 | 
            -
             | 
| 536 | 
            -
                                 | 
| 537 | 
            -
             | 
| 538 | 
            -
             | 
| 539 | 
            -
             | 
| 540 | 
            -
             | 
| 541 | 
            -
             | 
| 542 | 
            -
                                 | 
| 543 | 
            -
             | 
| 544 | 
            -
             | 
| 545 | 
            -
             | 
| 546 | 
            -
             | 
| 547 | 
            -
             | 
| 548 | 
            -
             | 
| 549 | 
            -
             | 
| 550 | 
            -
             | 
| 551 | 
            -
             | 
| 552 | 
            -
             | 
| 553 | 
            -
             | 
| 554 | 
            -
             | 
| 555 | 
            -
             | 
| 556 | 
            -
             | 
| 557 | 
            -
                                         | 
| 558 | 
            -
                                         | 
| 559 | 
            -
             | 
| 560 | 
            -
             | 
| 561 | 
            -
             | 
| 562 | 
            -
             | 
| 523 | 
            +
                            // Clone the options object for each chunk upload:
         | 
| 524 | 
            +
                            var o = $.extend({}, options);
         | 
| 525 | 
            +
                            o.blob = slice.call(
         | 
| 526 | 
            +
                                file,
         | 
| 527 | 
            +
                                ub,
         | 
| 528 | 
            +
                                ub + mcs
         | 
| 529 | 
            +
                            );
         | 
| 530 | 
            +
                            // Store the current chunk size, as the blob itself
         | 
| 531 | 
            +
                            // will be dereferenced after data processing:
         | 
| 532 | 
            +
                            o.chunkSize = o.blob.size;
         | 
| 533 | 
            +
                            // Expose the chunk bytes position range:
         | 
| 534 | 
            +
                            o.contentRange = 'bytes ' + ub + '-' +
         | 
| 535 | 
            +
                                (ub + o.chunkSize - 1) + '/' + fs;
         | 
| 536 | 
            +
                            // Process the upload data (the blob and potential form data):
         | 
| 537 | 
            +
                            that._initXHRData(o);
         | 
| 538 | 
            +
                            // Add progress listeners for this chunk upload:
         | 
| 539 | 
            +
                            that._initProgressListener(o);
         | 
| 540 | 
            +
                            jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context))
         | 
| 541 | 
            +
                                .done(function (result, textStatus, jqXHR) {
         | 
| 542 | 
            +
                                    ub = that._getUploadedBytes(jqXHR) ||
         | 
| 543 | 
            +
                                        (ub + o.chunkSize);
         | 
| 544 | 
            +
                                    // Create a progress event if upload is done and
         | 
| 545 | 
            +
                                    // no progress event has been invoked for this chunk:
         | 
| 546 | 
            +
                                    if (!o.loaded) {
         | 
| 547 | 
            +
                                        that._onProgress($.Event('progress', {
         | 
| 548 | 
            +
                                            lengthComputable: true,
         | 
| 549 | 
            +
                                            loaded: ub - o.uploadedBytes,
         | 
| 550 | 
            +
                                            total: ub - o.uploadedBytes
         | 
| 551 | 
            +
                                        }), o);
         | 
| 552 | 
            +
                                    }
         | 
| 553 | 
            +
                                    options.uploadedBytes = o.uploadedBytes = ub;
         | 
| 554 | 
            +
                                    if (ub < fs) {
         | 
| 555 | 
            +
                                        // File upload not yet complete,
         | 
| 556 | 
            +
                                        // continue with the next chunk:
         | 
| 557 | 
            +
                                        upload();
         | 
| 558 | 
            +
                                    } else {
         | 
| 559 | 
            +
                                        dfd.resolveWith(
         | 
| 560 | 
            +
                                            o.context,
         | 
| 561 | 
            +
                                            [result, textStatus, jqXHR]
         | 
| 562 | 
            +
                                        );
         | 
| 563 | 
            +
                                    }
         | 
| 564 | 
            +
                                })
         | 
| 565 | 
            +
                                .fail(function (jqXHR, textStatus, errorThrown) {
         | 
| 566 | 
            +
                                    dfd.rejectWith(
         | 
| 567 | 
            +
                                        o.context,
         | 
| 568 | 
            +
                                        [jqXHR, textStatus, errorThrown]
         | 
| 569 | 
            +
                                    );
         | 
| 570 | 
            +
                                });
         | 
| 563 571 | 
             
                        };
         | 
| 564 | 
            -
                         | 
| 565 | 
            -
                         | 
| 566 | 
            -
                        // and jqXHR callbacks mapped to the equivalent Promise methods:
         | 
| 567 | 
            -
                        pipe = upload(n);
         | 
| 568 | 
            -
                        pipe.abort = function () {
         | 
| 572 | 
            +
                        this._enhancePromise(promise);
         | 
| 573 | 
            +
                        promise.abort = function () {
         | 
| 569 574 | 
             
                            return jqXHR.abort();
         | 
| 570 575 | 
             
                        };
         | 
| 571 | 
            -
                         | 
| 576 | 
            +
                        upload();
         | 
| 577 | 
            +
                        return promise;
         | 
| 572 578 | 
             
                    },
         | 
| 573 579 |  | 
| 574 580 | 
             
                    _beforeSend: function (e, data) {
         | 
| @@ -766,7 +772,7 @@ | |
| 766 772 | 
             
                        // Avoid memory leaks with the detached file input:
         | 
| 767 773 | 
             
                        $.cleanData(input.unbind('remove'));
         | 
| 768 774 | 
             
                        // Replace the original file input element in the fileInput
         | 
| 769 | 
            -
                        //  | 
| 775 | 
            +
                        // elements set with the clone, which has been copied including
         | 
| 770 776 | 
             
                        // event handlers:
         | 
| 771 777 | 
             
                        this.options.fileInput = this.options.fileInput.map(function (i, el) {
         | 
| 772 778 | 
             
                            if (el === input[0]) {
         | 
| @@ -784,16 +790,29 @@ | |
| 784 790 | 
             
                    _handleFileTreeEntry: function (entry, path) {
         | 
| 785 791 | 
             
                        var that = this,
         | 
| 786 792 | 
             
                            dfd = $.Deferred(),
         | 
| 787 | 
            -
                            errorHandler = function () {
         | 
| 788 | 
            -
                                 | 
| 793 | 
            +
                            errorHandler = function (e) {
         | 
| 794 | 
            +
                                if (e && !e.entry) {
         | 
| 795 | 
            +
                                    e.entry = entry;
         | 
| 796 | 
            +
                                }
         | 
| 797 | 
            +
                                // Since $.when returns immediately if one
         | 
| 798 | 
            +
                                // Deferred is rejected, we use resolve instead.
         | 
| 799 | 
            +
                                // This allows valid files and invalid items
         | 
| 800 | 
            +
                                // to be returned together in one set:
         | 
| 801 | 
            +
                                dfd.resolve([e]);
         | 
| 789 802 | 
             
                            },
         | 
| 790 803 | 
             
                            dirReader;
         | 
| 791 804 | 
             
                        path = path || '';
         | 
| 792 805 | 
             
                        if (entry.isFile) {
         | 
| 793 | 
            -
                            entry. | 
| 794 | 
            -
                                 | 
| 795 | 
            -
                                 | 
| 796 | 
            -
             | 
| 806 | 
            +
                            if (entry._file) {
         | 
| 807 | 
            +
                                // Workaround for Chrome bug #149735
         | 
| 808 | 
            +
                                entry._file.relativePath = path;
         | 
| 809 | 
            +
                                dfd.resolve(entry._file);
         | 
| 810 | 
            +
                            } else {
         | 
| 811 | 
            +
                                entry.file(function (file) {
         | 
| 812 | 
            +
                                    file.relativePath = path;
         | 
| 813 | 
            +
                                    dfd.resolve(file);
         | 
| 814 | 
            +
                                }, errorHandler);
         | 
| 815 | 
            +
                            }
         | 
| 797 816 | 
             
                        } else if (entry.isDirectory) {
         | 
| 798 817 | 
             
                            dirReader = entry.createReader();
         | 
| 799 818 | 
             
                            dirReader.readEntries(function (entries) {
         | 
| @@ -805,7 +824,9 @@ | |
| 805 824 | 
             
                                }).fail(errorHandler);
         | 
| 806 825 | 
             
                            }, errorHandler);
         | 
| 807 826 | 
             
                        } else {
         | 
| 808 | 
            -
                             | 
| 827 | 
            +
                            // Return an empy list for file system items
         | 
| 828 | 
            +
                            // other than files or directories:
         | 
| 829 | 
            +
                            dfd.resolve([]);
         | 
| 809 830 | 
             
                        }
         | 
| 810 831 | 
             
                        return dfd.promise();
         | 
| 811 832 | 
             
                    },
         | 
| @@ -832,8 +853,14 @@ | |
| 832 853 | 
             
                                items[0].getAsEntry)) {
         | 
| 833 854 | 
             
                            return this._handleFileTreeEntries(
         | 
| 834 855 | 
             
                                $.map(items, function (item) {
         | 
| 856 | 
            +
                                    var entry;
         | 
| 835 857 | 
             
                                    if (item.webkitGetAsEntry) {
         | 
| 836 | 
            -
                                         | 
| 858 | 
            +
                                        entry = item.webkitGetAsEntry();
         | 
| 859 | 
            +
                                        if (entry) {
         | 
| 860 | 
            +
                                            // Workaround for Chrome bug #149735:
         | 
| 861 | 
            +
                                            entry._file = item.getAsFile();
         | 
| 862 | 
            +
                                        }
         | 
| 863 | 
            +
                                        return entry;
         | 
| 837 864 | 
             
                                    }
         | 
| 838 865 | 
             
                                    return item.getAsEntry();
         | 
| 839 866 | 
             
                                })
         | 
| @@ -844,7 +871,7 @@ | |
| 844 871 | 
             
                        ).promise();
         | 
| 845 872 | 
             
                    },
         | 
| 846 873 |  | 
| 847 | 
            -
                     | 
| 874 | 
            +
                    _getSingleFileInputFiles: function (fileInput) {
         | 
| 848 875 | 
             
                        fileInput = $(fileInput);
         | 
| 849 876 | 
             
                        var entries = fileInput.prop('webkitEntries') ||
         | 
| 850 877 | 
             
                                fileInput.prop('entries'),
         | 
| @@ -857,23 +884,44 @@ | |
| 857 884 | 
             
                        if (!files.length) {
         | 
| 858 885 | 
             
                            value = fileInput.prop('value');
         | 
| 859 886 | 
             
                            if (!value) {
         | 
| 860 | 
            -
                                return $.Deferred(). | 
| 887 | 
            +
                                return $.Deferred().resolve([]).promise();
         | 
| 861 888 | 
             
                            }
         | 
| 862 889 | 
             
                            // If the files property is not available, the browser does not
         | 
| 863 890 | 
             
                            // support the File API and we add a pseudo File object with
         | 
| 864 891 | 
             
                            // the input value as name with path information removed:
         | 
| 865 892 | 
             
                            files = [{name: value.replace(/^.*\\/, '')}];
         | 
| 893 | 
            +
                        } else if (files[0].name === undefined && files[0].fileName) {
         | 
| 894 | 
            +
                            // File normalization for Safari 4 and Firefox 3:
         | 
| 895 | 
            +
                            $.each(files, function (index, file) {
         | 
| 896 | 
            +
                                file.name = file.fileName;
         | 
| 897 | 
            +
                                file.size = file.fileSize;
         | 
| 898 | 
            +
                            });
         | 
| 866 899 | 
             
                        }
         | 
| 867 900 | 
             
                        return $.Deferred().resolve(files).promise();
         | 
| 868 901 | 
             
                    },
         | 
| 869 902 |  | 
| 903 | 
            +
                    _getFileInputFiles: function (fileInput) {
         | 
| 904 | 
            +
                        if (!(fileInput instanceof $) || fileInput.length === 1) {
         | 
| 905 | 
            +
                            return this._getSingleFileInputFiles(fileInput);
         | 
| 906 | 
            +
                        }
         | 
| 907 | 
            +
                        return $.when.apply(
         | 
| 908 | 
            +
                            $,
         | 
| 909 | 
            +
                            $.map(fileInput, this._getSingleFileInputFiles)
         | 
| 910 | 
            +
                        ).pipe(function () {
         | 
| 911 | 
            +
                            return Array.prototype.concat.apply(
         | 
| 912 | 
            +
                                [],
         | 
| 913 | 
            +
                                arguments
         | 
| 914 | 
            +
                            );
         | 
| 915 | 
            +
                        });
         | 
| 916 | 
            +
                    },
         | 
| 917 | 
            +
             | 
| 870 918 | 
             
                    _onChange: function (e) {
         | 
| 871 | 
            -
                        var that =  | 
| 919 | 
            +
                        var that = this,
         | 
| 872 920 | 
             
                            data = {
         | 
| 873 921 | 
             
                                fileInput: $(e.target),
         | 
| 874 922 | 
             
                                form: $(e.target.form)
         | 
| 875 923 | 
             
                            };
         | 
| 876 | 
            -
                         | 
| 924 | 
            +
                        this._getFileInputFiles(data.fileInput).always(function (files) {
         | 
| 877 925 | 
             
                            data.files = files;
         | 
| 878 926 | 
             
                            if (that.options.replaceFileInput) {
         | 
| 879 927 | 
             
                                that._replaceFileInput(data.fileInput);
         | 
| @@ -885,8 +933,7 @@ | |
| 885 933 | 
             
                    },
         | 
| 886 934 |  | 
| 887 935 | 
             
                    _onPaste: function (e) {
         | 
| 888 | 
            -
                        var  | 
| 889 | 
            -
                            cbd = e.originalEvent.clipboardData,
         | 
| 936 | 
            +
                        var cbd = e.originalEvent.clipboardData,
         | 
| 890 937 | 
             
                            items = (cbd && cbd.items) || [],
         | 
| 891 938 | 
             
                            data = {files: []};
         | 
| 892 939 | 
             
                        $.each(items, function (index, item) {
         | 
| @@ -895,18 +942,18 @@ | |
| 895 942 | 
             
                                data.files.push(file);
         | 
| 896 943 | 
             
                            }
         | 
| 897 944 | 
             
                        });
         | 
| 898 | 
            -
                        if ( | 
| 899 | 
            -
                                 | 
| 945 | 
            +
                        if (this._trigger('paste', e, data) === false ||
         | 
| 946 | 
            +
                                this._onAdd(e, data) === false) {
         | 
| 900 947 | 
             
                            return false;
         | 
| 901 948 | 
             
                        }
         | 
| 902 949 | 
             
                    },
         | 
| 903 950 |  | 
| 904 951 | 
             
                    _onDrop: function (e) {
         | 
| 905 952 | 
             
                        e.preventDefault();
         | 
| 906 | 
            -
                        var that =  | 
| 953 | 
            +
                        var that = this,
         | 
| 907 954 | 
             
                            dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
         | 
| 908 955 | 
             
                            data = {};
         | 
| 909 | 
            -
                         | 
| 956 | 
            +
                        this._getDroppedFiles(dataTransfer).always(function (files) {
         | 
| 910 957 | 
             
                            data.files = files;
         | 
| 911 958 | 
             
                            if (that._trigger('drop', e, data) !== false) {
         | 
| 912 959 | 
             
                                that._onAdd(e, data);
         | 
| @@ -915,9 +962,8 @@ | |
| 915 962 | 
             
                    },
         | 
| 916 963 |  | 
| 917 964 | 
             
                    _onDragOver: function (e) {
         | 
| 918 | 
            -
                        var  | 
| 919 | 
            -
             | 
| 920 | 
            -
                        if (that._trigger('dragover', e) === false) {
         | 
| 965 | 
            +
                        var dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
         | 
| 966 | 
            +
                        if (this._trigger('dragover', e) === false) {
         | 
| 921 967 | 
             
                            return false;
         | 
| 922 968 | 
             
                        }
         | 
| 923 969 | 
             
                        if (dataTransfer) {
         | 
| @@ -927,25 +973,24 @@ | |
| 927 973 | 
             
                    },
         | 
| 928 974 |  | 
| 929 975 | 
             
                    _initEventHandlers: function () {
         | 
| 930 | 
            -
                        var ns = this.options.namespace;
         | 
| 931 976 | 
             
                        if (this._isXHRUpload(this.options)) {
         | 
| 932 | 
            -
                            this.options.dropZone
         | 
| 933 | 
            -
                                 | 
| 934 | 
            -
                                 | 
| 935 | 
            -
             | 
| 977 | 
            +
                            this._on(this.options.dropZone, {
         | 
| 978 | 
            +
                                dragover: this._onDragOver,
         | 
| 979 | 
            +
                                drop: this._onDrop
         | 
| 980 | 
            +
                            });
         | 
| 981 | 
            +
                            this._on(this.options.pasteZone, {
         | 
| 982 | 
            +
                                paste: this._onPaste
         | 
| 983 | 
            +
                            });
         | 
| 936 984 | 
             
                        }
         | 
| 937 | 
            -
                        this.options.fileInput
         | 
| 938 | 
            -
                             | 
| 985 | 
            +
                        this._on(this.options.fileInput, {
         | 
| 986 | 
            +
                            change: this._onChange
         | 
| 987 | 
            +
                        });
         | 
| 939 988 | 
             
                    },
         | 
| 940 989 |  | 
| 941 990 | 
             
                    _destroyEventHandlers: function () {
         | 
| 942 | 
            -
                         | 
| 943 | 
            -
                        this.options. | 
| 944 | 
            -
             | 
| 945 | 
            -
                            .unbind('drop.' + ns, this._onDrop)
         | 
| 946 | 
            -
                            .unbind('paste.' + ns, this._onPaste);
         | 
| 947 | 
            -
                        this.options.fileInput
         | 
| 948 | 
            -
                            .unbind('change.' + ns, this._onChange);
         | 
| 991 | 
            +
                        this._off(this.options.dropZone, 'dragover drop');
         | 
| 992 | 
            +
                        this._off(this.options.pasteZone, 'paste');
         | 
| 993 | 
            +
                        this._off(this.options.fileInput, 'change');
         | 
| 949 994 | 
             
                    },
         | 
| 950 995 |  | 
| 951 996 | 
             
                    _setOption: function (key, value) {
         | 
| @@ -953,7 +998,7 @@ | |
| 953 998 | 
             
                        if (refresh) {
         | 
| 954 999 | 
             
                            this._destroyEventHandlers();
         | 
| 955 1000 | 
             
                        }
         | 
| 956 | 
            -
                         | 
| 1001 | 
            +
                        this._super(key, value);
         | 
| 957 1002 | 
             
                        if (refresh) {
         | 
| 958 1003 | 
             
                            this._initSpecialOptions();
         | 
| 959 1004 | 
             
                            this._initEventHandlers();
         | 
| @@ -971,13 +1016,15 @@ | |
| 971 1016 | 
             
                        if (!(options.dropZone instanceof $)) {
         | 
| 972 1017 | 
             
                            options.dropZone = $(options.dropZone);
         | 
| 973 1018 | 
             
                        }
         | 
| 1019 | 
            +
                        if (!(options.pasteZone instanceof $)) {
         | 
| 1020 | 
            +
                            options.pasteZone = $(options.pasteZone);
         | 
| 1021 | 
            +
                        }
         | 
| 974 1022 | 
             
                    },
         | 
| 975 1023 |  | 
| 976 1024 | 
             
                    _create: function () {
         | 
| 977 1025 | 
             
                        var options = this.options;
         | 
| 978 1026 | 
             
                        // Initialize options set via HTML5 data-attributes:
         | 
| 979 1027 | 
             
                        $.extend(options, $(this.element[0].cloneNode(false)).data());
         | 
| 980 | 
            -
                        options.namespace = options.namespace || this.widgetName;
         | 
| 981 1028 | 
             
                        this._initSpecialOptions();
         | 
| 982 1029 | 
             
                        this._slots = [];
         | 
| 983 1030 | 
             
                        this._sequence = this._getXHRPromise(true);
         | 
| @@ -985,19 +1032,8 @@ | |
| 985 1032 | 
             
                        this._initEventHandlers();
         | 
| 986 1033 | 
             
                    },
         | 
| 987 1034 |  | 
| 988 | 
            -
                     | 
| 989 | 
            -
                        this._destroyEventHandlers();
         | 
| 990 | 
            -
                        $.Widget.prototype.destroy.call(this);
         | 
| 991 | 
            -
                    },
         | 
| 992 | 
            -
             | 
| 993 | 
            -
                    enable: function () {
         | 
| 994 | 
            -
                        $.Widget.prototype.enable.call(this);
         | 
| 995 | 
            -
                        this._initEventHandlers();
         | 
| 996 | 
            -
                    },
         | 
| 997 | 
            -
             | 
| 998 | 
            -
                    disable: function () {
         | 
| 1035 | 
            +
                    _destroy: function () {
         | 
| 999 1036 | 
             
                        this._destroyEventHandlers();
         | 
| 1000 | 
            -
                        $.Widget.prototype.disable.call(this);
         | 
| 1001 1037 | 
             
                    },
         | 
| 1002 1038 |  | 
| 1003 1039 | 
             
                    // This method is exposed to the widget API and allows adding files
         |