Dotclear

source: admin/js/jsUpload/jquery.fileupload-ui.js @ 1188:7867c72294e6

Revision 1188:7867c72294e6, 24.6 KB checked in by Sogos <thibault.cordier@…>, 12 years ago (diff)

Revert lib.dc.page.php
Masquage dynamique lors d un envoi du bouton

Line 
1/*
2 * jQuery File Upload User Interface Plugin 8.2.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, 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            './jquery.fileupload-resize',
23            './jquery.fileupload-validate'
24        ], factory);
25    } else {
26        // Browser globals:
27        factory(
28            window.jQuery,
29            window.tmpl
30        );
31    }
32}(function ($, tmpl, loadImage) {
33    'use strict';
34
35    $.blueimp.fileupload.prototype._specialOptions.push(
36        'filesContainer',
37        'uploadTemplateId',
38        'downloadTemplateId'
39    );
40
41    // The UI version extends the file upload widget
42    // and adds complete user interface interaction:
43    $.widget('blueimp.fileupload', $.blueimp.fileupload, {
44
45        options: {
46            // By default, files added to the widget are uploaded as soon
47            // as the user clicks on the start buttons. To enable automatic
48            // uploads, set the following option to true:
49            autoUpload: false,
50            // The ID of the upload template:
51            uploadTemplateId: 'template-upload',
52            // The ID of the download template:
53            downloadTemplateId: 'template-download',
54            // The container for the list of files. If undefined, it is set to
55            // an element with class "files" inside of the widget element:
56            filesContainer: undefined,
57            // By default, files are appended to the files container.
58            // Set the following option to true, to prepend files instead:
59            prependFiles: false,
60            // The expected data type of the upload response, sets the dataType
61            // option of the $.ajax upload requests:
62            dataType: 'json',
63
64            // Function returning the current number of files,
65            // used by the maxNumberOfFiles validation:
66            getNumberOfFiles: function () {
67                return this.filesContainer.children().length;
68            },
69
70            // Callback to retrieve the list of files from the server response:
71            getFilesFromResponse: function (data) {
72                if (data.result && $.isArray(data.result.files)) {
73                    return data.result.files;
74                }
75                return [];
76            },
77
78            // The add callback is invoked as soon as files are added to the fileupload
79            // widget (via file input selection, drag & drop or add API call).
80            // See the basic file upload widget for more information:
81            add: function (e, data) {
82                var $this = $(this),
83                    that = $this.data('blueimp-fileupload') ||
84                        $this.data('fileupload'),
85                    options = that.options,
86                    files = data.files;
87                data.process(function () {
88                    return $this.fileupload('process', data);
89                }).always(function () {
90                    data.context = that._renderUpload(files).data('data', data);
91                    that._renderPreviews(data);
92                    options.filesContainer[
93                        options.prependFiles ? 'prepend' : 'append'
94                    ](data.context);
95                    that._forceReflow(data.context);
96                    that._transition(data.context).done(
97                        function () {
98                            if ((that._trigger('added', e, data) !== false) &&
99                                    (options.autoUpload || data.autoUpload) &&
100                                    data.autoUpload !== false && !data.files.error) {
101                                data.submit();
102                            }
103                        }
104                    );
105                });
106            },
107            // Callback for the start of each file upload request:
108            send: function (e, data) {
109                $(this).find('.start').hide();
110                var that = $(this).data('blueimp-fileupload') ||
111                        $(this).data('fileupload');
112                if (data.context && data.dataType &&
113                        data.dataType.substr(0, 6) === 'iframe') {
114                    // Iframe Transport does not support progress events.
115                    // In lack of an indeterminate progress bar, we set
116                    // the progress to 100%, showing the full animated bar:
117                    data.context
118                        .find('.progress').addClass(
119                            !$.support.transition && 'progress-animated'
120                        )
121                        .attr('aria-valuenow', 100)
122                        .find('.bar').css(
123                            'width',
124                            '100%'
125                        );
126                }
127                return that._trigger('sent', e, data);
128            },
129            // Callback for successful uploads:
130            done: function (e, data) {
131
132                var that = $(this).data('blueimp-fileupload') ||
133                        $(this).data('fileupload'),
134                    getFilesFromResponse = data.getFilesFromResponse ||
135                        that.options.getFilesFromResponse,
136                    files = getFilesFromResponse(data),
137                    template,
138                    deferred;
139                if (data.context) {
140                    data.context.each(function (index) {
141                        var file = files[index] ||
142                                {error: 'Empty file upload result'},
143                            deferred = that._addFinishedDeferreds();
144                        that._transition($(this)).done(
145                            function () {
146                                var node = $(this);
147                                template = that._renderDownload([file])
148                                    .replaceAll(node);
149                                that._forceReflow(template);
150                                that._transition(template).done(
151                                    function () {
152                                        data.context = $(this);
153                                        that._trigger('completed', e, data);
154                                        that._trigger('finished', e, data);
155                                        deferred.resolve();
156                                    }
157                                );
158                            }
159                        );
160                    });
161                } else {
162                    template = that._renderDownload(files)
163                        .appendTo(that.options.filesContainer);
164                    that._forceReflow(template);
165                    deferred = that._addFinishedDeferreds();
166                    that._transition(template).done(
167                        function () {
168                            data.context = $(this);
169                            that._trigger('completed', e, data);
170                            that._trigger('finished', e, data);
171                            deferred.resolve();
172                        }
173                    );
174                }
175            },
176            // Callback for failed (abort or error) uploads:
177            fail: function (e, data) {
178                var that = $(this).data('blueimp-fileupload') ||
179                        $(this).data('fileupload'),
180                    template,
181                    deferred;
182                if (data.context) {
183                    data.context.each(function (index) {
184                        if (data.errorThrown !== 'abort') {
185                            var file = data.files[index];
186                            file.error = file.error || data.errorThrown ||
187                                true;
188                            deferred = that._addFinishedDeferreds();
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                                            that._trigger('finished', e, data);
200                                            deferred.resolve();
201                                        }
202                                    );
203                                }
204                            );
205                        } else {
206                            deferred = that._addFinishedDeferreds();
207                            that._transition($(this)).done(
208                                function () {
209                                    $(this).remove();
210                                    that._trigger('failed', e, data);
211                                    that._trigger('finished', e, data);
212                                    deferred.resolve();
213                                }
214                            );
215                        }
216                    });
217                } else if (data.errorThrown !== 'abort') {
218                    data.context = that._renderUpload(data.files)
219                        .appendTo(that.options.filesContainer)
220                        .data('data', data);
221                    that._forceReflow(data.context);
222                    deferred = that._addFinishedDeferreds();
223                    that._transition(data.context).done(
224                        function () {
225                            data.context = $(this);
226                            that._trigger('failed', e, data);
227                            that._trigger('finished', e, data);
228                            deferred.resolve();
229                        }
230                    );
231                } else {
232                    that._trigger('failed', e, data);
233                    that._trigger('finished', e, data);
234                    that._addFinishedDeferreds().resolve();
235                }
236            },
237            // Callback for upload progress events:
238            progress: function (e, data) {
239                if (data.context) {
240                    var progress = Math.floor(data.loaded / data.total * 100);
241                    data.context.find('.progress')
242                        .attr('aria-valuenow', progress)
243                        .find('.bar').css(
244                            'width',
245                            progress + '%'
246                        );
247                }
248            },
249            // Callback for global upload progress events:
250            progressall: function (e, data) {
251                var $this = $(this),
252                    progress = Math.floor(data.loaded / data.total * 100),
253                    globalProgressNode = $this.find('.fileupload-progress'),
254                    extendedProgressNode = globalProgressNode
255                        .find('.progress-extended');
256                if (extendedProgressNode.length) {
257                    extendedProgressNode.html(
258                        ($this.data('blueimp-fileupload') || $this.data('fileupload'))
259                            ._renderExtendedProgress(data)
260                    );
261                }
262                globalProgressNode
263                    .find('.progress')
264                    .attr('aria-valuenow', progress)
265                    .find('.bar').css(
266                        'width',
267                        progress + '%'
268                    );
269            },
270            // Callback for uploads start, equivalent to the global ajaxStart event:
271            start: function (e) {
272                var that = $(this).data('blueimp-fileupload') ||
273                $(this).find('.start').hide();
274                that._resetFinishedDeferreds();
275                that._transition($(this).find('.fileupload-progress')).done(
276
277                    function () {
278
279                        that._trigger('started', e);
280                    }
281                );
282            },
283            // Callback for uploads stop, equivalent to the global ajaxStop event:
284            stop: function (e) {
285                $(this).find('.start').show();
286                var that = $(this).data('blueimp-fileupload') ||
287                        $(this).data('fileupload'),
288                    deferred = that._addFinishedDeferreds();
289                $.when.apply($, that._getFinishedDeferreds())
290                    .done(function () {
291                        that._trigger('stopped', e);
292                    });
293                that._transition($(this).find('.fileupload-progress')).done(
294                    function () {
295                        $(this).find('.progress')
296                            .attr('aria-valuenow', '0')
297                            .find('.bar').css('width', '0%');
298                        $(this).find('.progress-extended').html('&nbsp;');
299                        deferred.resolve();
300                    }
301                );
302            },
303            processstart: function () {
304                $(this).addClass('fileupload-processing');
305            },
306            processstop: function () {
307                $(this).removeClass('fileupload-processing');
308            },
309            // Callback for file deletion:
310            destroy: function (e, data) {
311                var that = $(this).data('blueimp-fileupload') ||
312                        $(this).data('fileupload');
313                if (data.url) {
314                    $.ajax(data).done(function () {
315                        that._transition(data.context).done(
316                            function () {
317                                $(this).remove();
318                                that._trigger('destroyed', e, data);
319                            }
320                        );
321                    });
322                }
323            }
324        },
325
326        _resetFinishedDeferreds: function () {
327            this._finishedUploads = [];
328        },
329
330        _addFinishedDeferreds: function (deferred) {
331            if (!deferred) {
332                deferred = $.Deferred();
333            }
334            this._finishedUploads.push(deferred);
335            return deferred;
336        },
337
338        _getFinishedDeferreds: function () {
339            return this._finishedUploads;
340        },
341
342        // Link handler, that allows to download files
343        // by drag & drop of the links to the desktop:
344        _enableDragToDesktop: function () {
345            var link = $(this),
346                url = link.prop('href'),
347                name = link.prop('download'),
348                type = 'application/octet-stream';
349            link.bind('dragstart', function (e) {
350                try {
351                    e.originalEvent.dataTransfer.setData(
352                        'DownloadURL',
353                        [type, name, url].join(':')
354                    );
355                } catch (ignore) {}
356            });
357        },
358
359        _formatFileSize: function (bytes) {
360            if (typeof bytes !== 'number') {
361                return '';
362            }
363            if (bytes >= 1000000000) {
364                return (bytes / 1000000000).toFixed(2) + ' GB';
365            }
366            if (bytes >= 1000000) {
367                return (bytes / 1000000).toFixed(2) + ' MB';
368            }
369            return (bytes / 1000).toFixed(2) + ' KB';
370        },
371
372        _formatBitrate: function (bits) {
373            if (typeof bits !== 'number') {
374                return '';
375            }
376            if (bits >= 1000000000) {
377                return (bits / 1000000000).toFixed(2) + ' Gbit/s';
378            }
379            if (bits >= 1000000) {
380                return (bits / 1000000).toFixed(2) + ' Mbit/s';
381            }
382            if (bits >= 1000) {
383                return (bits / 1000).toFixed(2) + ' kbit/s';
384            }
385            return bits.toFixed(2) + ' bit/s';
386        },
387
388        _formatTime: function (seconds) {
389            var date = new Date(seconds * 1000),
390                days = Math.floor(seconds / 86400);
391            days = days ? days + 'd ' : '';
392            return days +
393                ('0' + date.getUTCHours()).slice(-2) + ':' +
394                ('0' + date.getUTCMinutes()).slice(-2) + ':' +
395                ('0' + date.getUTCSeconds()).slice(-2);
396        },
397
398        _formatPercentage: function (floatValue) {
399            return (floatValue * 100).toFixed(2) + ' %';
400        },
401
402        _renderExtendedProgress: function (data) {
403            return this._formatBitrate(data.bitrate) + ' | ' +
404                this._formatTime(
405                    (data.total - data.loaded) * 8 / data.bitrate
406                ) + ' | ' +
407                this._formatPercentage(
408                    data.loaded / data.total
409                ) + ' | ' +
410                this._formatFileSize(data.loaded) + ' / ' +
411                this._formatFileSize(data.total);
412        },
413
414        _renderTemplate: function (func, files) {
415            if (!func) {
416                return $();
417            }
418            var result = func({
419                files: files,
420                formatFileSize: this._formatFileSize,
421                options: this.options
422            });
423            if (result instanceof $) {
424                return result;
425            }
426            return $(this.options.templatesContainer).html(result).children();
427        },
428
429        _renderPreviews: function (data) {
430            data.context.find('.preview').each(function (index, elm) {
431                $(elm).append(data.files[index].preview);
432            });
433        },
434
435        _renderUpload: function (files) {
436            return this._renderTemplate(
437                this.options.uploadTemplate,
438                files
439            );
440        },
441
442        _renderDownload: function (files) {
443            return this._renderTemplate(
444                this.options.downloadTemplate,
445                files
446            ).find('a[download]').each(this._enableDragToDesktop).end();
447        },
448
449        _startHandler: function (e) {
450            e.preventDefault();
451            var button = $(e.currentTarget),
452                template = button.closest('.template-upload'),
453                data = template.data('data');
454            if (data && data.submit && !data.jqXHR && data.submit()) {
455                button.prop('disabled', true);
456            }
457        },
458
459        _cancelHandler: function (e) {
460            e.preventDefault();
461            var template = $(e.currentTarget).closest('.template-upload'),
462                data = template.data('data') || {};
463            if (!data.jqXHR) {
464                data.errorThrown = 'abort';
465                this._trigger('fail', e, data);
466            } else {
467                data.jqXHR.abort();
468            }
469        },
470
471        _deleteHandler: function (e) {
472            e.preventDefault();
473            var button = $(e.currentTarget);
474            this._trigger('destroy', e, $.extend({
475                context: button.closest('.template-download'),
476                type: 'DELETE'
477            }, button.data()));
478        },
479
480        _forceReflow: function (node) {
481            return $.support.transition && node.length &&
482                node[0].offsetWidth;
483        },
484
485        _transition: function (node) {
486            var dfd = $.Deferred();
487            if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
488                node.bind(
489                    $.support.transition.end,
490                    function (e) {
491                        // Make sure we don't respond to other transitions events
492                        // in the container element, e.g. from button elements:
493                        if (e.target === node[0]) {
494                            node.unbind($.support.transition.end);
495                            dfd.resolveWith(node);
496                        }
497                    }
498                ).toggleClass('in');
499            } else {
500                node.toggleClass('in');
501                dfd.resolveWith(node);
502            }
503            return dfd;
504        },
505
506        _initButtonBarEventHandlers: function () {
507            var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
508                filesList = this.options.filesContainer;
509            this._on(fileUploadButtonBar.find('.start'), {
510                click: function (e) {
511                    e.preventDefault();
512                    filesList.find('.start').click();
513                }
514            });
515            this._on(fileUploadButtonBar.find('.cancel'), {
516                click: function (e) {
517                    e.preventDefault();
518                    filesList.find('.cancel').click();
519                }
520            });
521            this._on(fileUploadButtonBar.find('.delete'), {
522                click: function (e) {
523                    e.preventDefault();
524                    filesList.find('.toggle:checked')
525                        .closest('.template-download')
526                        .find('.delete').click();
527                    fileUploadButtonBar.find('.toggle')
528                        .prop('checked', false);
529                }
530            });
531            this._on(fileUploadButtonBar.find('.toggle'), {
532                change: function (e) {
533                    filesList.find('.toggle').prop(
534                        'checked',
535                        $(e.currentTarget).is(':checked')
536                    );
537                }
538            });
539        },
540
541        _destroyButtonBarEventHandlers: function () {
542            this._off(
543                this.element.find('.fileupload-buttonbar')
544                    .find('.start, .cancel, .delete'),
545                'click'
546            );
547            this._off(
548                this.element.find('.fileupload-buttonbar .toggle'),
549                'change.'
550            );
551        },
552
553        _initEventHandlers: function () {
554            this._super();
555            this._on(this.options.filesContainer, {
556                'click .start': this._startHandler,
557                'click .cancel': this._cancelHandler,
558                'click .delete': this._deleteHandler
559            });
560            this._initButtonBarEventHandlers();
561        },
562
563        _destroyEventHandlers: function () {
564            this._destroyButtonBarEventHandlers();
565            this._off(this.options.filesContainer, 'click');
566            this._super();
567        },
568
569        _enableFileInputButton: function () {
570            this.element.find('.fileinput-button input')
571                .prop('disabled', false)
572                .parent().removeClass('disabled');
573        },
574
575        _disableFileInputButton: function () {
576            this.element.find('.fileinput-button input')
577                .prop('disabled', true)
578                .parent().addClass('disabled');
579        },
580
581        _initTemplates: function () {
582            var options = this.options;
583            options.templatesContainer = this.document[0].createElement(
584                options.filesContainer.prop('nodeName')
585            );
586            if (tmpl) {
587                if (options.uploadTemplateId) {
588                    options.uploadTemplate = tmpl(options.uploadTemplateId);
589                }
590                if (options.downloadTemplateId) {
591                    options.downloadTemplate = tmpl(options.downloadTemplateId);
592                }
593            }
594        },
595
596        _initFilesContainer: function () {
597            var options = this.options;
598            if (options.filesContainer === undefined) {
599                options.filesContainer = this.element.find('.files');
600            } else if (!(options.filesContainer instanceof $)) {
601                options.filesContainer = $(options.filesContainer);
602            }
603        },
604
605        _initSpecialOptions: function () {
606            this._super();
607            this._initFilesContainer();
608            this._initTemplates();
609        },
610
611        _create: function () {
612            this._super();
613            this._resetFinishedDeferreds();
614        },
615
616        enable: function () {
617            var wasDisabled = false;
618            if (this.options.disabled) {
619                wasDisabled = true;
620            }
621            this._super();
622            if (wasDisabled) {
623                this.element.find('input, button').prop('disabled', false);
624                this._enableFileInputButton();
625            }
626        },
627
628        disable: function () {
629            if (!this.options.disabled) {
630                this.element.find('input, button').prop('disabled', true);
631                this._disableFileInputButton();
632            }
633            this._super();
634        }
635
636    });
637
638}));
Note: See TracBrowser for help on using the repository browser.

Sites map