fileupload-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,723 @@
1
+ /*
2
+ * jQuery File Upload User Interface Plugin 6.9.3
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
+ .replaceAll(node);
155
+ that._forceReflow(template);
156
+ that._transition(template).done(
157
+ function () {
158
+ data.context = $(this);
159
+ that._trigger('completed', e, data);
160
+ }
161
+ );
162
+ }
163
+ );
164
+ });
165
+ } else {
166
+ template = that._renderDownload(data.result)
167
+ .appendTo(that.options.filesContainer);
168
+ that._forceReflow(template);
169
+ that._transition(template).done(
170
+ function () {
171
+ data.context = $(this);
172
+ that._trigger('completed', e, data);
173
+ }
174
+ );
175
+ }
176
+ },
177
+ // Callback for failed (abort or error) uploads:
178
+ fail: function (e, data) {
179
+ var that = $(this).data('fileupload'),
180
+ template;
181
+ that._adjustMaxNumberOfFiles(data.files.length);
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
+ that._transition($(this)).done(
189
+ function () {
190
+ var node = $(this);
191
+ template = that._renderDownload([file])
192
+ .replaceAll(node);
193
+ that._forceReflow(template);
194
+ that._transition(template).done(
195
+ function () {
196
+ data.context = $(this);
197
+ that._trigger('failed', e, data);
198
+ }
199
+ );
200
+ }
201
+ );
202
+ } else {
203
+ that._transition($(this)).done(
204
+ function () {
205
+ $(this).remove();
206
+ that._trigger('failed', e, data);
207
+ }
208
+ );
209
+ }
210
+ });
211
+ } else if (data.errorThrown !== 'abort') {
212
+ that._adjustMaxNumberOfFiles(-data.files.length);
213
+ data.context = that._renderUpload(data.files)
214
+ .appendTo(that.options.filesContainer)
215
+ .data('data', data);
216
+ that._forceReflow(data.context);
217
+ that._transition(data.context).done(
218
+ function () {
219
+ data.context = $(this);
220
+ that._trigger('failed', e, data);
221
+ }
222
+ );
223
+ } else {
224
+ that._trigger('failed', e, data);
225
+ }
226
+ },
227
+ // Callback for upload progress events:
228
+ progress: function (e, data) {
229
+ if (data.context) {
230
+ var progress = parseInt(data.loaded / data.total * 100, 10);
231
+ data.context.find('.progress')
232
+ .attr('aria-valuenow', progress)
233
+ .find('.bar').css(
234
+ 'width',
235
+ progress + '%'
236
+ );
237
+ }
238
+ },
239
+ // Callback for global upload progress events:
240
+ progressall: function (e, data) {
241
+ var $this = $(this),
242
+ progress = parseInt(data.loaded / data.total * 100, 10),
243
+ globalProgressNode = $this.find('.fileupload-progress'),
244
+ extendedProgressNode = globalProgressNode
245
+ .find('.progress-extended');
246
+ if (extendedProgressNode.length) {
247
+ extendedProgressNode.html(
248
+ $this.data('fileupload')._renderExtendedProgress(data)
249
+ );
250
+ }
251
+ globalProgressNode
252
+ .find('.progress')
253
+ .attr('aria-valuenow', progress)
254
+ .find('.bar').css(
255
+ 'width',
256
+ progress + '%'
257
+ );
258
+ },
259
+ // Callback for uploads start, equivalent to the global ajaxStart event:
260
+ start: function (e) {
261
+ var that = $(this).data('fileupload');
262
+ that._transition($(this).find('.fileupload-progress')).done(
263
+ function () {
264
+ that._trigger('started', e);
265
+ }
266
+ );
267
+ },
268
+ // Callback for uploads stop, equivalent to the global ajaxStop event:
269
+ stop: function (e) {
270
+ var that = $(this).data('fileupload');
271
+ that._transition($(this).find('.fileupload-progress')).done(
272
+ function () {
273
+ $(this).find('.progress')
274
+ .attr('aria-valuenow', '0')
275
+ .find('.bar').css('width', '0%');
276
+ $(this).find('.progress-extended').html(' ');
277
+ that._trigger('stopped', e);
278
+ }
279
+ );
280
+ },
281
+ // Callback for file deletion:
282
+ destroy: function (e, data) {
283
+ var that = $(this).data('fileupload');
284
+ if (data.url) {
285
+ $.ajax(data);
286
+ that._adjustMaxNumberOfFiles(1);
287
+ }
288
+ that._transition(data.context).done(
289
+ function () {
290
+ $(this).remove();
291
+ that._trigger('destroyed', e, data);
292
+ }
293
+ );
294
+ }
295
+ },
296
+
297
+ // Link handler, that allows to download files
298
+ // by drag & drop of the links to the desktop:
299
+ _enableDragToDesktop: function () {
300
+ var link = $(this),
301
+ url = link.prop('href'),
302
+ name = link.prop('download'),
303
+ type = 'application/octet-stream';
304
+ link.bind('dragstart', function (e) {
305
+ try {
306
+ e.originalEvent.dataTransfer.setData(
307
+ 'DownloadURL',
308
+ [type, name, url].join(':')
309
+ );
310
+ } catch (err) {}
311
+ });
312
+ },
313
+
314
+ _adjustMaxNumberOfFiles: function (operand) {
315
+ if (typeof this.options.maxNumberOfFiles === 'number') {
316
+ this.options.maxNumberOfFiles += operand;
317
+ if (this.options.maxNumberOfFiles < 1) {
318
+ this._disableFileInputButton();
319
+ } else {
320
+ this._enableFileInputButton();
321
+ }
322
+ }
323
+ },
324
+
325
+ _formatFileSize: function (bytes) {
326
+ if (typeof bytes !== 'number') {
327
+ return '';
328
+ }
329
+ if (bytes >= 1000000000) {
330
+ return (bytes / 1000000000).toFixed(2) + ' GB';
331
+ }
332
+ if (bytes >= 1000000) {
333
+ return (bytes / 1000000).toFixed(2) + ' MB';
334
+ }
335
+ return (bytes / 1000).toFixed(2) + ' KB';
336
+ },
337
+
338
+ _formatBitrate: function (bits) {
339
+ if (typeof bits !== 'number') {
340
+ return '';
341
+ }
342
+ if (bits >= 1000000000) {
343
+ return (bits / 1000000000).toFixed(2) + ' Gbit/s';
344
+ }
345
+ if (bits >= 1000000) {
346
+ return (bits / 1000000).toFixed(2) + ' Mbit/s';
347
+ }
348
+ if (bits >= 1000) {
349
+ return (bits / 1000).toFixed(2) + ' kbit/s';
350
+ }
351
+ return bits + ' bit/s';
352
+ },
353
+
354
+ _formatTime: function (seconds) {
355
+ var date = new Date(seconds * 1000),
356
+ days = parseInt(seconds / 86400, 10);
357
+ days = days ? days + 'd ' : '';
358
+ return days +
359
+ ('0' + date.getUTCHours()).slice(-2) + ':' +
360
+ ('0' + date.getUTCMinutes()).slice(-2) + ':' +
361
+ ('0' + date.getUTCSeconds()).slice(-2);
362
+ },
363
+
364
+ _formatPercentage: function (floatValue) {
365
+ return (floatValue * 100).toFixed(2) + ' %';
366
+ },
367
+
368
+ _renderExtendedProgress: function (data) {
369
+ return this._formatBitrate(data.bitrate) + ' | ' +
370
+ this._formatTime(
371
+ (data.total - data.loaded) * 8 / data.bitrate
372
+ ) + ' | ' +
373
+ this._formatPercentage(
374
+ data.loaded / data.total
375
+ ) + ' | ' +
376
+ this._formatFileSize(data.loaded) + ' / ' +
377
+ this._formatFileSize(data.total);
378
+ },
379
+
380
+ _hasError: function (file) {
381
+ if (file.error) {
382
+ return file.error;
383
+ }
384
+ // The number of added files is subtracted from
385
+ // maxNumberOfFiles before validation, so we check if
386
+ // maxNumberOfFiles is below 0 (instead of below 1):
387
+ if (this.options.maxNumberOfFiles < 0) {
388
+ return 'maxNumberOfFiles';
389
+ }
390
+ // Files are accepted if either the file type or the file name
391
+ // matches against the acceptFileTypes regular expression, as
392
+ // only browsers with support for the File API report the type:
393
+ if (!(this.options.acceptFileTypes.test(file.type) ||
394
+ this.options.acceptFileTypes.test(file.name))) {
395
+ return 'acceptFileTypes';
396
+ }
397
+ if (this.options.maxFileSize &&
398
+ file.size > this.options.maxFileSize) {
399
+ return 'maxFileSize';
400
+ }
401
+ if (typeof file.size === 'number' &&
402
+ file.size < this.options.minFileSize) {
403
+ return 'minFileSize';
404
+ }
405
+ return null;
406
+ },
407
+
408
+ _validate: function (files) {
409
+ var that = this,
410
+ valid = !!files.length;
411
+ $.each(files, function (index, file) {
412
+ file.error = that._hasError(file);
413
+ if (file.error) {
414
+ valid = false;
415
+ }
416
+ });
417
+ return valid;
418
+ },
419
+
420
+ _renderTemplate: function (func, files) {
421
+ if (!func) {
422
+ return $();
423
+ }
424
+ var result = func({
425
+ files: files,
426
+ formatFileSize: this._formatFileSize,
427
+ options: this.options
428
+ });
429
+ if (result instanceof $) {
430
+ return result;
431
+ }
432
+ return $(this.options.templatesContainer).html(result).children();
433
+ },
434
+
435
+ _renderPreview: function (file, node) {
436
+ var that = this,
437
+ options = this.options,
438
+ dfd = $.Deferred();
439
+ return ((loadImage && loadImage(
440
+ file,
441
+ function (img) {
442
+ node.append(img);
443
+ that._forceReflow(node);
444
+ that._transition(node).done(function () {
445
+ dfd.resolveWith(node);
446
+ });
447
+ if (!$.contains(document.body, node[0])) {
448
+ // If the element is not part of the DOM,
449
+ // transition events are not triggered,
450
+ // so we have to resolve manually:
451
+ dfd.resolveWith(node);
452
+ }
453
+ },
454
+ {
455
+ maxWidth: options.previewMaxWidth,
456
+ maxHeight: options.previewMaxHeight,
457
+ canvas: options.previewAsCanvas
458
+ }
459
+ )) || dfd.resolveWith(node)) && dfd;
460
+ },
461
+
462
+ _renderPreviews: function (files, nodes) {
463
+ var that = this,
464
+ options = this.options;
465
+ nodes.find('.preview span').each(function (index, element) {
466
+ var file = files[index];
467
+ if (options.previewSourceFileTypes.test(file.type) &&
468
+ ($.type(options.previewSourceMaxFileSize) !== 'number' ||
469
+ file.size < options.previewSourceMaxFileSize)) {
470
+ that._processingQueue = that._processingQueue.pipe(function () {
471
+ var dfd = $.Deferred();
472
+ that._renderPreview(file, $(element)).done(
473
+ function () {
474
+ dfd.resolveWith(that);
475
+ }
476
+ );
477
+ return dfd.promise();
478
+ });
479
+ }
480
+ });
481
+ return this._processingQueue;
482
+ },
483
+
484
+ _renderUpload: function (files) {
485
+ return this._renderTemplate(
486
+ this.options.uploadTemplate,
487
+ files
488
+ );
489
+ },
490
+
491
+ _renderDownload: function (files) {
492
+ return this._renderTemplate(
493
+ this.options.downloadTemplate,
494
+ files
495
+ ).find('a[download]').each(this._enableDragToDesktop).end();
496
+ },
497
+
498
+ _startHandler: function (e) {
499
+ e.preventDefault();
500
+ var button = $(this),
501
+ template = button.closest('.template-upload'),
502
+ data = template.data('data');
503
+ if (data && data.submit && !data.jqXHR && data.submit()) {
504
+ button.prop('disabled', true);
505
+ }
506
+ },
507
+
508
+ _cancelHandler: function (e) {
509
+ e.preventDefault();
510
+ var template = $(this).closest('.template-upload'),
511
+ data = template.data('data') || {};
512
+ if (!data.jqXHR) {
513
+ data.errorThrown = 'abort';
514
+ e.data.fileupload._trigger('fail', e, data);
515
+ } else {
516
+ data.jqXHR.abort();
517
+ }
518
+ },
519
+
520
+ _deleteHandler: function (e) {
521
+ e.preventDefault();
522
+ var button = $(this);
523
+ e.data.fileupload._trigger('destroy', e, {
524
+ context: button.closest('.template-download'),
525
+ url: button.attr('data-url'),
526
+ type: button.attr('data-type') || 'DELETE',
527
+ dataType: e.data.fileupload.options.dataType
528
+ });
529
+ },
530
+
531
+ _forceReflow: function (node) {
532
+ return $.support.transition && node.length &&
533
+ node[0].offsetWidth;
534
+ },
535
+
536
+ _transition: function (node) {
537
+ var dfd = $.Deferred();
538
+ if ($.support.transition && node.hasClass('fade')) {
539
+ node.bind(
540
+ $.support.transition.end,
541
+ function (e) {
542
+ // Make sure we don't respond to other transitions events
543
+ // in the container element, e.g. from button elements:
544
+ if (e.target === node[0]) {
545
+ node.unbind($.support.transition.end);
546
+ dfd.resolveWith(node);
547
+ }
548
+ }
549
+ ).toggleClass('in');
550
+ } else {
551
+ node.toggleClass('in');
552
+ dfd.resolveWith(node);
553
+ }
554
+ return dfd;
555
+ },
556
+
557
+ _initButtonBarEventHandlers: function () {
558
+ var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
559
+ filesList = this.options.filesContainer,
560
+ ns = this.options.namespace;
561
+ fileUploadButtonBar.find('.start')
562
+ .bind('click.' + ns, function (e) {
563
+ e.preventDefault();
564
+ filesList.find('.start button').click();
565
+ });
566
+ fileUploadButtonBar.find('.cancel')
567
+ .bind('click.' + ns, function (e) {
568
+ e.preventDefault();
569
+ filesList.find('.cancel button').click();
570
+ });
571
+ fileUploadButtonBar.find('.delete')
572
+ .bind('click.' + ns, function (e) {
573
+ e.preventDefault();
574
+ filesList.find('.delete input:checked')
575
+ .siblings('button').click();
576
+ fileUploadButtonBar.find('.toggle')
577
+ .prop('checked', false);
578
+ });
579
+ fileUploadButtonBar.find('.toggle')
580
+ .bind('change.' + ns, function (e) {
581
+ filesList.find('.delete input').prop(
582
+ 'checked',
583
+ $(this).is(':checked')
584
+ );
585
+ });
586
+ },
587
+
588
+ _destroyButtonBarEventHandlers: function () {
589
+ this.element.find('.fileupload-buttonbar button')
590
+ .unbind('click.' + this.options.namespace);
591
+ this.element.find('.fileupload-buttonbar .toggle')
592
+ .unbind('change.' + this.options.namespace);
593
+ },
594
+
595
+ _initEventHandlers: function () {
596
+ parentWidget.prototype._initEventHandlers.call(this);
597
+ var eventData = {fileupload: this};
598
+ this.options.filesContainer
599
+ .delegate(
600
+ '.start button',
601
+ 'click.' + this.options.namespace,
602
+ eventData,
603
+ this._startHandler
604
+ )
605
+ .delegate(
606
+ '.cancel button',
607
+ 'click.' + this.options.namespace,
608
+ eventData,
609
+ this._cancelHandler
610
+ )
611
+ .delegate(
612
+ '.delete button',
613
+ 'click.' + this.options.namespace,
614
+ eventData,
615
+ this._deleteHandler
616
+ );
617
+ this._initButtonBarEventHandlers();
618
+ },
619
+
620
+ _destroyEventHandlers: function () {
621
+ var options = this.options;
622
+ this._destroyButtonBarEventHandlers();
623
+ options.filesContainer
624
+ .undelegate('.start button', 'click.' + options.namespace)
625
+ .undelegate('.cancel button', 'click.' + options.namespace)
626
+ .undelegate('.delete button', 'click.' + options.namespace);
627
+ parentWidget.prototype._destroyEventHandlers.call(this);
628
+ },
629
+
630
+ _enableFileInputButton: function () {
631
+ this.element.find('.fileinput-button input')
632
+ .prop('disabled', false)
633
+ .parent().removeClass('disabled');
634
+ },
635
+
636
+ _disableFileInputButton: function () {
637
+ this.element.find('.fileinput-button input')
638
+ .prop('disabled', true)
639
+ .parent().addClass('disabled');
640
+ },
641
+
642
+ _initTemplates: function () {
643
+ var options = this.options;
644
+ options.templatesContainer = document.createElement(
645
+ options.filesContainer.prop('nodeName')
646
+ );
647
+ if (tmpl) {
648
+ if (options.uploadTemplateId) {
649
+ options.uploadTemplate = tmpl(options.uploadTemplateId);
650
+ }
651
+ if (options.downloadTemplateId) {
652
+ options.downloadTemplate = tmpl(options.downloadTemplateId);
653
+ }
654
+ }
655
+ },
656
+
657
+ _initFilesContainer: function () {
658
+ var options = this.options;
659
+ if (options.filesContainer === undefined) {
660
+ options.filesContainer = this.element.find('.files');
661
+ } else if (!(options.filesContainer instanceof $)) {
662
+ options.filesContainer = $(options.filesContainer);
663
+ }
664
+ },
665
+
666
+ _stringToRegExp: function (str) {
667
+ var parts = str.split('/'),
668
+ modifiers = parts.pop();
669
+ parts.shift();
670
+ return new RegExp(parts.join('/'), modifiers);
671
+ },
672
+
673
+ _initRegExpOptions: function () {
674
+ var options = this.options;
675
+ if ($.type(options.acceptFileTypes) === 'string') {
676
+ options.acceptFileTypes = this._stringToRegExp(
677
+ options.acceptFileTypes
678
+ );
679
+ }
680
+ if ($.type(options.previewSourceFileTypes) === 'string') {
681
+ options.previewSourceFileTypes = this._stringToRegExp(
682
+ options.previewSourceFileTypes
683
+ );
684
+ }
685
+ },
686
+
687
+ _initSpecialOptions: function () {
688
+ parentWidget.prototype._initSpecialOptions.call(this);
689
+ this._initFilesContainer();
690
+ this._initTemplates();
691
+ this._initRegExpOptions();
692
+ },
693
+
694
+ _create: function () {
695
+ parentWidget.prototype._create.call(this);
696
+ this._refreshOptionsList.push(
697
+ 'filesContainer',
698
+ 'uploadTemplateId',
699
+ 'downloadTemplateId'
700
+ );
701
+ if (!$.blueimpFP) {
702
+ this._processingQueue = $.Deferred().resolveWith(this).promise();
703
+ this.process = function () {
704
+ return this._processingQueue;
705
+ };
706
+ }
707
+ },
708
+
709
+ enable: function () {
710
+ parentWidget.prototype.enable.call(this);
711
+ this.element.find('input, button').prop('disabled', false);
712
+ this._enableFileInputButton();
713
+ },
714
+
715
+ disable: function () {
716
+ this.element.find('input, button').prop('disabled', true);
717
+ this._disableFileInputButton();
718
+ parentWidget.prototype.disable.call(this);
719
+ }
720
+
721
+ });
722
+
723
+ }));