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