jquery-fileuploads-rails4 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/Rakefile +40 -0
- data/Readme.md +92 -0
- data/demo/.gitignore +3 -0
- data/demo/Gemfile +8 -0
- data/demo/Rakefile +2 -0
- data/demo/Readme.md +12 -0
- data/demo/app/assets/javascripts/application.js.coffee +9 -0
- data/demo/app/controllers/application_controller.rb +7 -0
- data/demo/app/views/application/basic.html.erb +12 -0
- data/demo/app/views/application/create.html.erb +1 -0
- data/demo/app/views/application/ui.html.erb +1 -0
- data/demo/app/views/layouts/application.html.erb +13 -0
- data/demo/bin/bundle +3 -0
- data/demo/bin/rails +4 -0
- data/demo/bin/rake +4 -0
- data/demo/config.ru +4 -0
- data/demo/config/application.rb +21 -0
- data/demo/config/boot.rb +6 -0
- data/demo/config/environment.rb +5 -0
- data/demo/config/routes.rb +6 -0
- data/demo/log/.gitkeep +0 -0
- data/dependencies.json +4 -0
- data/jquery-fileuploads-rails4.gemspec +17 -0
- data/lib/jquery-fileuploads-rails4.rb +9 -0
- data/vendor/assets/javascripts/jquery.fileupload.js +1460 -0
- data/vendor/assets/javascripts/jquery.iframe-transport.js +214 -0
- data/vendor/legacy_assets/javascripts/jquery.fileupload-fp.js +219 -0
- data/vendor/legacy_assets/javascripts/jquery.fileupload-ip.js +160 -0
- data/vendor/legacy_assets/javascripts/jquery.fileupload-ui.js +702 -0
- data/vendor/legacy_assets/javascripts/jquery.postmessage-transport.js +117 -0
- data/vendor/legacy_assets/javascripts/jquery.xdr-transport.js +85 -0
- data/vendor/legacy_assets/stylesheets/jquery.fileupload-ui.css +84 -0
- metadata +107 -0
| @@ -0,0 +1,702 @@ | |
| 1 | 
            +
            /*
         | 
| 2 | 
            +
             * jQuery File Upload User Interface Plugin 6.9.1
         | 
| 3 | 
            +
             * https://github.com/blueimp/jQuery-File-Upload
         | 
| 4 | 
            +
             *
         | 
| 5 | 
            +
             * Copyright 2010, Sebastian Tschan
         | 
| 6 | 
            +
             * https://blueimp.net
         | 
| 7 | 
            +
             *
         | 
| 8 | 
            +
             * Licensed under the MIT license:
         | 
| 9 | 
            +
             * http://www.opensource.org/licenses/MIT
         | 
| 10 | 
            +
             */
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            /*jslint nomen: true, unparam: true, regexp: true */
         | 
