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