card-mod-format 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/assets/script/decko/clicks_and_hovers.js.coffee +49 -0
  3. data/assets/script/decko/decko.js.coffee +32 -0
  4. data/assets/script/decko/decko_jquery.js.coffee +25 -0
  5. data/assets/script/decko/slot.js.coffee +150 -0
  6. data/assets/script/decko/slot_ready.js.coffee +11 -0
  7. data/assets/script/decko/slotter.js.coffee +208 -0
  8. data/assets/script/jquery/jquery-ui.min.js +13 -0
  9. data/assets/script/jquery/jquery.autosize.js +274 -0
  10. data/assets/script/jquery/jquery.ui.autocomplete.html.js +41 -0
  11. data/assets/script/manifest.yml +38 -0
  12. data/assets/style/common.scss +73 -0
  13. data/assets/style/logo_and_credit.scss +24 -0
  14. data/assets/style/menu.scss +43 -0
  15. data/assets/style/messaging.scss +59 -0
  16. data/assets/style/misc.scss +90 -0
  17. data/assets/style/open_and_closed.scss +68 -0
  18. data/data/files/credit_image.svg +59 -0
  19. data/data/files/mod_format_script_asset_output/file.js +66 -0
  20. data/data/real.yml +67 -0
  21. data/lib/card/format/html_format.rb +0 -2
  22. data/lib/card/mod/format.rb +4 -0
  23. data/lib/card/path.rb +20 -20
  24. data/set/all/base.rb +1 -11
  25. data/set/all/content.rb +3 -11
  26. data/set/all/csv.rb +22 -74
  27. data/set/all/data.rb +2 -2
  28. data/set/all/demo.rb +6 -2
  29. data/set/all/error.rb +1 -1
  30. data/set/all/html/error.rb +1 -1
  31. data/set/all/html/head.rb +22 -12
  32. data/set/all/html/header.rb +10 -40
  33. data/set/all/html/header_wrap.haml +3 -4
  34. data/set/all/html/labeled.haml +1 -1
  35. data/set/all/html/menu.rb +36 -12
  36. data/set/all/html/views.rb +8 -17
  37. data/set/all/html/wrap.rb +5 -4
  38. data/set/all/html.rb +2 -3
  39. data/set/all/json.rb +1 -5
  40. data/set/right/head.rb +1 -0
  41. data/set/type/cardtype.rb +4 -6
  42. data/set/type/json.rb +1 -1
  43. data/set/type/number.rb +1 -16
  44. data/vendor/jquery_file_upload/LICENSE.txt +20 -0
  45. data/vendor/jquery_file_upload/README.md +224 -0
  46. data/vendor/jquery_file_upload/SECURITY.md +227 -0
  47. data/vendor/jquery_file_upload/VULNERABILITIES.md +118 -0
  48. data/vendor/jquery_file_upload/cors/postmessage.html +85 -0
  49. data/vendor/jquery_file_upload/cors/result.html +26 -0
  50. data/vendor/jquery_file_upload/css/jquery.fileupload-noscript.css +22 -0
  51. data/vendor/jquery_file_upload/css/jquery.fileupload-ui-noscript.css +17 -0
  52. data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +68 -0
  53. data/vendor/jquery_file_upload/css/jquery.fileupload.css +36 -0
  54. data/vendor/jquery_file_upload/docker-compose.yml +55 -0
  55. data/vendor/jquery_file_upload/img/loading.gif +0 -0
  56. data/vendor/jquery_file_upload/img/progressbar.gif +0 -0
  57. data/vendor/jquery_file_upload/index.html +357 -0
  58. data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +126 -0
  59. data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +97 -0
  60. data/vendor/jquery_file_upload/js/demo.js +75 -0
  61. data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +101 -0
  62. data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +347 -0
  63. data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +170 -0
  64. data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +759 -0
  65. data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +119 -0
  66. data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +101 -0
  67. data/vendor/jquery_file_upload/js/jquery.fileupload.js +1604 -0
  68. data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +227 -0
  69. data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +805 -0
  70. data/vendor/jquery_file_upload/package-lock.json +6853 -0
  71. data/vendor/jquery_file_upload/package.json +116 -0
  72. data/vendor/jquery_file_upload/server/gae-python/app.yaml +18 -0
  73. data/vendor/jquery_file_upload/server/gae-python/main.py +204 -0
  74. data/vendor/jquery_file_upload/server/gae-python/static/favicon.ico +0 -0
  75. data/vendor/jquery_file_upload/server/gae-python/static/robots.txt +2 -0
  76. data/vendor/jquery_file_upload/server/php/Dockerfile +44 -0
  77. data/vendor/jquery_file_upload/server/php/UploadHandler.php +1480 -0
  78. data/vendor/jquery_file_upload/server/php/index.php +15 -0
  79. data/vendor/jquery_file_upload/server/php/php.ini +5 -0
  80. data/vendor/jquery_file_upload/test/index.html +49 -0
  81. data/vendor/jquery_file_upload/test/unit.js +989 -0
  82. data/vendor/jquery_file_upload/test/vendor/chai.js +10854 -0
  83. data/vendor/jquery_file_upload/test/vendor/mocha.css +325 -0
  84. data/vendor/jquery_file_upload/test/vendor/mocha.js +18178 -0
  85. data/vendor/jquery_file_upload/wdio/LICENSE.txt +20 -0
  86. data/vendor/jquery_file_upload/wdio/assets/black+white-3x2.jpg +0 -0
  87. data/vendor/jquery_file_upload/wdio/assets/black+white-60x40.gif +0 -0
  88. data/vendor/jquery_file_upload/wdio/conf/chrome.js +40 -0
  89. data/vendor/jquery_file_upload/wdio/conf/firefox.js +25 -0
  90. data/vendor/jquery_file_upload/wdio/hooks/index.js +36 -0
  91. data/vendor/jquery_file_upload/wdio/test/pages/file-upload.js +79 -0
  92. data/vendor/jquery_file_upload/wdio/test/specs/01-file-upload.js +25 -0
  93. data/vendor/jquery_file_upload/wdio/wdio.conf.js +4 -0
  94. data/vendor/jquery_rails/CHANGELOG.md +359 -0
  95. data/vendor/jquery_rails/CONTRIBUTING.md +132 -0
  96. data/vendor/jquery_rails/Gemfile +22 -0
  97. data/vendor/jquery_rails/MIT-LICENSE +21 -0
  98. data/vendor/jquery_rails/README.md +75 -0
  99. data/vendor/jquery_rails/Rakefile +59 -0
  100. data/vendor/jquery_rails/VERSIONS.md +62 -0
  101. data/vendor/jquery_rails/jquery-rails.gemspec +26 -0
  102. data/vendor/jquery_rails/lib/jquery/assert_select.rb +149 -0
  103. data/vendor/jquery_rails/lib/jquery/rails/engine.rb +6 -0
  104. data/vendor/jquery_rails/lib/jquery/rails/version.rb +9 -0
  105. data/vendor/jquery_rails/lib/jquery/rails.rb +8 -0
  106. data/vendor/jquery_rails/lib/jquery-rails.rb +1 -0
  107. data/vendor/jquery_rails/test/assert_select_jquery_test.rb +85 -0
  108. data/vendor/jquery_rails/test/test_helper.rb +6 -0
  109. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.js +11008 -0
  110. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.js +5 -0
  111. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.map +1 -0
  112. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.js +9814 -0
  113. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.js +4 -0
  114. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.map +1 -0
  115. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.js +10364 -0
  116. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.js +2 -0
  117. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.map +1 -0
  118. data/vendor/jquery_rails/vendor/assets/javascripts/jquery_ujs.js +555 -0
  119. metadata +104 -7
@@ -0,0 +1,759 @@
1
+ /*
2
+ * jQuery File Upload User Interface Plugin
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
+ * https://opensource.org/licenses/MIT
10
+ */
11
+
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')
35
+ );
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();
133
+ }
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
+ });
143
+ }
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
+ });
197
+ });
198
+ });
199
+ } else {
200
+ template = that
201
+ ._renderDownload(files)
202
+ [that.options.prependFiles ? 'prependTo' : 'appendTo'](
203
+ that.options.filesContainer
204
+ );
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
+ });
242
+ } else {
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
+ });
250
+ }
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);
374
+ });
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);
382
+ });
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);
546
+ }
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');
630
+ }
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
+ });