| 13 | 
            +
            /*global define, window, document, URL, webkitURL, FileReader */
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            (function (factory) {
         | 
| 16 | 
            +
                'use strict';
         | 
| 17 | 
            +
                if (typeof define === 'function' && define.amd) {
         | 
| 18 | 
            +
                    // Register as an anonymous AMD module:
         | 
| 19 | 
            +
                    define([
         | 
| 20 | 
            +
                        'jquery',
         | 
| 21 | 
            +
                        'tmpl',
         | 
| 22 | 
            +
                        'load-image',
         | 
| 23 | 
            +
                        './jquery.fileupload-fp'
         | 
| 24 | 
            +
                    ], factory);
         | 
| 25 | 
            +
                } else {
         | 
| 26 | 
            +
                    // Browser globals:
         | 
| 27 | 
            +
                    factory(
         | 
| 28 | 
            +
                        window.jQuery,
         | 
| 29 | 
            +
                        window.tmpl,
         | 
| 30 | 
            +
                        window.loadImage
         | 
| 31 | 
            +
                    );
         | 
| 32 | 
            +
                }
         | 
| 33 | 
            +
            }(function ($, tmpl, loadImage) {
         | 
| 34 | 
            +
                'use strict';
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                // The UI version extends the FP (file processing) version or the basic
         | 
| 37 | 
            +
                // file upload widget and adds complete user interface interaction:
         | 
| 38 | 
            +
                var parentWidget = ($.blueimpFP || $.blueimp).fileupload;
         | 
| 39 | 
            +
                $.widget('blueimpUI.fileupload', parentWidget, {
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    options: {
         | 
| 42 | 
            +
                        // By default, files added to the widget are uploaded as soon
         | 
| 43 | 
            +
                        // as the user clicks on the start buttons. To enable automatic
         | 
| 44 | 
            +
                        // uploads, set the following option to true:
         | 
| 45 | 
            +
                        autoUpload: false,
         | 
| 46 | 
            +
                        // The following option limits the number of files that are
         | 
| 47 | 
            +
                        // allowed to be uploaded using this widget:
         | 
| 48 | 
            +
                        maxNumberOfFiles: undefined,
         | 
| 49 | 
            +
                        // The maximum allowed file size:
         | 
| 50 | 
            +
                        maxFileSize: undefined,
         | 
| 51 | 
            +
                        // The minimum allowed file size:
         | 
| 52 | 
            +
                        minFileSize: undefined,
         | 
| 53 | 
            +
                        // The regular expression for allowed file types, matches
         | 
| 54 | 
            +
                        // against either file type or file name:
         | 
| 55 | 
            +
                        acceptFileTypes:  /.+$/i,
         | 
| 56 | 
            +
                        // The regular expression to define for which files a preview
         | 
| 57 | 
            +
                        // image is shown, matched against the file type:
         | 
| 58 | 
            +
                        previewSourceFileTypes: /^image\/(gif|jpeg|png)$/,
         | 
| 59 | 
            +
                        // The maximum file size of images that are to be displayed as preview:
         | 
| 60 | 
            +
                        previewSourceMaxFileSize: 5000000, // 5MB
         | 
| 61 | 
            +
                        // The maximum width of the preview images:
         | 
| 62 | 
            +
                        previewMaxWidth: 80,
         | 
| 63 | 
            +
                        // The maximum height of the preview images:
         | 
| 64 | 
            +
                        previewMaxHeight: 80,
         | 
| 65 | 
            +
                        // By default, preview images are displayed as canvas elements
         | 
| 66 | 
            +
                        // if supported by the browser. Set the following option to false
         | 
| 67 | 
            +
                        // to always display preview images as img elements:
         | 
| 68 | 
            +
                        previewAsCanvas: true,
         | 
| 69 | 
            +
                        // The ID of the upload template:
         | 
| 70 | 
            +
                        uploadTemplateId: 'template-upload',
         | 
| 71 | 
            +
                        // The ID of the download template:
         | 
| 72 | 
            +
                        downloadTemplateId: 'template-download',
         | 
| 73 | 
            +
                        // The container for the list of files. If undefined, it is set to
         | 
| 74 | 
            +
                        // an element with class "files" inside of the widget element:
         | 
| 75 | 
            +
                        filesContainer: undefined,
         | 
| 76 | 
            +
                        // By default, files are appended to the files container.
         | 
| 77 | 
            +
                        // Set the following option to true, to prepend files instead:
         | 
| 78 | 
            +
                        prependFiles: false,
         | 
| 79 | 
            +
                        // The expected data type of the upload response, sets the dataType
         | 
| 80 | 
            +
                        // option of the $.ajax upload requests:
         | 
| 81 | 
            +
                        dataType: 'json',
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                        // The add callback is invoked as soon as files are added to the fileupload
         | 
| 84 | 
            +
                        // widget (via file input selection, drag & drop or add API call).
         | 
| 85 | 
            +
                        // See the basic file upload widget for more information:
         | 
| 86 | 
            +
                        add: function (e, data) {
         | 
| 87 | 
            +
                            var that = $(this).data('fileupload'),
         | 
| 88 | 
            +
                                options = that.options,
         | 
| 89 | 
            +
                                files = data.files;
         | 
| 90 | 
            +
                            $(this).fileupload('process', data).done(function () {
         | 
| 91 | 
            +
                                that._adjustMaxNumberOfFiles(-files.length);
         | 
| 92 | 
            +
                                data.isAdjusted = true;
         | 
| 93 | 
            +
                                data.files.valid = data.isValidated = that._validate(files);
         | 
| 94 | 
            +
                                data.context = that._renderUpload(files).data('data', data);
         | 
| 95 | 
            +
                                options.filesContainer[
         | 
| 96 | 
            +
                                    options.prependFiles ? 'prepend' : 'append'
         | 
| 97 | 
            +
                                ](data.context);
         | 
| 98 | 
            +
                                that._renderPreviews(files, data.context);
         | 
| 99 | 
            +
                                that._forceReflow(data.context);
         | 
| 100 | 
            +
                                that._transition(data.context).done(
         | 
| 101 | 
            +
                                    function () {
         | 
| 102 | 
            +
                                        if ((that._trigger('added', e, data) !== false) &&
         | 
| 103 | 
            +
                                                (options.autoUpload || data.autoUpload) &&
         | 
| 104 | 
            +
                                                data.autoUpload !== false && data.isValidated) {
         | 
| 105 | 
            +
                                            data.submit();
         | 
| 106 | 
            +
                                        }
         | 
| 107 | 
            +
                                    }
         | 
| 108 | 
            +
                                );
         | 
| 109 | 
            +
                            });
         | 
| 110 | 
            +
                        },
         | 
| 111 | 
            +
                        // Callback for the start of each file upload request:
         | 
| 112 | 
            +
                        send: function (e, data) {
         | 
| 113 | 
            +
                            var that = $(this).data('fileupload');
         | 
| 114 | 
            +
                            if (!data.isValidated) {
         | 
| 115 | 
            +
                                if (!data.isAdjusted) {
         | 
| 116 | 
            +
                                    that._adjustMaxNumberOfFiles(-data.files.length);
         | 
| 117 | 
            +
                                }
         | 
| 118 | 
            +
                                if (!that._validate(data.files)) {
         | 
| 119 | 
            +
                                    return false;
         | 
| 120 | 
            +
                                }
         | 
| 121 | 
            +
                            }
         | 
| 122 | 
            +
                            if (data.context && data.dataType &&
         | 
| 123 | 
            +
                                    data.dataType.substr(0, 6) === 'iframe') {
         | 
| 124 | 
            +
                                // Iframe Transport does not support progress events.
         | 
| 125 | 
            +
                                // In lack of an indeterminate progress bar, we set
         | 
| 126 | 
            +
                                // the progress to 100%, showing the full animated bar:
         | 
| 127 | 
            +
                                data.context
         | 
| 128 | 
            +
                                    .find('.progress').addClass(
         | 
| 129 | 
            +
                                        !$.support.transition && 'progress-animated'
         | 
| 130 | 
            +
                                    )
         | 
| 131 | 
            +
                                    .attr('aria-valuenow', 100)
         | 
| 132 | 
            +
                                    .find('.bar').css(
         | 
| 133 | 
            +
                                        'width',
         | 
| 134 | 
            +
                                        '100%'
         | 
| 135 | 
            +
                                    );
         | 
| 136 | 
            +
                            }
         | 
| 137 | 
            +
                            return that._trigger('sent', e, data);
         | 
| 138 | 
            +
                        },
         | 
| 139 | 
            +
                        // Callback for successful uploads:
         | 
| 140 | 
            +
                        done: function (e, data) {
         | 
| 141 | 
            +
                            var that = $(this).data('fileupload'),
         | 
| 142 | 
            +
                                template;
         | 
| 143 | 
            +
                            if (data.context) {
         | 
| 144 | 
            +
                                data.context.each(function (index) {
         | 
| 145 | 
            +
                                    var file = ($.isArray(data.result) &&
         | 
| 146 | 
            +
                                            data.result[index]) || {error: 'emptyResult'};
         | 
| 147 | 
            +
                                    if (file.error) {
         | 
| 148 | 
            +
                                        that._adjustMaxNumberOfFiles(1);
         | 
| 149 | 
            +
                                    }
         | 
| 150 | 
            +
                                    that._transition($(this)).done(
         | 
| 151 | 
            +
                                        function () {
         | 
| 152 | 
            +
                                            var node = $(this);
         | 
| 153 | 
            +
                                            template = that._renderDownload([file])
         | 
| 154 | 
            +
                                                .css('height', node.height())
         | 
| 155 | 
            +
                                                .replaceAll(node);
         | 
| 156 | 
            +
                                            that._forceReflow(template);
         | 
| 157 | 
            +
                                            that._transition(template).done(
         | 
| 158 | 
            +
                                                function () {
         | 
| 159 | 
            +
                                                    data.context = $(this);
         | 
| 160 | 
            +
                                                    that._trigger('completed', e, data);
         | 
| 161 | 
            +
                                                }
         | 
| 162 | 
            +
                                            );
         | 
| 163 | 
            +
                                        }
         | 
| 164 | 
            +
                                    );
         | 
| 165 | 
            +
                                });
         | 
| 166 | 
            +
                            } else {
         | 
| 167 | 
            +
                                template = that._renderDownload(data.result)
         | 
| 168 | 
            +
                                    .appendTo(that.options.filesContainer);
         | 
| 169 | 
            +
                                that._forceReflow(template);
         | 
| 170 | 
            +
                                that._transition(template).done(
         | 
| 171 | 
            +
                                    function () {
         | 
| 172 | 
            +
                                        data.context = $(this);
         | 
| 173 | 
            +
                                        that._trigger('completed', e, data);
         | 
| 174 | 
            +
                                    }
         | 
| 175 | 
            +
                                );
         | 
| 176 | 
            +
                            }
         | 
| 177 | 
            +
                        },
         | 
| 178 | 
            +
                        // Callback for failed (abort or error) uploads:
         | 
| 179 | 
            +
                        fail: function (e, data) {
         | 
| 180 | 
            +
                            var that = $(this).data('fileupload'),
         | 
| 181 | 
            +
                                template;
         | 
| 182 | 
            +
                            that._adjustMaxNumberOfFiles(data.files.length);
         | 
| 183 | 
            +
                            if (data.context) {
         | 
| 184 | 
            +
                                data.context.each(function (index) {
         | 
| 185 | 
            +
                                    if (data.errorThrown !== 'abort') {
         | 
| 186 | 
            +
                                        var file = data.files[index];
         | 
| 187 | 
            +
                                        file.error = file.error || data.errorThrown ||
         | 
| 188 | 
            +
                                            true;
         | 
| 189 | 
            +
                                        that._transition($(this)).done(
         | 
| 190 | 
            +
                                            function () {
         | 
| 191 | 
            +
                                                var node = $(this);
         | 
| 192 | 
            +
                                                template = that._renderDownload([file])
         | 
| 193 | 
            +
                                                    .replaceAll(node);
         | 
| 194 | 
            +
                                                that._forceReflow(template);
         | 
| 195 | 
            +
                                                that._transition(template).done(
         | 
| 196 | 
            +
                                                    function () {
         | 
| 197 | 
            +
                                                        data.context = $(this);
         | 
| 198 | 
            +
                                                        that._trigger('failed', e, data);
         | 
| 199 | 
            +
                                                    }
         | 
| 200 | 
            +
                                                );
         | 
| 201 | 
            +
                                            }
         | 
| 202 | 
            +
                                        );
         | 
| 203 | 
            +
                                    } else {
         | 
| 204 | 
            +
                                        that._transition($(this)).done(
         | 
| 205 | 
            +
                                            function () {
         | 
| 206 | 
            +
                                                $(this).remove();
         | 
| 207 | 
            +
                                                that._trigger('failed', e, data);
         | 
| 208 | 
            +
                                            }
         | 
| 209 | 
            +
                                        );
         | 
| 210 | 
            +
                                    }
         | 
| 211 | 
            +
                                });
         | 
| 212 | 
            +
                            } else if (data.errorThrown !== 'abort') {
         | 
| 213 | 
            +
                                that._adjustMaxNumberOfFiles(-data.files.length);
         | 
| 214 | 
            +
                                data.context = that._renderUpload(data.files)
         | 
| 215 | 
            +
                                    .appendTo(that.options.filesContainer)
         | 
| 216 | 
            +
                                    .data('data', data);
         | 
| 217 | 
            +
                                that._forceReflow(data.context);
         | 
| 218 | 
            +
                                that._transition(data.context).done(
         | 
| 219 | 
            +
                                    function () {
         | 
| 220 | 
            +
                                        data.context = $(this);
         | 
| 221 | 
            +
                                        that._trigger('failed', e, data);
         | 
| 222 | 
            +
                                    }
         | 
| 223 | 
            +
                                );
         | 
| 224 | 
            +
                            } else {
         | 
| 225 | 
            +
                                that._trigger('failed', e, data);
         | 
| 226 | 
            +
                            }
         | 
| 227 | 
            +
                        },
         | 
| 228 | 
            +
                        // Callback for upload progress events:
         | 
| 229 | 
            +
                        progress: function (e, data) {
         | 
| 230 | 
            +
                            if (data.context) {
         | 
| 231 | 
            +
                                var progress = parseInt(data.loaded / data.total * 100, 10);
         | 
| 232 | 
            +
                                data.context.find('.progress')
         | 
| 233 | 
            +
                                    .attr('aria-valuenow', progress)
         | 
| 234 | 
            +
                                    .find('.bar').css(
         | 
| 235 | 
            +
                                        'width',
         | 
| 236 | 
            +
                                        progress + '%'
         | 
| 237 | 
            +
                                    );
         | 
| 238 | 
            +
                            }
         | 
| 239 | 
            +
                        },
         | 
| 240 | 
            +
                        // Callback for global upload progress events:
         | 
| 241 | 
            +
                        progressall: function (e, data) {
         | 
| 242 | 
            +
                            var $this = $(this),
         | 
| 243 | 
            +
                                progress = parseInt(data.loaded / data.total * 100, 10),
         | 
| 244 | 
            +
                                globalProgressNode = $this.find('.fileupload-progress'),
         | 
| 245 | 
            +
                                extendedProgressNode = globalProgressNode
         | 
| 246 | 
            +
                                    .find('.progress-extended');
         | 
| 247 | 
            +
                            if (extendedProgressNode.length) {
         | 
| 248 | 
            +
                                extendedProgressNode.html(
         | 
| 249 | 
            +
                                    $this.data('fileupload')._renderExtendedProgress(data)
         | 
| 250 | 
            +
                                );
         | 
| 251 | 
            +
                            }
         | 
| 252 | 
            +
                            globalProgressNode
         | 
| 253 | 
            +
                                .find('.progress')
         | 
| 254 | 
            +
                                .attr('aria-valuenow', progress)
         | 
| 255 | 
            +
                                .find('.bar').css(
         | 
| 256 | 
            +
                                    'width',
         | 
| 257 | 
            +
                                    progress + '%'
         | 
| 258 | 
            +
                                );
         | 
| 259 | 
            +
                        },
         | 
| 260 | 
            +
                        // Callback for uploads start, equivalent to the global ajaxStart event:
         | 
| 261 | 
            +
                        start: function (e) {
         | 
| 262 | 
            +
                            var that = $(this).data('fileupload');
         | 
| 263 | 
            +
                            that._transition($(this).find('.fileupload-progress')).done(
         | 
| 264 | 
            +
                                function () {
         | 
| 265 | 
            +
                                    that._trigger('started', e);
         | 
| 266 | 
            +
                                }
         | 
| 267 | 
            +
                            );
         | 
| 268 | 
            +
                        },
         | 
| 269 | 
            +
                        // Callback for uploads stop, equivalent to the global ajaxStop event:
         | 
| 270 | 
            +
                        stop: function (e) {
         | 
| 271 | 
            +
                            var that = $(this).data('fileupload');
         | 
| 272 | 
            +
                            that._transition($(this).find('.fileupload-progress')).done(
         | 
| 273 | 
            +
                                function () {
         | 
| 274 | 
            +
                                    $(this).find('.progress')
         | 
| 275 | 
            +
                                        .attr('aria-valuenow', '0')
         | 
| 276 | 
            +
                                        .find('.bar').css('width', '0%');
         | 
| 277 | 
            +
                                    $(this).find('.progress-extended').html(' ');
         | 
| 278 | 
            +
                                    that._trigger('stopped', e);
         | 
| 279 | 
            +
                                }
         | 
| 280 | 
            +
                            );
         | 
| 281 | 
            +
                        },
         | 
| 282 | 
            +
                        // Callback for file deletion:
         | 
| 283 | 
            +
                        destroy: function (e, data) {
         | 
| 284 | 
            +
                            var that = $(this).data('fileupload');
         | 
| 285 | 
            +
                            if (data.url) {
         | 
| 286 | 
            +
                                $.ajax(data);
         | 
| 287 | 
            +
                                that._adjustMaxNumberOfFiles(1);
         | 
| 288 | 
            +
                            }
         | 
| 289 | 
            +
                            that._transition(data.context).done(
         | 
| 290 | 
            +
                                function () {
         | 
| 291 | 
            +
                                    $(this).remove();
         | 
| 292 | 
            +
                                    that._trigger('destroyed', e, data);
         | 
| 293 | 
            +
                                }
         | 
| 294 | 
            +
                            );
         | 
| 295 | 
            +
                        }
         | 
| 296 | 
            +
                    },
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                    // Link handler, that allows to download files
         | 
| 299 | 
            +
                    // by drag & drop of the links to the desktop:
         | 
| 300 | 
            +
                    _enableDragToDesktop: function () {
         | 
| 301 | 
            +
                        var link = $(this),
         | 
| 302 | 
            +
                            url = link.prop('href'),
         | 
| 303 | 
            +
                            name = link.prop('download'),
         | 
| 304 | 
            +
                            type = 'application/octet-stream';
         | 
| 305 | 
            +
                        link.bind('dragstart', function (e) {
         | 
| 306 | 
            +
                            try {
         | 
| 307 | 
            +
                                e.originalEvent.dataTransfer.setData(
         | 
| 308 | 
            +
                                    'DownloadURL',
         | 
| 309 | 
            +
                                    [type, name, url].join(':')
         | 
| 310 | 
            +
                                );
         | 
| 311 | 
            +
                            } catch (err) {}
         | 
| 312 | 
            +
                        });
         | 
| 313 | 
            +
                    },
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                    _adjustMaxNumberOfFiles: function (operand) {
         | 
| 316 | 
            +
                        if (typeof this.options.maxNumberOfFiles === 'number') {
         | 
| 317 | 
            +
                            this.options.maxNumberOfFiles += operand;
         | 
| 318 | 
            +
                            if (this.options.maxNumberOfFiles < 1) {
         | 
| 319 | 
            +
                                this._disableFileInputButton();
         | 
| 320 | 
            +
                            } else {
         | 
| 321 | 
            +
                                this._enableFileInputButton();
         | 
| 322 | 
            +
                            }
         | 
| 323 | 
            +
                        }
         | 
| 324 | 
            +
                    },
         | 
| 325 | 
            +
             | 
| 326 | 
            +
                    _formatFileSize: function (bytes) {
         | 
| 327 | 
            +
                        if (typeof bytes !== 'number') {
         | 
| 328 | 
            +
                            return '';
         | 
| 329 | 
            +
                        }
         | 
| 330 | 
            +
                        if (bytes >= 1000000000) {
         | 
| 331 | 
            +
                            return (bytes / 1000000000).toFixed(2) + ' GB';
         | 
| 332 | 
            +
                        }
         | 
| 333 | 
            +
                        if (bytes >= 1000000) {
         | 
| 334 | 
            +
                            return (bytes / 1000000).toFixed(2) + ' MB';
         | 
| 335 | 
            +
                        }
         | 
| 336 | 
            +
                        return (bytes / 1000).toFixed(2) + ' KB';
         | 
| 337 | 
            +
                    },
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                    _formatBitrate: function (bits) {
         | 
| 340 | 
            +
                        if (typeof bits !== 'number') {
         | 
| 341 | 
            +
                            return '';
         | 
| 342 | 
            +
                        }
         | 
| 343 | 
            +
                        if (bits >= 1000000000) {
         | 
| 344 | 
            +
                            return (bits / 1000000000).toFixed(2) + ' Gbit/s';
         | 
| 345 | 
            +
                        }
         | 
| 346 | 
            +
                        if (bits >= 1000000) {
         | 
| 347 | 
            +
                            return (bits / 1000000).toFixed(2) + ' Mbit/s';
         | 
| 348 | 
            +
                        }
         | 
| 349 | 
            +
                        if (bits >= 1000) {
         | 
| 350 | 
            +
                            return (bits / 1000).toFixed(2) + ' kbit/s';
         | 
| 351 | 
            +
                        }
         | 
| 352 | 
            +
                        return bits + ' bit/s';
         | 
| 353 | 
            +
                    },
         | 
| 354 | 
            +
             | 
| 355 | 
            +
                    _formatTime: function (seconds) {
         | 
| 356 | 
            +
                        var date = new Date(seconds * 1000),
         | 
| 357 | 
            +
                            days = parseInt(seconds / 86400, 10);
         | 
| 358 | 
            +
                        days = days ? days + 'd ' : '';
         | 
| 359 | 
            +
                        return days +
         | 
| 360 | 
            +
                            ('0' + date.getUTCHours()).slice(-2) + ':' +
         | 
| 361 | 
            +
                            ('0' + date.getUTCMinutes()).slice(-2) + ':' +
         | 
| 362 | 
            +
                            ('0' + date.getUTCSeconds()).slice(-2);
         | 
| 363 | 
            +
                    },
         | 
| 364 | 
            +
             | 
| 365 | 
            +
                    _formatPercentage: function (floatValue) {
         | 
| 366 | 
            +
                        return (floatValue * 100).toFixed(2) + ' %';
         | 
| 367 | 
            +
                    },
         | 
| 368 | 
            +
             | 
| 369 | 
            +
                    _renderExtendedProgress: function (data) {
         | 
| 370 | 
            +
                        return this._formatBitrate(data.bitrate) + ' | ' +
         | 
| 371 | 
            +
                            this._formatTime(
         | 
| 372 | 
            +
                                (data.total - data.loaded) * 8 / data.bitrate
         | 
| 373 | 
            +
                            ) + ' | ' +
         | 
| 374 | 
            +
                            this._formatPercentage(
         | 
| 375 | 
            +
                                data.loaded / data.total
         | 
| 376 | 
            +
                            ) + ' | ' +
         | 
| 377 | 
            +
                            this._formatFileSize(data.loaded) + ' / ' +
         | 
| 378 | 
            +
                            this._formatFileSize(data.total);
         | 
| 379 | 
            +
                    },
         | 
| 380 | 
            +
             | 
| 381 | 
            +
                    _hasError: function (file) {
         | 
| 382 | 
            +
                        if (file.error) {
         | 
| 383 | 
            +
                            return file.error;
         | 
| 384 | 
            +
                        }
         | 
| 385 | 
            +
                        // The number of added files is subtracted from
         | 
| 386 | 
            +
                        // maxNumberOfFiles before validation, so we check if
         | 
| 387 | 
            +
                        // maxNumberOfFiles is below 0 (instead of below 1):
         | 
| 388 | 
            +
                        if (this.options.maxNumberOfFiles < 0) {
         | 
| 389 | 
            +
                            return 'maxNumberOfFiles';
         | 
| 390 | 
            +
                        }
         | 
| 391 | 
            +
                        // Files are accepted if either the file type or the file name
         | 
| 392 | 
            +
                        // matches against the acceptFileTypes regular expression, as
         | 
| 393 | 
            +
                        // only browsers with support for the File API report the type:
         | 
| 394 | 
            +
                        if (!(this.options.acceptFileTypes.test(file.type) ||
         | 
| 395 | 
            +
                                this.options.acceptFileTypes.test(file.name))) {
         | 
| 396 | 
            +
                            return 'acceptFileTypes';
         | 
| 397 | 
            +
                        }
         | 
| 398 | 
            +
                        if (this.options.maxFileSize &&
         | 
| 399 | 
            +
                                file.size > this.options.maxFileSize) {
         | 
| 400 | 
            +
                            return 'maxFileSize';
         | 
| 401 | 
            +
                        }
         | 
| 402 | 
            +
                        if (typeof file.size === 'number' &&
         | 
| 403 | 
            +
                                file.size < this.options.minFileSize) {
         | 
| 404 | 
            +
                            return 'minFileSize';
         | 
| 405 | 
            +
                        }
         | 
| 406 | 
            +
                        return null;
         | 
| 407 | 
            +
                    },
         | 
| 408 | 
            +
             | 
| 409 | 
            +
                    _validate: function (files) {
         | 
| 410 | 
            +
                        var that = this,
         | 
| 411 | 
            +
                            valid = !!files.length;
         | 
| 412 | 
            +
                        $.each(files, function (index, file) {
         | 
| 413 | 
            +
                            file.error = that._hasError(file);
         | 
| 414 | 
            +
                            if (file.error) {
         | 
| 415 | 
            +
                                valid = false;
         | 
| 416 | 
            +
                            }
         | 
| 417 | 
            +
                        });
         | 
| 418 | 
            +
                        return valid;
         | 
| 419 | 
            +
                    },
         | 
| 420 | 
            +
             | 
| 421 | 
            +
                    _renderTemplate: function (func, files) {
         | 
| 422 | 
            +
                        if (!func) {
         | 
| 423 | 
            +
                            return $();
         | 
| 424 | 
            +
                        }
         | 
| 425 | 
            +
                        var result = func({
         | 
| 426 | 
            +
                            files: files,
         | 
| 427 | 
            +
                            formatFileSize: this._formatFileSize,
         | 
| 428 | 
            +
                            options: this.options
         | 
| 429 | 
            +
                        });
         | 
| 430 | 
            +
                        if (result instanceof $) {
         | 
| 431 | 
            +
                            return result;
         | 
| 432 | 
            +
                        }
         | 
| 433 | 
            +
                        return $(this.options.templatesContainer).html(result).children();
         | 
| 434 | 
            +
                    },
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                    _renderPreview: function (file, node) {
         | 
| 437 | 
            +
                        var that = this,
         | 
| 438 | 
            +
                            options = this.options,
         | 
| 439 | 
            +
                            dfd = $.Deferred();
         | 
| 440 | 
            +
                        return ((loadImage && loadImage(
         | 
| 441 | 
            +
                            file,
         | 
| 442 | 
            +
                            function (img) {
         | 
| 443 | 
            +
                                node.append(img);
         | 
| 444 | 
            +
                                that._forceReflow(node);
         | 
| 445 | 
            +
                                that._transition(node).done(function () {
         | 
| 446 | 
            +
                                    dfd.resolveWith(node);
         | 
| 447 | 
            +
                                });
         | 
| 448 | 
            +
                                if (!$.contains(document.body, node[0])) {
         | 
| 449 | 
            +
                                    // If the element is not part of the DOM,
         | 
| 450 | 
            +
                                    // transition events are not triggered,
         | 
| 451 | 
            +
                                    // so we have to resolve manually:
         | 
| 452 | 
            +
                                    dfd.resolveWith(node);
         | 
| 453 | 
            +
                                }
         | 
| 454 | 
            +
                            },
         | 
| 455 | 
            +
                            {
         | 
| 456 | 
            +
                                maxWidth: options.previewMaxWidth,
         | 
| 457 | 
            +
                                maxHeight: options.previewMaxHeight,
         | 
| 458 | 
            +
                                canvas: options.previewAsCanvas
         | 
| 459 | 
            +
                            }
         | 
| 460 | 
            +
                        )) || dfd.resolveWith(node)) && dfd;
         | 
| 461 | 
            +
                    },
         | 
| 462 | 
            +
             | 
| 463 | 
            +
                    _renderPreviews: function (files, nodes) {
         | 
| 464 | 
            +
                        var that = this,
         | 
| 465 | 
            +
                            options = this.options;
         | 
| 466 | 
            +
                        nodes.find('.preview span').each(function (index, element) {
         | 
| 467 | 
            +
                            var file = files[index];
         | 
| 468 | 
            +
                            if (options.previewSourceFileTypes.test(file.type) &&
         | 
| 469 | 
            +
                                    ($.type(options.previewSourceMaxFileSize) !== 'number' ||
         | 
| 470 | 
            +
                                    file.size < options.previewSourceMaxFileSize)) {
         | 
| 471 | 
            +
                                that._processingQueue = that._processingQueue.pipe(function () {
         | 
| 472 | 
            +
                                    var dfd = $.Deferred();
         | 
| 473 | 
            +
                                    that._renderPreview(file, $(element)).done(
         | 
| 474 | 
            +
                                        function () {
         | 
| 475 | 
            +
                                            dfd.resolveWith(that);
         | 
| 476 | 
            +
                                        }
         | 
| 477 | 
            +
                                    );
         | 
| 478 | 
            +
                                    return dfd.promise();
         | 
| 479 | 
            +
                                });
         | 
| 480 | 
            +
                            }
         | 
| 481 | 
            +
                        });
         | 
| 482 | 
            +
                        return this._processingQueue;
         | 
| 483 | 
            +
                    },
         | 
| 484 | 
            +
             | 
| 485 | 
            +
                    _renderUpload: function (files) {
         | 
| 486 | 
            +
                        return this._renderTemplate(
         | 
| 487 | 
            +
                            this.options.uploadTemplate,
         | 
| 488 | 
            +
                            files
         | 
| 489 | 
            +
                        );
         | 
| 490 | 
            +
                    },
         | 
| 491 | 
            +
             | 
| 492 | 
            +
                    _renderDownload: function (files) {
         | 
| 493 | 
            +
                        return this._renderTemplate(
         | 
| 494 | 
            +
                            this.options.downloadTemplate,
         | 
| 495 | 
            +
                            files
         | 
| 496 | 
            +
                        ).find('a[download]').each(this._enableDragToDesktop).end();
         | 
| 497 | 
            +
                    },
         | 
| 498 | 
            +
             | 
| 499 | 
            +
                    _startHandler: function (e) {
         | 
| 500 | 
            +
                        e.preventDefault();
         | 
| 501 | 
            +
                        var button = $(this),
         | 
| 502 | 
            +
                            template = button.closest('.template-upload'),
         | 
| 503 | 
            +
                            data = template.data('data');
         | 
| 504 | 
            +
                        if (data && data.submit && !data.jqXHR && data.submit()) {
         | 
| 505 | 
            +
                            button.prop('disabled', true);
         | 
| 506 | 
            +
                        }
         | 
| 507 | 
            +
                    },
         | 
| 508 | 
            +
             | 
| 509 | 
            +
                    _cancelHandler: function (e) {
         | 
| 510 | 
            +
                        e.preventDefault();
         | 
| 511 | 
            +
                        var template = $(this).closest('.template-upload'),
         | 
| 512 | 
            +
                            data = template.data('data') || {};
         | 
| 513 | 
            +
                        if (!data.jqXHR) {
         | 
| 514 | 
            +
                            data.errorThrown = 'abort';
         | 
| 515 | 
            +
                            e.data.fileupload._trigger('fail', e, data);
         | 
| 516 | 
            +
                        } else {
         | 
| 517 | 
            +
                            data.jqXHR.abort();
         | 
| 518 | 
            +
                        }
         | 
| 519 | 
            +
                    },
         | 
| 520 | 
            +
             | 
| 521 | 
            +
                    _deleteHandler: function (e) {
         | 
| 522 | 
            +
                        e.preventDefault();
         | 
| 523 | 
            +
                        var button = $(this);
         | 
| 524 | 
            +
                        e.data.fileupload._trigger('destroy', e, {
         | 
| 525 | 
            +
                            context: button.closest('.template-download'),
         | 
| 526 | 
            +
                            url: button.attr('data-url'),
         | 
| 527 | 
            +
                            type: button.attr('data-type') || 'DELETE',
         | 
| 528 | 
            +
                            dataType: e.data.fileupload.options.dataType
         | 
| 529 | 
            +
                        });
         | 
| 530 | 
            +
                    },
         | 
| 531 | 
            +
             | 
| 532 | 
            +
                    _forceReflow: function (node) {
         | 
| 533 | 
            +
                        return $.support.transition && node.length &&
         | 
| 534 | 
            +
                            node[0].offsetWidth;
         | 
| 535 | 
            +
                    },
         | 
| 536 | 
            +
             | 
| 537 | 
            +
                    _transition: function (node) {
         | 
| 538 | 
            +
                        var dfd = $.Deferred();
         | 
| 539 | 
            +
                        if ($.support.transition && node.hasClass('fade')) {
         | 
| 540 | 
            +
                            node.bind(
         | 
| 541 | 
            +
                                $.support.transition.end,
         | 
| 542 | 
            +
                                function (e) {
         | 
| 543 | 
            +
                                    // Make sure we don't respond to other transitions events
         | 
| 544 | 
            +
                                    // in the container element, e.g. from button elements:
         | 
| 545 | 
            +
                                    if (e.target === node[0]) {
         | 
| 546 | 
            +
                                        node.unbind($.support.transition.end);
         | 
| 547 | 
            +
                                        dfd.resolveWith(node);
         | 
| 548 | 
            +
                                    }
         | 
| 549 | 
            +
                                }
         | 
| 550 | 
            +
                            ).toggleClass('in');
         | 
| 551 | 
            +
                        } else {
         | 
| 552 | 
            +
                            node.toggleClass('in');
         | 
| 553 | 
            +
                            dfd.resolveWith(node);
         | 
| 554 | 
            +
                        }
         | 
| 555 | 
            +
                        return dfd;
         | 
| 556 | 
            +
                    },
         | 
| 557 | 
            +
             | 
| 558 | 
            +
                    _initButtonBarEventHandlers: function () {
         | 
| 559 | 
            +
                        var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
         | 
| 560 | 
            +
                            filesList = this.options.filesContainer,
         | 
| 561 | 
            +
                            ns = this.options.namespace;
         | 
| 562 | 
            +
                        fileUploadButtonBar.find('.start')
         | 
| 563 | 
            +
                            .bind('click.' + ns, function (e) {
         | 
| 564 | 
            +
                                e.preventDefault();
         | 
| 565 | 
            +
                                filesList.find('.start button').click();
         | 
| 566 | 
            +
                            });
         | 
| 567 | 
            +
                        fileUploadButtonBar.find('.cancel')
         | 
| 568 | 
            +
                            .bind('click.' + ns, function (e) {
         | 
| 569 | 
            +
                                e.preventDefault();
         | 
| 570 | 
            +
                                filesList.find('.cancel button').click();
         | 
| 571 | 
            +
                            });
         | 
| 572 | 
            +
                        fileUploadButtonBar.find('.delete')
         | 
| 573 | 
            +
                            .bind('click.' + ns, function (e) {
         | 
| 574 | 
            +
                                e.preventDefault();
         | 
| 575 | 
            +
                                filesList.find('.delete input:checked')
         | 
| 576 | 
            +
                                    .siblings('button').click();
         | 
| 577 | 
            +
                                fileUploadButtonBar.find('.toggle')
         | 
| 578 | 
            +
                                    .prop('checked', false);
         | 
| 579 | 
            +
                            });
         | 
| 580 | 
            +
                        fileUploadButtonBar.find('.toggle')
         | 
| 581 | 
            +
                            .bind('change.' + ns, function (e) {
         | 
| 582 | 
            +
                                filesList.find('.delete input').prop(
         | 
| 583 | 
            +
                                    'checked',
         | 
| 584 | 
            +
                                    $(this).is(':checked')
         | 
| 585 | 
            +
                                );
         | 
| 586 | 
            +
                            });
         | 
| 587 | 
            +
                    },
         | 
| 588 | 
            +
             | 
| 589 | 
            +
                    _destroyButtonBarEventHandlers: function () {
         | 
| 590 | 
            +
                        this.element.find('.fileupload-buttonbar button')
         | 
| 591 | 
            +
                            .unbind('click.' + this.options.namespace);
         | 
| 592 | 
            +
                        this.element.find('.fileupload-buttonbar .toggle')
         | 
| 593 | 
            +
                            .unbind('change.' + this.options.namespace);
         | 
| 594 | 
            +
                    },
         | 
| 595 | 
            +
             | 
| 596 | 
            +
                    _initEventHandlers: function () {
         | 
| 597 | 
            +
                        parentWidget.prototype._initEventHandlers.call(this);
         | 
| 598 | 
            +
                        var eventData = {fileupload: this};
         | 
| 599 | 
            +
                        this.options.filesContainer
         | 
| 600 | 
            +
                            .delegate(
         | 
| 601 | 
            +
                                '.start button',
         | 
| 602 | 
            +
                                'click.' + this.options.namespace,
         | 
| 603 | 
            +
                                eventData,
         | 
| 604 | 
            +
                                this._startHandler
         | 
| 605 | 
            +
                            )
         | 
| 606 | 
            +
                            .delegate(
         | 
| 607 | 
            +
                                '.cancel button',
         | 
| 608 | 
            +
                                'click.' + this.options.namespace,
         | 
| 609 | 
            +
                                eventData,
         | 
| 610 | 
            +
                                this._cancelHandler
         | 
| 611 | 
            +
                            )
         | 
| 612 | 
            +
                            .delegate(
         | 
| 613 | 
            +
                                '.delete button',
         | 
| 614 | 
            +
                                'click.' + this.options.namespace,
         | 
| 615 | 
            +
                                eventData,
         | 
| 616 | 
            +
                                this._deleteHandler
         | 
| 617 | 
            +
                            );
         | 
| 618 | 
            +
                        this._initButtonBarEventHandlers();
         | 
| 619 | 
            +
                    },
         | 
| 620 | 
            +
             | 
| 621 | 
            +
                    _destroyEventHandlers: function () {
         | 
| 622 | 
            +
                        var options = this.options;
         | 
| 623 | 
            +
                        this._destroyButtonBarEventHandlers();
         | 
| 624 | 
            +
                        options.filesContainer
         | 
| 625 | 
            +
                            .undelegate('.start button', 'click.' + options.namespace)
         | 
| 626 | 
            +
                            .undelegate('.cancel button', 'click.' + options.namespace)
         | 
| 627 | 
            +
                            .undelegate('.delete button', 'click.' + options.namespace);
         | 
| 628 | 
            +
                        parentWidget.prototype._destroyEventHandlers.call(this);
         | 
| 629 | 
            +
                    },
         | 
| 630 | 
            +
             | 
| 631 | 
            +
                    _enableFileInputButton: function () {
         | 
| 632 | 
            +
                        this.element.find('.fileinput-button input')
         | 
| 633 | 
            +
                            .prop('disabled', false)
         | 
| 634 | 
            +
                            .parent().removeClass('disabled');
         | 
| 635 | 
            +
                    },
         | 
| 636 | 
            +
             | 
| 637 | 
            +
                    _disableFileInputButton: function () {
         | 
| 638 | 
            +
                        this.element.find('.fileinput-button input')
         | 
| 639 | 
            +
                            .prop('disabled', true)
         | 
| 640 | 
            +
                            .parent().addClass('disabled');
         | 
| 641 | 
            +
                    },
         | 
| 642 | 
            +
             | 
| 643 | 
            +
                    _initTemplates: function () {
         | 
| 644 | 
            +
                        var options = this.options;
         | 
| 645 | 
            +
                        options.templatesContainer = document.createElement(
         | 
| 646 | 
            +
                            options.filesContainer.prop('nodeName')
         | 
| 647 | 
            +
                        );
         | 
| 648 | 
            +
                        if (tmpl) {
         | 
| 649 | 
            +
                            if (options.uploadTemplateId) {
         | 
| 650 | 
            +
                                options.uploadTemplate = tmpl(options.uploadTemplateId);
         | 
| 651 | 
            +
                            }
         | 
| 652 | 
            +
                            if (options.downloadTemplateId) {
         | 
| 653 | 
            +
                                options.downloadTemplate = tmpl(options.downloadTemplateId);
         | 
| 654 | 
            +
                            }
         | 
| 655 | 
            +
                        }
         | 
| 656 | 
            +
                    },
         | 
| 657 | 
            +
             | 
| 658 | 
            +
                    _initFilesContainer: function () {
         | 
| 659 | 
            +
                        var options = this.options;
         | 
| 660 | 
            +
                        if (options.filesContainer === undefined) {
         | 
| 661 | 
            +
                            options.filesContainer = this.element.find('.files');
         | 
| 662 | 
            +
                        } else if (!(options.filesContainer instanceof $)) {
         | 
| 663 | 
            +
                            options.filesContainer = $(options.filesContainer);
         | 
| 664 | 
            +
                        }
         | 
| 665 | 
            +
                    },
         | 
| 666 | 
            +
             | 
| 667 | 
            +
                    _initSpecialOptions: function () {
         | 
| 668 | 
            +
                        parentWidget.prototype._initSpecialOptions.call(this);
         | 
| 669 | 
            +
                        this._initFilesContainer();
         | 
| 670 | 
            +
                        this._initTemplates();
         | 
| 671 | 
            +
                    },
         | 
| 672 | 
            +
             | 
| 673 | 
            +
                    _create: function () {
         | 
| 674 | 
            +
                        parentWidget.prototype._create.call(this);
         | 
| 675 | 
            +
                        this._refreshOptionsList.push(
         | 
| 676 | 
            +
                            'filesContainer',
         | 
| 677 | 
            +
                            'uploadTemplateId',
         | 
| 678 | 
            +
                            'downloadTemplateId'
         | 
| 679 | 
            +
                        );
         | 
| 680 | 
            +
                        if (!$.blueimpFP) {
         | 
| 681 | 
            +
                            this._processingQueue = $.Deferred().resolveWith(this).promise();
         | 
| 682 | 
            +
                            this.process = function () {
         | 
| 683 | 
            +
                                return this._processingQueue;
         | 
| 684 | 
            +
                            };
         | 
| 685 | 
            +
                        }
         | 
| 686 | 
            +
                    },
         | 
| 687 | 
            +
             | 
| 688 | 
            +
                    enable: function () {
         | 
| 689 | 
            +
                        parentWidget.prototype.enable.call(this);
         | 
| 690 | 
            +
                        this.element.find('input, button').prop('disabled', false);
         | 
| 691 | 
            +
                        this._enableFileInputButton();
         | 
| 692 | 
            +
                    },
         | 
| 693 | 
            +
             | 
| 694 | 
            +
                    disable: function () {
         | 
| 695 | 
            +
                        this.element.find('input, button').prop('disabled', true);
         | 
| 696 | 
            +
                        this._disableFileInputButton();
         | 
| 697 | 
            +
                        parentWidget.prototype.disable.call(this);
         | 
| 698 | 
            +
                    }
         | 
| 699 | 
            +
             | 
| 700 | 
            +
                });
         | 
| 701 | 
            +
             | 
| 702 | 
            +
            }));
         |