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