card-mod-script 0.13.4 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/assets/script/decko/components.js.coffee +3 -0
  3. data/assets/script/decko/decko.js.coffee +0 -15
  4. data/assets/script/decko/editor.js.coffee +3 -1
  5. data/assets/script/decko/filter.js.coffee +13 -6
  6. data/assets/script/decko/mod.js.coffee +2 -8
  7. data/assets/script/{script_pointer_config.js.coffee → decko/pointer_config.js.coffee} +1 -2
  8. data/assets/script/{script_pointer_list_editor.js.coffee → decko/pointer_list_editor.js.coffee} +0 -0
  9. data/assets/script/decko/slot.js.coffee +2 -2
  10. data/assets/script/decko/slot_ready.js.coffee +1 -0
  11. data/assets/script/decko/slotter.js.coffee +23 -31
  12. data/assets/script/decko/type_editor.js.coffee +21 -0
  13. data/assets/script/decko/upload.js.coffee +12 -5
  14. data/assets/script/manifest.yml +15 -2
  15. data/set/abstract/00_script.rb +30 -31
  16. data/set/abstract/01_asset_script.rb +0 -16
  17. data/set/abstract/{script_asset_list.rb → script_group.rb} +12 -13
  18. data/set/all/head_javascript.rb +4 -5
  19. data/set/right/script.rb +1 -14
  20. data/set/type/local_script_folder_group.rb +2 -2
  21. data/set/type/local_script_manifest_group.rb +1 -1
  22. data/set/type_plus_right/mod/script.rb +56 -0
  23. data/set/type_plus_right/set/script.rb +7 -0
  24. data/vendor/jquery_file_upload/LICENSE.txt +11 -12
  25. data/vendor/jquery_file_upload/README.md +189 -72
  26. data/vendor/jquery_file_upload/SECURITY.md +227 -0
  27. data/vendor/jquery_file_upload/VULNERABILITIES.md +118 -0
  28. data/vendor/jquery_file_upload/cors/postmessage.html +68 -58
  29. data/vendor/jquery_file_upload/cors/result.html +12 -10
  30. data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +24 -13
  31. data/vendor/jquery_file_upload/css/jquery.fileupload.css +3 -4
  32. data/vendor/jquery_file_upload/docker-compose.yml +55 -0
  33. data/vendor/jquery_file_upload/index.html +332 -230
  34. data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +109 -109
  35. data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +81 -73
  36. data/vendor/jquery_file_upload/js/demo.js +75 -0
  37. data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +82 -94
  38. data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +321 -300
  39. data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +138 -146
  40. data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +737 -692
  41. data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +91 -97
  42. data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +82 -94
  43. data/vendor/jquery_file_upload/js/jquery.fileupload.js +1569 -1451
  44. data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +208 -205
  45. data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +397 -340
  46. data/vendor/jquery_file_upload/package-lock.json +6853 -0
  47. data/vendor/jquery_file_upload/package.json +71 -10
  48. data/vendor/jquery_file_upload/server/gae-python/app.yaml +11 -10
  49. data/vendor/jquery_file_upload/server/php/Dockerfile +23 -17
  50. data/vendor/jquery_file_upload/server/php/UploadHandler.php +206 -137
  51. data/vendor/jquery_file_upload/server/php/php.ini +5 -0
  52. data/vendor/jquery_file_upload/test/index.html +36 -159
  53. data/vendor/jquery_file_upload/test/unit.js +989 -0
  54. data/vendor/jquery_file_upload/test/vendor/chai.js +10854 -0
  55. data/vendor/jquery_file_upload/test/vendor/mocha.css +325 -0
  56. data/vendor/jquery_file_upload/test/vendor/mocha.js +18178 -0
  57. data/vendor/jquery_file_upload/wdio/LICENSE.txt +20 -0
  58. data/vendor/jquery_file_upload/wdio/assets/black+white-3x2.jpg +0 -0
  59. data/vendor/jquery_file_upload/wdio/assets/black+white-60x40.gif +0 -0
  60. data/vendor/jquery_file_upload/wdio/conf/chrome.js +40 -0
  61. data/vendor/jquery_file_upload/wdio/conf/firefox.js +25 -0
  62. data/vendor/jquery_file_upload/wdio/hooks/index.js +36 -0
  63. data/vendor/jquery_file_upload/wdio/test/pages/file-upload.js +79 -0
  64. data/vendor/jquery_file_upload/wdio/test/specs/01-file-upload.js +25 -0
  65. data/vendor/jquery_file_upload/wdio/wdio.conf.js +4 -0
  66. metadata +34 -52
  67. data/file/mod_script_script_decko_machine_output/file.js +0 -2685
  68. data/file/mod_script_script_jquery_machine_output/file.js +0 -12926
  69. data/lib/javascript/script_html5shiv_printshiv.js +0 -1
  70. data/set/self/script_html5shiv_printshiv.rb +0 -11
  71. data/set/self/script_mods.rb +0 -1
  72. data/set/type/mod_script_assets.rb +0 -21
  73. data/vendor/jquery_file_upload/CONTRIBUTING.md +0 -15
  74. data/vendor/jquery_file_upload/angularjs.html +0 -211
  75. data/vendor/jquery_file_upload/basic-plus.html +0 -226
  76. data/vendor/jquery_file_upload/basic.html +0 -136
  77. data/vendor/jquery_file_upload/bower-version-update.js +0 -16
  78. data/vendor/jquery_file_upload/bower.json +0 -64
  79. data/vendor/jquery_file_upload/css/jquery-ui-demo-ie8.css +0 -21
  80. data/vendor/jquery_file_upload/css/jquery-ui-demo.css +0 -67
  81. data/vendor/jquery_file_upload/css/style.css +0 -15
  82. data/vendor/jquery_file_upload/jquery-ui.html +0 -252
  83. data/vendor/jquery_file_upload/js/app.js +0 -101
  84. data/vendor/jquery_file_upload/js/jquery.fileupload-angular.js +0 -437
  85. data/vendor/jquery_file_upload/js/jquery.fileupload-jquery-ui.js +0 -161
  86. data/vendor/jquery_file_upload/js/main.js +0 -75
  87. data/vendor/jquery_file_upload/server/gae-go/app/main.go +0 -361
  88. data/vendor/jquery_file_upload/server/gae-go/app.yaml +0 -12
  89. data/vendor/jquery_file_upload/server/gae-go/static/favicon.ico +0 -0
  90. data/vendor/jquery_file_upload/server/gae-go/static/robots.txt +0 -2
  91. data/vendor/jquery_file_upload/server/php/docker-compose.yml +0 -9
  92. data/vendor/jquery_file_upload/test/test.js +0 -1292
@@ -9,706 +9,751 @@
9
9
  * https://opensource.org/licenses/MIT
10
10
  */
11
11
 
12
- /* jshint nomen:false */
13
- /* global define, require, window */
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
- 'blueimp-tmpl',
22
- './jquery.fileupload-image',
23
- './jquery.fileupload-audio',
24
- './jquery.fileupload-video',
25
- './jquery.fileupload-validate'
26
- ], factory);
27
- } else if (typeof exports === 'object') {
28
- // Node/CommonJS:
29
- factory(
30
- require('jquery'),
31
- require('blueimp-tmpl'),
32
- require('./jquery.fileupload-image'),
33
- require('./jquery.fileupload-audio'),
34
- require('./jquery.fileupload-video'),
35
- require('./jquery.fileupload-validate')
36
- );
37
- } else {
38
- // Browser globals:
39
- factory(
40
- window.jQuery,
41
- window.tmpl
42
- );
43
- }
44
- }(function ($, tmpl) {
45
- 'use strict';
46
-
47
- $.blueimp.fileupload.prototype._specialOptions.push(
48
- 'filesContainer',
49
- 'uploadTemplateId',
50
- 'downloadTemplateId'
12
+ /* global define, require */
13
+
14
+ (function (factory) {
15
+ 'use strict';
16
+ if (typeof define === 'function' && define.amd) {
17
+ // Register as an anonymous AMD module:
18
+ define([
19
+ 'jquery',
20
+ 'blueimp-tmpl',
21
+ './jquery.fileupload-image',
22
+ './jquery.fileupload-audio',
23
+ './jquery.fileupload-video',
24
+ './jquery.fileupload-validate'
25
+ ], factory);
26
+ } else if (typeof exports === 'object') {
27
+ // Node/CommonJS:
28
+ factory(
29
+ require('jquery'),
30
+ require('blueimp-tmpl'),
31
+ require('./jquery.fileupload-image'),
32
+ require('./jquery.fileupload-audio'),
33
+ require('./jquery.fileupload-video'),
34
+ require('./jquery.fileupload-validate')
51
35
  );
52
-
53
- // The UI version extends the file upload widget
54
- // and adds complete user interface interaction:
55
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
56
-
57
- options: {
58
- // By default, files added to the widget are uploaded as soon
59
- // as the user clicks on the start buttons. To enable automatic
60
- // uploads, set the following option to true:
61
- autoUpload: false,
62
- // The ID of the upload template:
63
- uploadTemplateId: 'template-upload',
64
- // The ID of the download template:
65
- downloadTemplateId: 'template-download',
66
- // The container for the list of files. If undefined, it is set to
67
- // an element with class "files" inside of the widget element:
68
- filesContainer: undefined,
69
- // By default, files are appended to the files container.
70
- // Set the following option to true, to prepend files instead:
71
- prependFiles: false,
72
- // The expected data type of the upload response, sets the dataType
73
- // option of the $.ajax upload requests:
74
- dataType: 'json',
75
-
76
- // Error and info messages:
77
- messages: {
78
- unknownError: 'Unknown error'
79
- },
80
-
81
- // Function returning the current number of files,
82
- // used by the maxNumberOfFiles validation:
83
- getNumberOfFiles: function () {
84
- return this.filesContainer.children()
85
- .not('.processing').length;
86
- },
87
-
88
- // Callback to retrieve the list of files from the server response:
89
- getFilesFromResponse: function (data) {
90
- if (data.result && $.isArray(data.result.files)) {
91
- return data.result.files;
92
- }
93
- return [];
94
- },
95
-
96
- // The add callback is invoked as soon as files are added to the fileupload
97
- // widget (via file input selection, drag & drop or add API call).
98
- // See the basic file upload widget for more information:
99
- add: function (e, data) {
100
- if (e.isDefaultPrevented()) {
101
- return false;
102
- }
103
- var $this = $(this),
104
- that = $this.data('blueimp-fileupload') ||
105
- $this.data('fileupload'),
106
- options = that.options;
107
- data.context = that._renderUpload(data.files)
108
- .data('data', data)
109
- .addClass('processing');
110
- options.filesContainer[
111
- options.prependFiles ? 'prepend' : 'append'
112
- ](data.context);
113
- that._forceReflow(data.context);
114
- that._transition(data.context);
115
- data.process(function () {
116
- return $this.fileupload('process', data);
117
- }).always(function () {
118
- data.context.each(function (index) {
119
- $(this).find('.size').text(
120
- that._formatFileSize(data.files[index].size)
121
- );
122
- }).removeClass('processing');
123
- that._renderPreviews(data);
124
- }).done(function () {
125
- data.context.find('.start').prop('disabled', false);
126
- if ((that._trigger('added', e, data) !== false) &&
127
- (options.autoUpload || data.autoUpload) &&
128
- data.autoUpload !== false) {
129
- data.submit();
130
- }
131
- }).fail(function () {
132
- if (data.files.error) {
133
- data.context.each(function (index) {
134
- var error = data.files[index].error;
135
- if (error) {
136
- $(this).find('.error').text(error);
137
- }
138
- });
139
- }
140
- });
141
- },
142
- // Callback for the start of each file upload request:
143
- send: function (e, data) {
144
- if (e.isDefaultPrevented()) {
145
- return false;
146
- }
147
- var that = $(this).data('blueimp-fileupload') ||
148
- $(this).data('fileupload');
149
- if (data.context && data.dataType &&
150
- data.dataType.substr(0, 6) === 'iframe') {
151
- // Iframe Transport does not support progress events.
152
- // In lack of an indeterminate progress bar, we set
153
- // the progress to 100%, showing the full animated bar:
154
- data.context
155
- .find('.progress').addClass(
156
- !$.support.transition && 'progress-animated'
157
- )
158
- .attr('aria-valuenow', 100)
159
- .children().first().css(
160
- 'width',
161
- '100%'
162
- );
163
- }
164
- return that._trigger('sent', e, data);
165
- },
166
- // Callback for successful uploads:
167
- done: function (e, data) {
168
- if (e.isDefaultPrevented()) {
169
- return false;
170
- }
171
- var that = $(this).data('blueimp-fileupload') ||
172
- $(this).data('fileupload'),
173
- getFilesFromResponse = data.getFilesFromResponse ||
174
- that.options.getFilesFromResponse,
175
- files = getFilesFromResponse(data),
176
- template,
177
- deferred;
178
- if (data.context) {
179
- data.context.each(function (index) {
180
- var file = files[index] ||
181
- {error: 'Empty file upload result'};
182
- deferred = that._addFinishedDeferreds();
183
- that._transition($(this)).done(
184
- function () {
185
- var node = $(this);
186
- template = that._renderDownload([file])
187
- .replaceAll(node);
188
- that._forceReflow(template);
189
- that._transition(template).done(
190
- function () {
191
- data.context = $(this);
192
- that._trigger('completed', e, data);
193
- that._trigger('finished', e, data);
194
- deferred.resolve();
195
- }
196
- );
197
- }
198
- );
199
- });
200
- } else {
201
- template = that._renderDownload(files)[
202
- that.options.prependFiles ? 'prependTo' : 'appendTo'
203
- ](that.options.filesContainer);
204
- that._forceReflow(template);
205
- deferred = that._addFinishedDeferreds();
206
- that._transition(template).done(
207
- function () {
208
- data.context = $(this);
209
- that._trigger('completed', e, data);
210
- that._trigger('finished', e, data);
211
- deferred.resolve();
212
- }
213
- );
214
- }
215
- },
216
- // Callback for failed (abort or error) uploads:
217
- fail: function (e, data) {
218
- if (e.isDefaultPrevented()) {
219
- return false;
220
- }
221
- var that = $(this).data('blueimp-fileupload') ||
222
- $(this).data('fileupload'),
223
- template,
224
- deferred;
225
- if (data.context) {
226
- data.context.each(function (index) {
227
- if (data.errorThrown !== 'abort') {
228
- var file = data.files[index];
229
- file.error = file.error || data.errorThrown ||
230
- data.i18n('unknownError');
231
- deferred = that._addFinishedDeferreds();
232
- that._transition($(this)).done(
233
- function () {
234
- var node = $(this);
235
- template = that._renderDownload([file])
236
- .replaceAll(node);
237
- that._forceReflow(template);
238
- that._transition(template).done(
239
- function () {
240
- data.context = $(this);
241
- that._trigger('failed', e, data);
242
- that._trigger('finished', e, data);
243
- deferred.resolve();
244
- }
245
- );
246
- }
247
- );
248
- } else {
249
- deferred = that._addFinishedDeferreds();
250
- that._transition($(this)).done(
251
- function () {
252
- $(this).remove();
253
- that._trigger('failed', e, data);
254
- that._trigger('finished', e, data);
255
- deferred.resolve();
256
- }
257
- );
258
- }
259
- });
260
- } else if (data.errorThrown !== 'abort') {
261
- data.context = that._renderUpload(data.files)[
262
- that.options.prependFiles ? 'prependTo' : 'appendTo'
263
- ](that.options.filesContainer)
264
- .data('data', data);
265
- that._forceReflow(data.context);
266
- deferred = that._addFinishedDeferreds();
267
- that._transition(data.context).done(
268
- function () {
269
- data.context = $(this);
270
- that._trigger('failed', e, data);
271
- that._trigger('finished', e, data);
272
- deferred.resolve();
273
- }
274
- );
275
- } else {
276
- that._trigger('failed', e, data);
277
- that._trigger('finished', e, data);
278
- that._addFinishedDeferreds().resolve();
279
- }
280
- },
281
- // Callback for upload progress events:
282
- progress: function (e, data) {
283
- if (e.isDefaultPrevented()) {
284
- return false;
285
- }
286
- var progress = Math.floor(data.loaded / data.total * 100);
287
- if (data.context) {
288
- data.context.each(function () {
289
- $(this).find('.progress')
290
- .attr('aria-valuenow', progress)
291
- .children().first().css(
292
- 'width',
293
- progress + '%'
294
- );
295
- });
296
- }
297
- },
298
- // Callback for global upload progress events:
299
- progressall: function (e, data) {
300
- if (e.isDefaultPrevented()) {
301
- return false;
302
- }
303
- var $this = $(this),
304
- progress = Math.floor(data.loaded / data.total * 100),
305
- globalProgressNode = $this.find('.fileupload-progress'),
306
- extendedProgressNode = globalProgressNode
307
- .find('.progress-extended');
308
- if (extendedProgressNode.length) {
309
- extendedProgressNode.html(
310
- ($this.data('blueimp-fileupload') || $this.data('fileupload'))
311
- ._renderExtendedProgress(data)
312
- );
313
- }
314
- globalProgressNode
315
- .find('.progress')
316
- .attr('aria-valuenow', progress)
317
- .children().first().css(
318
- 'width',
319
- progress + '%'
320
- );
321
- },
322
- // Callback for uploads start, equivalent to the global ajaxStart event:
323
- start: function (e) {
324
- if (e.isDefaultPrevented()) {
325
- return false;
326
- }
327
- var that = $(this).data('blueimp-fileupload') ||
328
- $(this).data('fileupload');
329
- that._resetFinishedDeferreds();
330
- that._transition($(this).find('.fileupload-progress')).done(
331
- function () {
332
- that._trigger('started', e);
333
- }
334
- );
335
- },
336
- // Callback for uploads stop, equivalent to the global ajaxStop event:
337
- stop: function (e) {
338
- if (e.isDefaultPrevented()) {
339
- return false;
340
- }
341
- var that = $(this).data('blueimp-fileupload') ||
342
- $(this).data('fileupload'),
343
- deferred = that._addFinishedDeferreds();
344
- $.when.apply($, that._getFinishedDeferreds())
345
- .done(function () {
346
- that._trigger('stopped', e);
347
- });
348
- that._transition($(this).find('.fileupload-progress')).done(
349
- function () {
350
- $(this).find('.progress')
351
- .attr('aria-valuenow', '0')
352
- .children().first().css('width', '0%');
353
- $(this).find('.progress-extended').html(' ');
354
- deferred.resolve();
355
- }
356
- );
357
- },
358
- processstart: function (e) {
359
- if (e.isDefaultPrevented()) {
360
- return false;
361
- }
362
- $(this).addClass('fileupload-processing');
363
- },
364
- processstop: function (e) {
365
- if (e.isDefaultPrevented()) {
366
- return false;
367
- }
368
- $(this).removeClass('fileupload-processing');
369
- },
370
- // Callback for file deletion:
371
- destroy: function (e, data) {
372
- if (e.isDefaultPrevented()) {
373
- return false;
374
- }
375
- var that = $(this).data('blueimp-fileupload') ||
376
- $(this).data('fileupload'),
377
- removeNode = function () {
378
- that._transition(data.context).done(
379
- function () {
380
- $(this).remove();
381
- that._trigger('destroyed', e, data);
382
- }
383
- );
384
- };
385
- if (data.url) {
386
- data.dataType = data.dataType || that.options.dataType;
387
- $.ajax(data).done(removeNode).fail(function () {
388
- that._trigger('destroyfailed', e, data);
389
- });
390
- } else {
391
- removeNode();
392
- }
393
- }
394
- },
395
-
396
- _resetFinishedDeferreds: function () {
397
- this._finishedUploads = [];
398
- },
399
-
400
- _addFinishedDeferreds: function (deferred) {
401
- if (!deferred) {
402
- deferred = $.Deferred();
403
- }
404
- this._finishedUploads.push(deferred);
405
- return deferred;
406
- },
407
-
408
- _getFinishedDeferreds: function () {
409
- return this._finishedUploads;
410
- },
411
-
412
- // Link handler, that allows to download files
413
- // by drag & drop of the links to the desktop:
414
- _enableDragToDesktop: function () {
415
- var link = $(this),
416
- url = link.prop('href'),
417
- name = link.prop('download'),
418
- type = 'application/octet-stream';
419
- link.bind('dragstart', function (e) {
420
- try {
421
- e.originalEvent.dataTransfer.setData(
422
- 'DownloadURL',
423
- [type, name, url].join(':')
424
- );
425
- } catch (ignore) {}
426
- });
427
- },
428
-
429
- _formatFileSize: function (bytes) {
430
- if (typeof bytes !== 'number') {
431
- return '';
432
- }
433
- if (bytes >= 1000000000) {
434
- return (bytes / 1000000000).toFixed(2) + ' GB';
435
- }
436
- if (bytes >= 1000000) {
437
- return (bytes / 1000000).toFixed(2) + ' MB';
438
- }
439
- return (bytes / 1000).toFixed(2) + ' KB';
440
- },
441
-
442
- _formatBitrate: function (bits) {
443
- if (typeof bits !== 'number') {
444
- return '';
445
- }
446
- if (bits >= 1000000000) {
447
- return (bits / 1000000000).toFixed(2) + ' Gbit/s';
448
- }
449
- if (bits >= 1000000) {
450
- return (bits / 1000000).toFixed(2) + ' Mbit/s';
451
- }
452
- if (bits >= 1000) {
453
- return (bits / 1000).toFixed(2) + ' kbit/s';
454
- }
455
- return bits.toFixed(2) + ' bit/s';
456
- },
457
-
458
- _formatTime: function (seconds) {
459
- var date = new Date(seconds * 1000),
460
- days = Math.floor(seconds / 86400);
461
- days = days ? days + 'd ' : '';
462
- return days +
463
- ('0' + date.getUTCHours()).slice(-2) + ':' +
464
- ('0' + date.getUTCMinutes()).slice(-2) + ':' +
465
- ('0' + date.getUTCSeconds()).slice(-2);
466
- },
467
-
468
- _formatPercentage: function (floatValue) {
469
- return (floatValue * 100).toFixed(2) + ' %';
470
- },
471
-
472
- _renderExtendedProgress: function (data) {
473
- return this._formatBitrate(data.bitrate) + ' | ' +
474
- this._formatTime(
475
- (data.total - data.loaded) * 8 / data.bitrate
476
- ) + ' | ' +
477
- this._formatPercentage(
478
- data.loaded / data.total
479
- ) + ' | ' +
480
- this._formatFileSize(data.loaded) + ' / ' +
481
- this._formatFileSize(data.total);
482
- },
483
-
484
- _renderTemplate: function (func, files) {
485
- if (!func) {
486
- return $();
36
+ } else {
37
+ // Browser globals:
38
+ factory(window.jQuery, window.tmpl);
39
+ }
40
+ })(function ($, tmpl) {
41
+ 'use strict';
42
+
43
+ $.blueimp.fileupload.prototype._specialOptions.push(
44
+ 'filesContainer',
45
+ 'uploadTemplateId',
46
+ 'downloadTemplateId'
47
+ );
48
+
49
+ // The UI version extends the file upload widget
50
+ // and adds complete user interface interaction:
51
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
52
+ options: {
53
+ // By default, files added to the widget are uploaded as soon
54
+ // as the user clicks on the start buttons. To enable automatic
55
+ // uploads, set the following option to true:
56
+ autoUpload: false,
57
+ // The class to show/hide UI elements:
58
+ showElementClass: 'in',
59
+ // The ID of the upload template:
60
+ uploadTemplateId: 'template-upload',
61
+ // The ID of the download template:
62
+ downloadTemplateId: 'template-download',
63
+ // The container for the list of files. If undefined, it is set to
64
+ // an element with class "files" inside of the widget element:
65
+ filesContainer: undefined,
66
+ // By default, files are appended to the files container.
67
+ // Set the following option to true, to prepend files instead:
68
+ prependFiles: false,
69
+ // The expected data type of the upload response, sets the dataType
70
+ // option of the $.ajax upload requests:
71
+ dataType: 'json',
72
+
73
+ // Error and info messages:
74
+ messages: {
75
+ unknownError: 'Unknown error'
76
+ },
77
+
78
+ // Function returning the current number of files,
79
+ // used by the maxNumberOfFiles validation:
80
+ getNumberOfFiles: function () {
81
+ return this.filesContainer.children().not('.processing').length;
82
+ },
83
+
84
+ // Callback to retrieve the list of files from the server response:
85
+ getFilesFromResponse: function (data) {
86
+ if (data.result && $.isArray(data.result.files)) {
87
+ return data.result.files;
88
+ }
89
+ return [];
90
+ },
91
+
92
+ // The add callback is invoked as soon as files are added to the fileupload
93
+ // widget (via file input selection, drag & drop or add API call).
94
+ // See the basic file upload widget for more information:
95
+ add: function (e, data) {
96
+ if (e.isDefaultPrevented()) {
97
+ return false;
98
+ }
99
+ var $this = $(this),
100
+ that = $this.data('blueimp-fileupload') || $this.data('fileupload'),
101
+ options = that.options;
102
+ data.context = that
103
+ ._renderUpload(data.files)
104
+ .data('data', data)
105
+ .addClass('processing');
106
+ options.filesContainer[options.prependFiles ? 'prepend' : 'append'](
107
+ data.context
108
+ );
109
+ that._forceReflow(data.context);
110
+ that._transition(data.context);
111
+ data
112
+ .process(function () {
113
+ return $this.fileupload('process', data);
114
+ })
115
+ .always(function () {
116
+ data.context
117
+ .each(function (index) {
118
+ $(this)
119
+ .find('.size')
120
+ .text(that._formatFileSize(data.files[index].size));
121
+ })
122
+ .removeClass('processing');
123
+ that._renderPreviews(data);
124
+ })
125
+ .done(function () {
126
+ data.context.find('.edit,.start').prop('disabled', false);
127
+ if (
128
+ that._trigger('added', e, data) !== false &&
129
+ (options.autoUpload || data.autoUpload) &&
130
+ data.autoUpload !== false
131
+ ) {
132
+ data.submit();
487
133
  }
488
- var result = func({
489
- files: files,
490
- formatFileSize: this._formatFileSize,
491
- options: this.options
492
- });
493
- if (result instanceof $) {
494
- return result;
134
+ })
135
+ .fail(function () {
136
+ if (data.files.error) {
137
+ data.context.each(function (index) {
138
+ var error = data.files[index].error;
139
+ if (error) {
140
+ $(this).find('.error').text(error);
141
+ }
142
+ });
495
143
  }
496
- return $(this.options.templatesContainer).html(result).children();
497
- },
498
-
499
- _renderPreviews: function (data) {
500
- data.context.find('.preview').each(function (index, elm) {
501
- $(elm).append(data.files[index].preview);
144
+ });
145
+ },
146
+ // Callback for the start of each file upload request:
147
+ send: function (e, data) {
148
+ if (e.isDefaultPrevented()) {
149
+ return false;
150
+ }
151
+ var that =
152
+ $(this).data('blueimp-fileupload') || $(this).data('fileupload');
153
+ if (
154
+ data.context &&
155
+ data.dataType &&
156
+ data.dataType.substr(0, 6) === 'iframe'
157
+ ) {
158
+ // Iframe Transport does not support progress events.
159
+ // In lack of an indeterminate progress bar, we set
160
+ // the progress to 100%, showing the full animated bar:
161
+ data.context
162
+ .find('.progress')
163
+ .addClass(!$.support.transition && 'progress-animated')
164
+ .attr('aria-valuenow', 100)
165
+ .children()
166
+ .first()
167
+ .css('width', '100%');
168
+ }
169
+ return that._trigger('sent', e, data);
170
+ },
171
+ // Callback for successful uploads:
172
+ done: function (e, data) {
173
+ if (e.isDefaultPrevented()) {
174
+ return false;
175
+ }
176
+ var that =
177
+ $(this).data('blueimp-fileupload') || $(this).data('fileupload'),
178
+ getFilesFromResponse =
179
+ data.getFilesFromResponse || that.options.getFilesFromResponse,
180
+ files = getFilesFromResponse(data),
181
+ template,
182
+ deferred;
183
+ if (data.context) {
184
+ data.context.each(function (index) {
185
+ var file = files[index] || { error: 'Empty file upload result' };
186
+ deferred = that._addFinishedDeferreds();
187
+ that._transition($(this)).done(function () {
188
+ var node = $(this);
189
+ template = that._renderDownload([file]).replaceAll(node);
190
+ that._forceReflow(template);
191
+ that._transition(template).done(function () {
192
+ data.context = $(this);
193
+ that._trigger('completed', e, data);
194
+ that._trigger('finished', e, data);
195
+ deferred.resolve();
196
+ });
502
197
  });
503
- },
504
-
505
- _renderUpload: function (files) {
506
- return this._renderTemplate(
507
- this.options.uploadTemplate,
508
- files
198
+ });
199
+ } else {
200
+ template = that
201
+ ._renderDownload(files)
202
+ [that.options.prependFiles ? 'prependTo' : 'appendTo'](
203
+ that.options.filesContainer
509
204
  );
510
- },
511
-
512
- _renderDownload: function (files) {
513
- return this._renderTemplate(
514
- this.options.downloadTemplate,
515
- files
516
- ).find('a[download]').each(this._enableDragToDesktop).end();
517
- },
518
-
519
- _startHandler: function (e) {
520
- e.preventDefault();
521
- var button = $(e.currentTarget),
522
- template = button.closest('.template-upload'),
523
- data = template.data('data');
524
- button.prop('disabled', true);
525
- if (data && data.submit) {
526
- data.submit();
527
- }
528
- },
529
-
530
- _cancelHandler: function (e) {
531
- e.preventDefault();
532
- var template = $(e.currentTarget)
533
- .closest('.template-upload,.template-download'),
534
- data = template.data('data') || {};
535
- data.context = data.context || template;
536
- if (data.abort) {
537
- data.abort();
538
- } else {
539
- data.errorThrown = 'abort';
540
- this._trigger('fail', e, data);
541
- }
542
- },
543
-
544
- _deleteHandler: function (e) {
545
- e.preventDefault();
546
- var button = $(e.currentTarget);
547
- this._trigger('destroy', e, $.extend({
548
- context: button.closest('.template-download'),
549
- type: 'DELETE'
550
- }, button.data()));
551
- },
552
-
553
- _forceReflow: function (node) {
554
- return $.support.transition && node.length &&
555
- node[0].offsetWidth;
556
- },
557
-
558
- _transition: function (node) {
559
- var dfd = $.Deferred();
560
- if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
561
- node.bind(
562
- $.support.transition.end,
563
- function (e) {
564
- // Make sure we don't respond to other transitions events
565
- // in the container element, e.g. from button elements:
566
- if (e.target === node[0]) {
567
- node.unbind($.support.transition.end);
568
- dfd.resolveWith(node);
569
- }
570
- }
571
- ).toggleClass('in');
205
+ that._forceReflow(template);
206
+ deferred = that._addFinishedDeferreds();
207
+ that._transition(template).done(function () {
208
+ data.context = $(this);
209
+ that._trigger('completed', e, data);
210
+ that._trigger('finished', e, data);
211
+ deferred.resolve();
212
+ });
213
+ }
214
+ },
215
+ // Callback for failed (abort or error) uploads:
216
+ fail: function (e, data) {
217
+ if (e.isDefaultPrevented()) {
218
+ return false;
219
+ }
220
+ var that =
221
+ $(this).data('blueimp-fileupload') || $(this).data('fileupload'),
222
+ template,
223
+ deferred;
224
+ if (data.context) {
225
+ data.context.each(function (index) {
226
+ if (data.errorThrown !== 'abort') {
227
+ var file = data.files[index];
228
+ file.error =
229
+ file.error || data.errorThrown || data.i18n('unknownError');
230
+ deferred = that._addFinishedDeferreds();
231
+ that._transition($(this)).done(function () {
232
+ var node = $(this);
233
+ template = that._renderDownload([file]).replaceAll(node);
234
+ that._forceReflow(template);
235
+ that._transition(template).done(function () {
236
+ data.context = $(this);
237
+ that._trigger('failed', e, data);
238
+ that._trigger('finished', e, data);
239
+ deferred.resolve();
240
+ });
241
+ });
572
242
  } else {
573
- node.toggleClass('in');
574
- dfd.resolveWith(node);
243
+ deferred = that._addFinishedDeferreds();
244
+ that._transition($(this)).done(function () {
245
+ $(this).remove();
246
+ that._trigger('failed', e, data);
247
+ that._trigger('finished', e, data);
248
+ deferred.resolve();
249
+ });
575
250
  }
576
- return dfd;
577
- },
578
-
579
- _initButtonBarEventHandlers: function () {
580
- var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
581
- filesList = this.options.filesContainer;
582
- this._on(fileUploadButtonBar.find('.start'), {
583
- click: function (e) {
584
- e.preventDefault();
585
- filesList.find('.start').click();
586
- }
587
- });
588
- this._on(fileUploadButtonBar.find('.cancel'), {
589
- click: function (e) {
590
- e.preventDefault();
591
- filesList.find('.cancel').click();
592
- }
593
- });
594
- this._on(fileUploadButtonBar.find('.delete'), {
595
- click: function (e) {
596
- e.preventDefault();
597
- filesList.find('.toggle:checked')
598
- .closest('.template-download')
599
- .find('.delete').click();
600
- fileUploadButtonBar.find('.toggle')
601
- .prop('checked', false);
602
- }
251
+ });
252
+ } else if (data.errorThrown !== 'abort') {
253
+ data.context = that
254
+ ._renderUpload(data.files)
255
+ [that.options.prependFiles ? 'prependTo' : 'appendTo'](
256
+ that.options.filesContainer
257
+ )
258
+ .data('data', data);
259
+ that._forceReflow(data.context);
260
+ deferred = that._addFinishedDeferreds();
261
+ that._transition(data.context).done(function () {
262
+ data.context = $(this);
263
+ that._trigger('failed', e, data);
264
+ that._trigger('finished', e, data);
265
+ deferred.resolve();
266
+ });
267
+ } else {
268
+ that._trigger('failed', e, data);
269
+ that._trigger('finished', e, data);
270
+ that._addFinishedDeferreds().resolve();
271
+ }
272
+ },
273
+ // Callback for upload progress events:
274
+ progress: function (e, data) {
275
+ if (e.isDefaultPrevented()) {
276
+ return false;
277
+ }
278
+ var progress = Math.floor((data.loaded / data.total) * 100);
279
+ if (data.context) {
280
+ data.context.each(function () {
281
+ $(this)
282
+ .find('.progress')
283
+ .attr('aria-valuenow', progress)
284
+ .children()
285
+ .first()
286
+ .css('width', progress + '%');
287
+ });
288
+ }
289
+ },
290
+ // Callback for global upload progress events:
291
+ progressall: function (e, data) {
292
+ if (e.isDefaultPrevented()) {
293
+ return false;
294
+ }
295
+ var $this = $(this),
296
+ progress = Math.floor((data.loaded / data.total) * 100),
297
+ globalProgressNode = $this.find('.fileupload-progress'),
298
+ extendedProgressNode = globalProgressNode.find('.progress-extended');
299
+ if (extendedProgressNode.length) {
300
+ extendedProgressNode.html(
301
+ (
302
+ $this.data('blueimp-fileupload') || $this.data('fileupload')
303
+ )._renderExtendedProgress(data)
304
+ );
305
+ }
306
+ globalProgressNode
307
+ .find('.progress')
308
+ .attr('aria-valuenow', progress)
309
+ .children()
310
+ .first()
311
+ .css('width', progress + '%');
312
+ },
313
+ // Callback for uploads start, equivalent to the global ajaxStart event:
314
+ start: function (e) {
315
+ if (e.isDefaultPrevented()) {
316
+ return false;
317
+ }
318
+ var that =
319
+ $(this).data('blueimp-fileupload') || $(this).data('fileupload');
320
+ that._resetFinishedDeferreds();
321
+ that
322
+ ._transition($(this).find('.fileupload-progress'))
323
+ .done(function () {
324
+ that._trigger('started', e);
325
+ });
326
+ },
327
+ // Callback for uploads stop, equivalent to the global ajaxStop event:
328
+ stop: function (e) {
329
+ if (e.isDefaultPrevented()) {
330
+ return false;
331
+ }
332
+ var that =
333
+ $(this).data('blueimp-fileupload') || $(this).data('fileupload'),
334
+ deferred = that._addFinishedDeferreds();
335
+ $.when.apply($, that._getFinishedDeferreds()).done(function () {
336
+ that._trigger('stopped', e);
337
+ });
338
+ that
339
+ ._transition($(this).find('.fileupload-progress'))
340
+ .done(function () {
341
+ $(this)
342
+ .find('.progress')
343
+ .attr('aria-valuenow', '0')
344
+ .children()
345
+ .first()
346
+ .css('width', '0%');
347
+ $(this).find('.progress-extended').html(' ');
348
+ deferred.resolve();
349
+ });
350
+ },
351
+ processstart: function (e) {
352
+ if (e.isDefaultPrevented()) {
353
+ return false;
354
+ }
355
+ $(this).addClass('fileupload-processing');
356
+ },
357
+ processstop: function (e) {
358
+ if (e.isDefaultPrevented()) {
359
+ return false;
360
+ }
361
+ $(this).removeClass('fileupload-processing');
362
+ },
363
+ // Callback for file deletion:
364
+ destroy: function (e, data) {
365
+ if (e.isDefaultPrevented()) {
366
+ return false;
367
+ }
368
+ var that =
369
+ $(this).data('blueimp-fileupload') || $(this).data('fileupload'),
370
+ removeNode = function () {
371
+ that._transition(data.context).done(function () {
372
+ $(this).remove();
373
+ that._trigger('destroyed', e, data);
603
374
  });
604
- this._on(fileUploadButtonBar.find('.toggle'), {
605
- change: function (e) {
606
- filesList.find('.toggle').prop(
607
- 'checked',
608
- $(e.currentTarget).is(':checked')
609
- );
610
- }
375
+ };
376
+ if (data.url) {
377
+ data.dataType = data.dataType || that.options.dataType;
378
+ $.ajax(data)
379
+ .done(removeNode)
380
+ .fail(function () {
381
+ that._trigger('destroyfailed', e, data);
611
382
  });
612
- },
613
-
614
- _destroyButtonBarEventHandlers: function () {
615
- this._off(
616
- this.element.find('.fileupload-buttonbar')
617
- .find('.start, .cancel, .delete'),
618
- 'click'
619
- );
620
- this._off(
621
- this.element.find('.fileupload-buttonbar .toggle'),
622
- 'change.'
623
- );
624
- },
625
-
626
- _initEventHandlers: function () {
627
- this._super();
628
- this._on(this.options.filesContainer, {
629
- 'click .start': this._startHandler,
630
- 'click .cancel': this._cancelHandler,
631
- 'click .delete': this._deleteHandler
632
- });
633
- this._initButtonBarEventHandlers();
634
- },
635
-
636
- _destroyEventHandlers: function () {
637
- this._destroyButtonBarEventHandlers();
638
- this._off(this.options.filesContainer, 'click');
639
- this._super();
640
- },
641
-
642
- _enableFileInputButton: function () {
643
- this.element.find('.fileinput-button input')
644
- .prop('disabled', false)
645
- .parent().removeClass('disabled');
646
- },
647
-
648
- _disableFileInputButton: function () {
649
- this.element.find('.fileinput-button input')
650
- .prop('disabled', true)
651
- .parent().addClass('disabled');
652
- },
653
-
654
- _initTemplates: function () {
655
- var options = this.options;
656
- options.templatesContainer = this.document[0].createElement(
657
- options.filesContainer.prop('nodeName')
658
- );
659
- if (tmpl) {
660
- if (options.uploadTemplateId) {
661
- options.uploadTemplate = tmpl(options.uploadTemplateId);
662
- }
663
- if (options.downloadTemplateId) {
664
- options.downloadTemplate = tmpl(options.downloadTemplateId);
665
- }
666
- }
667
- },
668
-
669
- _initFilesContainer: function () {
670
- var options = this.options;
671
- if (options.filesContainer === undefined) {
672
- options.filesContainer = this.element.find('.files');
673
- } else if (!(options.filesContainer instanceof $)) {
674
- options.filesContainer = $(options.filesContainer);
675
- }
676
- },
677
-
678
- _initSpecialOptions: function () {
679
- this._super();
680
- this._initFilesContainer();
681
- this._initTemplates();
682
- },
683
-
684
- _create: function () {
685
- this._super();
686
- this._resetFinishedDeferreds();
687
- if (!$.support.fileInput) {
688
- this._disableFileInputButton();
689
- }
690
- },
691
-
692
- enable: function () {
693
- var wasDisabled = false;
694
- if (this.options.disabled) {
695
- wasDisabled = true;
696
- }
697
- this._super();
698
- if (wasDisabled) {
699
- this.element.find('input, button').prop('disabled', false);
700
- this._enableFileInputButton();
701
- }
702
- },
703
-
704
- disable: function () {
705
- if (!this.options.disabled) {
706
- this.element.find('input, button').prop('disabled', true);
707
- this._disableFileInputButton();
383
+ } else {
384
+ removeNode();
385
+ }
386
+ }
387
+ },
388
+
389
+ _resetFinishedDeferreds: function () {
390
+ this._finishedUploads = [];
391
+ },
392
+
393
+ _addFinishedDeferreds: function (deferred) {
394
+ // eslint-disable-next-line new-cap
395
+ var promise = deferred || $.Deferred();
396
+ this._finishedUploads.push(promise);
397
+ return promise;
398
+ },
399
+
400
+ _getFinishedDeferreds: function () {
401
+ return this._finishedUploads;
402
+ },
403
+
404
+ // Link handler, that allows to download files
405
+ // by drag & drop of the links to the desktop:
406
+ _enableDragToDesktop: function () {
407
+ var link = $(this),
408
+ url = link.prop('href'),
409
+ name = link.prop('download'),
410
+ type = 'application/octet-stream';
411
+ link.on('dragstart', function (e) {
412
+ try {
413
+ e.originalEvent.dataTransfer.setData(
414
+ 'DownloadURL',
415
+ [type, name, url].join(':')
416
+ );
417
+ } catch (ignore) {
418
+ // Ignore exceptions
419
+ }
420
+ });
421
+ },
422
+
423
+ _formatFileSize: function (bytes) {
424
+ if (typeof bytes !== 'number') {
425
+ return '';
426
+ }
427
+ if (bytes >= 1000000000) {
428
+ return (bytes / 1000000000).toFixed(2) + ' GB';
429
+ }
430
+ if (bytes >= 1000000) {
431
+ return (bytes / 1000000).toFixed(2) + ' MB';
432
+ }
433
+ return (bytes / 1000).toFixed(2) + ' KB';
434
+ },
435
+
436
+ _formatBitrate: function (bits) {
437
+ if (typeof bits !== 'number') {
438
+ return '';
439
+ }
440
+ if (bits >= 1000000000) {
441
+ return (bits / 1000000000).toFixed(2) + ' Gbit/s';
442
+ }
443
+ if (bits >= 1000000) {
444
+ return (bits / 1000000).toFixed(2) + ' Mbit/s';
445
+ }
446
+ if (bits >= 1000) {
447
+ return (bits / 1000).toFixed(2) + ' kbit/s';
448
+ }
449
+ return bits.toFixed(2) + ' bit/s';
450
+ },
451
+
452
+ _formatTime: function (seconds) {
453
+ var date = new Date(seconds * 1000),
454
+ days = Math.floor(seconds / 86400);
455
+ days = days ? days + 'd ' : '';
456
+ return (
457
+ days +
458
+ ('0' + date.getUTCHours()).slice(-2) +
459
+ ':' +
460
+ ('0' + date.getUTCMinutes()).slice(-2) +
461
+ ':' +
462
+ ('0' + date.getUTCSeconds()).slice(-2)
463
+ );
464
+ },
465
+
466
+ _formatPercentage: function (floatValue) {
467
+ return (floatValue * 100).toFixed(2) + ' %';
468
+ },
469
+
470
+ _renderExtendedProgress: function (data) {
471
+ return (
472
+ this._formatBitrate(data.bitrate) +
473
+ ' | ' +
474
+ this._formatTime(((data.total - data.loaded) * 8) / data.bitrate) +
475
+ ' | ' +
476
+ this._formatPercentage(data.loaded / data.total) +
477
+ ' | ' +
478
+ this._formatFileSize(data.loaded) +
479
+ ' / ' +
480
+ this._formatFileSize(data.total)
481
+ );
482
+ },
483
+
484
+ _renderTemplate: function (func, files) {
485
+ if (!func) {
486
+ return $();
487
+ }
488
+ var result = func({
489
+ files: files,
490
+ formatFileSize: this._formatFileSize,
491
+ options: this.options
492
+ });
493
+ if (result instanceof $) {
494
+ return result;
495
+ }
496
+ return $(this.options.templatesContainer).html(result).children();
497
+ },
498
+
499
+ _renderPreviews: function (data) {
500
+ data.context.find('.preview').each(function (index, elm) {
501
+ $(elm).empty().append(data.files[index].preview);
502
+ });
503
+ },
504
+
505
+ _renderUpload: function (files) {
506
+ return this._renderTemplate(this.options.uploadTemplate, files);
507
+ },
508
+
509
+ _renderDownload: function (files) {
510
+ return this._renderTemplate(this.options.downloadTemplate, files)
511
+ .find('a[download]')
512
+ .each(this._enableDragToDesktop)
513
+ .end();
514
+ },
515
+
516
+ _editHandler: function (e) {
517
+ e.preventDefault();
518
+ if (!this.options.edit) return;
519
+ var that = this,
520
+ button = $(e.currentTarget),
521
+ template = button.closest('.template-upload'),
522
+ data = template.data('data'),
523
+ index = button.data().index;
524
+ this.options.edit(data.files[index]).then(function (file) {
525
+ if (!file) return;
526
+ data.files[index] = file;
527
+ data.context.addClass('processing');
528
+ template.find('.edit,.start').prop('disabled', true);
529
+ $(that.element)
530
+ .fileupload('process', data)
531
+ .always(function () {
532
+ template
533
+ .find('.size')
534
+ .text(that._formatFileSize(data.files[index].size));
535
+ data.context.removeClass('processing');
536
+ that._renderPreviews(data);
537
+ })
538
+ .done(function () {
539
+ template.find('.edit,.start').prop('disabled', false);
540
+ })
541
+ .fail(function () {
542
+ template.find('.edit').prop('disabled', false);
543
+ var error = data.files[index].error;
544
+ if (error) {
545
+ template.find('.error').text(error);
708
546
  }
709
- this._super();
547
+ });
548
+ });
549
+ },
550
+
551
+ _startHandler: function (e) {
552
+ e.preventDefault();
553
+ var button = $(e.currentTarget),
554
+ template = button.closest('.template-upload'),
555
+ data = template.data('data');
556
+ button.prop('disabled', true);
557
+ if (data && data.submit) {
558
+ data.submit();
559
+ }
560
+ },
561
+
562
+ _cancelHandler: function (e) {
563
+ e.preventDefault();
564
+ var template = $(e.currentTarget).closest(
565
+ '.template-upload,.template-download'
566
+ ),
567
+ data = template.data('data') || {};
568
+ data.context = data.context || template;
569
+ if (data.abort) {
570
+ data.abort();
571
+ } else {
572
+ data.errorThrown = 'abort';
573
+ this._trigger('fail', e, data);
574
+ }
575
+ },
576
+
577
+ _deleteHandler: function (e) {
578
+ e.preventDefault();
579
+ var button = $(e.currentTarget);
580
+ this._trigger(
581
+ 'destroy',
582
+ e,
583
+ $.extend(
584
+ {
585
+ context: button.closest('.template-download'),
586
+ type: 'DELETE'
587
+ },
588
+ button.data()
589
+ )
590
+ );
591
+ },
592
+
593
+ _forceReflow: function (node) {
594
+ return $.support.transition && node.length && node[0].offsetWidth;
595
+ },
596
+
597
+ _transition: function (node) {
598
+ // eslint-disable-next-line new-cap
599
+ var dfd = $.Deferred();
600
+ if (
601
+ $.support.transition &&
602
+ node.hasClass('fade') &&
603
+ node.is(':visible')
604
+ ) {
605
+ var transitionEndHandler = function (e) {
606
+ // Make sure we don't respond to other transition events
607
+ // in the container element, e.g. from button elements:
608
+ if (e.target === node[0]) {
609
+ node.off($.support.transition.end, transitionEndHandler);
610
+ dfd.resolveWith(node);
611
+ }
612
+ };
613
+ node
614
+ .on($.support.transition.end, transitionEndHandler)
615
+ .toggleClass(this.options.showElementClass);
616
+ } else {
617
+ node.toggleClass(this.options.showElementClass);
618
+ dfd.resolveWith(node);
619
+ }
620
+ return dfd;
621
+ },
622
+
623
+ _initButtonBarEventHandlers: function () {
624
+ var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
625
+ filesList = this.options.filesContainer;
626
+ this._on(fileUploadButtonBar.find('.start'), {
627
+ click: function (e) {
628
+ e.preventDefault();
629
+ filesList.find('.start').trigger('click');
710
630
  }
711
-
712
- });
713
-
714
- }));
631
+ });
632
+ this._on(fileUploadButtonBar.find('.cancel'), {
633
+ click: function (e) {
634
+ e.preventDefault();
635
+ filesList.find('.cancel').trigger('click');
636
+ }
637
+ });
638
+ this._on(fileUploadButtonBar.find('.delete'), {
639
+ click: function (e) {
640
+ e.preventDefault();
641
+ filesList
642
+ .find('.toggle:checked')
643
+ .closest('.template-download')
644
+ .find('.delete')
645
+ .trigger('click');
646
+ fileUploadButtonBar.find('.toggle').prop('checked', false);
647
+ }
648
+ });
649
+ this._on(fileUploadButtonBar.find('.toggle'), {
650
+ change: function (e) {
651
+ filesList
652
+ .find('.toggle')
653
+ .prop('checked', $(e.currentTarget).is(':checked'));
654
+ }
655
+ });
656
+ },
657
+
658
+ _destroyButtonBarEventHandlers: function () {
659
+ this._off(
660
+ this.element
661
+ .find('.fileupload-buttonbar')
662
+ .find('.start, .cancel, .delete'),
663
+ 'click'
664
+ );
665
+ this._off(this.element.find('.fileupload-buttonbar .toggle'), 'change.');
666
+ },
667
+
668
+ _initEventHandlers: function () {
669
+ this._super();
670
+ this._on(this.options.filesContainer, {
671
+ 'click .edit': this._editHandler,
672
+ 'click .start': this._startHandler,
673
+ 'click .cancel': this._cancelHandler,
674
+ 'click .delete': this._deleteHandler
675
+ });
676
+ this._initButtonBarEventHandlers();
677
+ },
678
+
679
+ _destroyEventHandlers: function () {
680
+ this._destroyButtonBarEventHandlers();
681
+ this._off(this.options.filesContainer, 'click');
682
+ this._super();
683
+ },
684
+
685
+ _enableFileInputButton: function () {
686
+ this.element
687
+ .find('.fileinput-button input')
688
+ .prop('disabled', false)
689
+ .parent()
690
+ .removeClass('disabled');
691
+ },
692
+
693
+ _disableFileInputButton: function () {
694
+ this.element
695
+ .find('.fileinput-button input')
696
+ .prop('disabled', true)
697
+ .parent()
698
+ .addClass('disabled');
699
+ },
700
+
701
+ _initTemplates: function () {
702
+ var options = this.options;
703
+ options.templatesContainer = this.document[0].createElement(
704
+ options.filesContainer.prop('nodeName')
705
+ );
706
+ if (tmpl) {
707
+ if (options.uploadTemplateId) {
708
+ options.uploadTemplate = tmpl(options.uploadTemplateId);
709
+ }
710
+ if (options.downloadTemplateId) {
711
+ options.downloadTemplate = tmpl(options.downloadTemplateId);
712
+ }
713
+ }
714
+ },
715
+
716
+ _initFilesContainer: function () {
717
+ var options = this.options;
718
+ if (options.filesContainer === undefined) {
719
+ options.filesContainer = this.element.find('.files');
720
+ } else if (!(options.filesContainer instanceof $)) {
721
+ options.filesContainer = $(options.filesContainer);
722
+ }
723
+ },
724
+
725
+ _initSpecialOptions: function () {
726
+ this._super();
727
+ this._initFilesContainer();
728
+ this._initTemplates();
729
+ },
730
+
731
+ _create: function () {
732
+ this._super();
733
+ this._resetFinishedDeferreds();
734
+ if (!$.support.fileInput) {
735
+ this._disableFileInputButton();
736
+ }
737
+ },
738
+
739
+ enable: function () {
740
+ var wasDisabled = false;
741
+ if (this.options.disabled) {
742
+ wasDisabled = true;
743
+ }
744
+ this._super();
745
+ if (wasDisabled) {
746
+ this.element.find('input, button').prop('disabled', false);
747
+ this._enableFileInputButton();
748
+ }
749
+ },
750
+
751
+ disable: function () {
752
+ if (!this.options.disabled) {
753
+ this.element.find('input, button').prop('disabled', true);
754
+ this._disableFileInputButton();
755
+ }
756
+ this._super();
757
+ }
758
+ });
759
+ });