glebtv-rails-uploader 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/README.md +48 -146
- data/Rakefile +2 -2
- data/app/assets/javascripts/uploader/application.js +5 -6
- data/app/assets/javascripts/uploader/rails_admin.js +6 -25
- data/app/assets/stylesheets/uploader/application.css.sass +2 -0
- data/app/assets/stylesheets/uploader/{application.css → application.css.scss} +0 -0
- data/app/controllers/uploader/attachments_controller.rb +28 -50
- data/app/views/rails_admin/main/_form_rails_uploader.haml +1 -10
- data/app/views/uploader/default/_container.html.erb +49 -64
- data/app/views/uploader/default/_download.html.erb +16 -12
- data/app/views/uploader/default/_upload.html.erb +2 -2
- data/config/routes.rb +1 -5
- data/lib/glebtv-rails-uploader.rb +0 -1
- data/lib/uploader.rb +5 -5
- data/lib/uploader/asset.rb +84 -41
- data/lib/uploader/engine.rb +10 -6
- data/lib/uploader/fileuploads.rb +53 -31
- data/lib/uploader/helpers/field_tag.rb +24 -35
- data/lib/uploader/helpers/form_builder.rb +1 -1
- data/lib/uploader/helpers/form_tag_helper.rb +2 -3
- data/lib/uploader/hooks/formtastic.rb +10 -4
- data/lib/uploader/hooks/simple_form.rb +1 -3
- data/lib/uploader/version.rb +1 -1
- data/spec/dummy/app/models/article.rb +3 -7
- data/spec/dummy/app/models/asset.rb +26 -19
- data/spec/dummy/app/models/picture.rb +4 -4
- data/spec/dummy/config/application.rb +5 -7
- data/spec/dummy/config/environments/development.rb +1 -5
- data/spec/dummy/config/environments/production.rb +0 -4
- data/spec/dummy/config/environments/test.rb +2 -6
- data/spec/dummy/db/migrate/20120508093416_create_assets.rb +3 -1
- data/spec/factories/articles.rb +1 -0
- data/spec/factories/assets.rb +1 -0
- data/spec/fileuploads_spec.rb +2 -2
- data/spec/mongoid_spec.rb +4 -6
- data/spec/requests/attachments_controller_spec.rb +10 -2
- data/spec/spec_helper.rb +7 -3
- data/spec/uploader_spec.rb +1 -1
- data/{app → vendor}/assets/images/uploader/but_del_tag2.png +0 -0
- data/{app → vendor}/assets/images/uploader/ico_attach.png +0 -0
- data/{app → vendor}/assets/images/uploader/preloader.gif +0 -0
- data/{app → vendor}/assets/images/uploader/progressBarFillBg.png +0 -0
- data/vendor/assets/javascripts/uploader/jquery.fileupload-fp.js +8 -4
- data/{app → vendor}/assets/javascripts/uploader/jquery.fileupload-ui.js +219 -44
- data/{app → vendor}/assets/javascripts/uploader/jquery.fileupload.js +16 -74
- data/{app → vendor}/assets/javascripts/uploader/jquery.iframe-transport.js +3 -9
- data/vendor/assets/javascripts/uploader/load-image.min.js +1 -0
- data/{app → vendor}/assets/javascripts/uploader/locales/en.js +0 -0
- data/{app → vendor}/assets/javascripts/uploader/locales/ru.js +0 -0
- data/{app → vendor}/assets/javascripts/uploader/locales/uk.js +0 -0
- data/vendor/assets/javascripts/uploader/tmpl.min.js +1 -0
- data/{app/assets/stylesheets/uploader/default.css → vendor/assets/stylesheets/uploader/default.css.scss} +3 -11
- data/{app/assets/stylesheets/uploader/jquery.fileupload-ui.css → vendor/assets/stylesheets/uploader/jquery.fileupload-ui.css.scss} +0 -0
- metadata +78 -146
- data/app/assets/javascripts/uploader/canvas-to-blob.js +0 -95
- data/app/assets/javascripts/uploader/jquery.fileupload-angular.js +0 -348
- data/app/assets/javascripts/uploader/jquery.fileupload-process.js +0 -158
- data/app/assets/javascripts/uploader/jquery.fileupload-resize.js +0 -212
- data/app/assets/javascripts/uploader/jquery.fileupload-validate.js +0 -116
- data/app/assets/javascripts/uploader/jquery.ui.widget.js +0 -530
- data/app/assets/javascripts/uploader/load-image.js +0 -381
- data/app/assets/javascripts/uploader/tmpl.js +0 -86
- data/lib/file_size_validator.rb +0 -68
- data/spec/dummy/config/mongoid.yml +0 -12
data/spec/uploader_spec.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* jQuery File Upload File Processing Plugin 1.2.
|
2
|
+
* jQuery File Upload File Processing Plugin 1.2.3
|
3
3
|
* https://github.com/blueimp/jQuery-File-Upload
|
4
4
|
*
|
5
5
|
* Copyright 2012, Sebastian Tschan
|
@@ -62,9 +62,13 @@
|
|
62
62
|
// fileupload widget (via file input selection, drag & drop or add
|
63
63
|
// API call). See the basic file upload widget for more information:
|
64
64
|
add: function (e, data) {
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
if (data.autoUpload || (data.autoUpload !== false &&
|
66
|
+
($(this).data('blueimp-fileupload') ||
|
67
|
+
$(this).data('fileupload')).options.autoUpload)) {
|
68
|
+
$(this).fileupload('process', data).done(function () {
|
69
|
+
data.submit();
|
70
|
+
});
|
71
|
+
}
|
68
72
|
}
|
69
73
|
},
|
70
74
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* jQuery File Upload User Interface Plugin
|
2
|
+
* jQuery File Upload User Interface Plugin 7.4.4
|
3
3
|
* https://github.com/blueimp/jQuery-File-Upload
|
4
4
|
*
|
5
5
|
* Copyright 2010, Sebastian Tschan
|
@@ -19,25 +19,20 @@
|
|
19
19
|
define([
|
20
20
|
'jquery',
|
21
21
|
'tmpl',
|
22
|
-
'
|
23
|
-
'./jquery.fileupload-
|
22
|
+
'load-image',
|
23
|
+
'./jquery.fileupload-fp'
|
24
24
|
], factory);
|
25
25
|
} else {
|
26
26
|
// Browser globals:
|
27
27
|
factory(
|
28
28
|
window.jQuery,
|
29
|
-
window.tmpl
|
29
|
+
window.tmpl,
|
30
|
+
window.loadImage
|
30
31
|
);
|
31
32
|
}
|
32
33
|
}(function ($, tmpl, loadImage) {
|
33
34
|
'use strict';
|
34
35
|
|
35
|
-
$.blueimp.fileupload.prototype._specialOptions.push(
|
36
|
-
'filesContainer',
|
37
|
-
'uploadTemplateId',
|
38
|
-
'downloadTemplateId'
|
39
|
-
);
|
40
|
-
|
41
36
|
// The UI version extends the file upload widget
|
42
37
|
// and adds complete user interface interaction:
|
43
38
|
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
|
@@ -47,6 +42,29 @@
|
|
47
42
|
// as the user clicks on the start buttons. To enable automatic
|
48
43
|
// uploads, set the following option to true:
|
49
44
|
autoUpload: false,
|
45
|
+
// The following option limits the number of files that are
|
46
|
+
// allowed to be uploaded using this widget:
|
47
|
+
maxNumberOfFiles: undefined,
|
48
|
+
// The maximum allowed file size:
|
49
|
+
maxFileSize: undefined,
|
50
|
+
// The minimum allowed file size:
|
51
|
+
minFileSize: undefined,
|
52
|
+
// The regular expression for allowed file types, matches
|
53
|
+
// against either file type or file name:
|
54
|
+
acceptFileTypes: /.+$/i,
|
55
|
+
// The regular expression to define for which files a preview
|
56
|
+
// image is shown, matched against the file type:
|
57
|
+
previewSourceFileTypes: /^image\/(gif|jpeg|png)$/,
|
58
|
+
// The maximum file size of images that are to be displayed as preview:
|
59
|
+
previewSourceMaxFileSize: 5000000, // 5MB
|
60
|
+
// The maximum width of the preview images:
|
61
|
+
previewMaxWidth: 80,
|
62
|
+
// The maximum height of the preview images:
|
63
|
+
previewMaxHeight: 80,
|
64
|
+
// By default, preview images are displayed as canvas elements
|
65
|
+
// if supported by the browser. Set the following option to false
|
66
|
+
// to always display preview images as img elements:
|
67
|
+
previewAsCanvas: true,
|
50
68
|
// The ID of the upload template:
|
51
69
|
uploadTemplateId: 'template-upload',
|
52
70
|
// The ID of the download template:
|
@@ -61,43 +79,29 @@
|
|
61
79
|
// option of the $.ajax upload requests:
|
62
80
|
dataType: 'json',
|
63
81
|
|
64
|
-
// Function returning the current number of files,
|
65
|
-
// used by the maxNumberOfFiles validation:
|
66
|
-
getNumberOfFiles: function () {
|
67
|
-
return this.filesContainer.children().length;
|
68
|
-
},
|
69
|
-
|
70
|
-
// Callback to retrieve the list of files from the server response:
|
71
|
-
getFilesFromResponse: function (data) {
|
72
|
-
if (data.result && $.isArray(data.result.files)) {
|
73
|
-
return data.result.files;
|
74
|
-
}
|
75
|
-
return [];
|
76
|
-
},
|
77
|
-
|
78
82
|
// The add callback is invoked as soon as files are added to the fileupload
|
79
83
|
// widget (via file input selection, drag & drop or add API call).
|
80
84
|
// See the basic file upload widget for more information:
|
81
85
|
add: function (e, data) {
|
82
|
-
var
|
83
|
-
|
84
|
-
$this.data('fileupload'),
|
86
|
+
var that = $(this).data('blueimp-fileupload') ||
|
87
|
+
$(this).data('fileupload'),
|
85
88
|
options = that.options,
|
86
89
|
files = data.files;
|
87
|
-
data.
|
88
|
-
|
89
|
-
|
90
|
+
$(this).fileupload('process', data).done(function () {
|
91
|
+
that._adjustMaxNumberOfFiles(-files.length);
|
92
|
+
data.maxNumberOfFilesAdjusted = true;
|
93
|
+
data.files.valid = data.isValidated = that._validate(files);
|
90
94
|
data.context = that._renderUpload(files).data('data', data);
|
91
|
-
that._renderPreviews(data);
|
92
95
|
options.filesContainer[
|
93
96
|
options.prependFiles ? 'prepend' : 'append'
|
94
97
|
](data.context);
|
98
|
+
that._renderPreviews(data);
|
95
99
|
that._forceReflow(data.context);
|
96
100
|
that._transition(data.context).done(
|
97
101
|
function () {
|
98
102
|
if ((that._trigger('added', e, data) !== false) &&
|
99
103
|
(options.autoUpload || data.autoUpload) &&
|
100
|
-
data.autoUpload !== false &&
|
104
|
+
data.autoUpload !== false && data.isValidated) {
|
101
105
|
data.submit();
|
102
106
|
}
|
103
107
|
}
|
@@ -108,6 +112,15 @@
|
|
108
112
|
send: function (e, data) {
|
109
113
|
var that = $(this).data('blueimp-fileupload') ||
|
110
114
|
$(this).data('fileupload');
|
115
|
+
if (!data.isValidated) {
|
116
|
+
if (!data.maxNumberOfFilesAdjusted) {
|
117
|
+
that._adjustMaxNumberOfFiles(-data.files.length);
|
118
|
+
data.maxNumberOfFilesAdjusted = true;
|
119
|
+
}
|
120
|
+
if (!that._validate(data.files)) {
|
121
|
+
return false;
|
122
|
+
}
|
123
|
+
}
|
111
124
|
if (data.context && data.dataType &&
|
112
125
|
data.dataType.substr(0, 6) === 'iframe') {
|
113
126
|
// Iframe Transport does not support progress events.
|
@@ -129,9 +142,7 @@
|
|
129
142
|
done: function (e, data) {
|
130
143
|
var that = $(this).data('blueimp-fileupload') ||
|
131
144
|
$(this).data('fileupload'),
|
132
|
-
|
133
|
-
that.options.getFilesFromResponse,
|
134
|
-
files = getFilesFromResponse(data),
|
145
|
+
files = that._getFilesFromResponse(data),
|
135
146
|
template,
|
136
147
|
deferred;
|
137
148
|
if (data.context) {
|
@@ -139,6 +150,9 @@
|
|
139
150
|
var file = files[index] ||
|
140
151
|
{error: 'Empty file upload result'},
|
141
152
|
deferred = that._addFinishedDeferreds();
|
153
|
+
if (file.error) {
|
154
|
+
that._adjustMaxNumberOfFiles(1);
|
155
|
+
}
|
142
156
|
that._transition($(this)).done(
|
143
157
|
function () {
|
144
158
|
var node = $(this);
|
@@ -157,6 +171,17 @@
|
|
157
171
|
);
|
158
172
|
});
|
159
173
|
} else {
|
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
|
+
}
|
160
185
|
template = that._renderDownload(files)
|
161
186
|
.appendTo(that.options.filesContainer);
|
162
187
|
that._forceReflow(template);
|
@@ -177,6 +202,9 @@
|
|
177
202
|
$(this).data('fileupload'),
|
178
203
|
template,
|
179
204
|
deferred;
|
205
|
+
if (data.maxNumberOfFilesAdjusted) {
|
206
|
+
that._adjustMaxNumberOfFiles(data.files.length);
|
207
|
+
}
|
180
208
|
if (data.context) {
|
181
209
|
data.context.each(function (index) {
|
182
210
|
if (data.errorThrown !== 'abort') {
|
@@ -295,12 +323,6 @@
|
|
295
323
|
}
|
296
324
|
);
|
297
325
|
},
|
298
|
-
processstart: function () {
|
299
|
-
$(this).addClass('fileupload-processing');
|
300
|
-
},
|
301
|
-
processstop: function () {
|
302
|
-
$(this).removeClass('fileupload-processing');
|
303
|
-
},
|
304
326
|
// Callback for file deletion:
|
305
327
|
destroy: function (e, data) {
|
306
328
|
var that = $(this).data('blueimp-fileupload') ||
|
@@ -310,6 +332,7 @@
|
|
310
332
|
that._transition(data.context).done(
|
311
333
|
function () {
|
312
334
|
$(this).remove();
|
335
|
+
that._adjustMaxNumberOfFiles(1);
|
313
336
|
that._trigger('destroyed', e, data);
|
314
337
|
}
|
315
338
|
);
|
@@ -334,6 +357,13 @@
|
|
334
357
|
return this._finishedUploads;
|
335
358
|
},
|
336
359
|
|
360
|
+
_getFilesFromResponse: function (data) {
|
361
|
+
if (data.result && $.isArray(data.result.files)) {
|
362
|
+
return data.result.files;
|
363
|
+
}
|
364
|
+
return [];
|
365
|
+
},
|
366
|
+
|
337
367
|
// Link handler, that allows to download files
|
338
368
|
// by drag & drop of the links to the desktop:
|
339
369
|
_enableDragToDesktop: function () {
|
@@ -347,10 +377,21 @@
|
|
347
377
|
'DownloadURL',
|
348
378
|
[type, name, url].join(':')
|
349
379
|
);
|
350
|
-
} catch (
|
380
|
+
} catch (err) {}
|
351
381
|
});
|
352
382
|
},
|
353
383
|
|
384
|
+
_adjustMaxNumberOfFiles: function (operand) {
|
385
|
+
if (typeof this.options.maxNumberOfFiles === 'number') {
|
386
|
+
this.options.maxNumberOfFiles += operand;
|
387
|
+
if (this.options.maxNumberOfFiles < 1) {
|
388
|
+
this._disableFileInputButton();
|
389
|
+
} else {
|
390
|
+
this._enableFileInputButton();
|
391
|
+
}
|
392
|
+
}
|
393
|
+
},
|
394
|
+
|
354
395
|
_formatFileSize: function (bytes) {
|
355
396
|
if (typeof bytes !== 'number') {
|
356
397
|
return '';
|
@@ -406,6 +447,46 @@
|
|
406
447
|
this._formatFileSize(data.total);
|
407
448
|
},
|
408
449
|
|
450
|
+
_hasError: function (file) {
|
451
|
+
if (file.error) {
|
452
|
+
return file.error;
|
453
|
+
}
|
454
|
+
// The number of added files is subtracted from
|
455
|
+
// maxNumberOfFiles before validation, so we check if
|
456
|
+
// maxNumberOfFiles is below 0 (instead of below 1):
|
457
|
+
if (this.options.maxNumberOfFiles < 0) {
|
458
|
+
return 'Maximum number of files exceeded';
|
459
|
+
}
|
460
|
+
// Files are accepted if either the file type or the file name
|
461
|
+
// matches against the acceptFileTypes regular expression, as
|
462
|
+
// only browsers with support for the File API report the type:
|
463
|
+
if (!(this.options.acceptFileTypes.test(file.type) ||
|
464
|
+
this.options.acceptFileTypes.test(file.name))) {
|
465
|
+
return 'Filetype not allowed';
|
466
|
+
}
|
467
|
+
if (this.options.maxFileSize &&
|
468
|
+
file.size > this.options.maxFileSize) {
|
469
|
+
return 'File is too big';
|
470
|
+
}
|
471
|
+
if (typeof file.size === 'number' &&
|
472
|
+
file.size < this.options.minFileSize) {
|
473
|
+
return 'File is too small';
|
474
|
+
}
|
475
|
+
return null;
|
476
|
+
},
|
477
|
+
|
478
|
+
_validate: function (files) {
|
479
|
+
var that = this,
|
480
|
+
valid = !!files.length;
|
481
|
+
$.each(files, function (index, file) {
|
482
|
+
file.error = that._hasError(file);
|
483
|
+
if (file.error) {
|
484
|
+
valid = false;
|
485
|
+
}
|
486
|
+
});
|
487
|
+
return valid;
|
488
|
+
},
|
489
|
+
|
409
490
|
_renderTemplate: function (func, files) {
|
410
491
|
if (!func) {
|
411
492
|
return $();
|
@@ -421,10 +502,63 @@
|
|
421
502
|
return $(this.options.templatesContainer).html(result).children();
|
422
503
|
},
|
423
504
|
|
505
|
+
_renderPreview: function (file, node) {
|
506
|
+
var that = this,
|
507
|
+
options = this.options,
|
508
|
+
dfd = $.Deferred();
|
509
|
+
return ((loadImage && loadImage(
|
510
|
+
file,
|
511
|
+
function (img) {
|
512
|
+
node.append(img);
|
513
|
+
that._forceReflow(node);
|
514
|
+
that._transition(node).done(function () {
|
515
|
+
dfd.resolveWith(node);
|
516
|
+
});
|
517
|
+
if (!$.contains(that.document[0].body, node[0])) {
|
518
|
+
// If the element is not part of the DOM,
|
519
|
+
// transition events are not triggered,
|
520
|
+
// so we have to resolve manually:
|
521
|
+
dfd.resolveWith(node);
|
522
|
+
}
|
523
|
+
node.on('remove', function () {
|
524
|
+
// If the element is removed before the
|
525
|
+
// transition finishes, transition events are
|
526
|
+
// not triggered, resolve manually:
|
527
|
+
dfd.resolveWith(node);
|
528
|
+
});
|
529
|
+
},
|
530
|
+
{
|
531
|
+
maxWidth: options.previewMaxWidth,
|
532
|
+
maxHeight: options.previewMaxHeight,
|
533
|
+
canvas: options.previewAsCanvas
|
534
|
+
}
|
535
|
+
)) || dfd.resolveWith(node)) && dfd;
|
536
|
+
},
|
537
|
+
|
424
538
|
_renderPreviews: function (data) {
|
425
|
-
|
426
|
-
|
539
|
+
var that = this,
|
540
|
+
options = this.options;
|
541
|
+
data.context.find('.preview span').each(function (index, element) {
|
542
|
+
var file = data.files[index];
|
543
|
+
if (options.previewSourceFileTypes.test(file.type) &&
|
544
|
+
($.type(options.previewSourceMaxFileSize) !== 'number' ||
|
545
|
+
file.size < options.previewSourceMaxFileSize)) {
|
546
|
+
that._processingQueue = that._processingQueue.pipe(function () {
|
547
|
+
var dfd = $.Deferred(),
|
548
|
+
ev = $.Event('previewdone', {
|
549
|
+
target: element
|
550
|
+
});
|
551
|
+
that._renderPreview(file, $(element)).done(
|
552
|
+
function () {
|
553
|
+
that._trigger(ev.type, ev, data);
|
554
|
+
dfd.resolveWith(that);
|
555
|
+
}
|
556
|
+
);
|
557
|
+
return dfd.promise();
|
558
|
+
});
|
559
|
+
}
|
427
560
|
});
|
561
|
+
return this._processingQueue;
|
428
562
|
},
|
429
563
|
|
430
564
|
_renderUpload: function (files) {
|
@@ -435,6 +569,7 @@
|
|
435
569
|
},
|
436
570
|
|
437
571
|
_renderDownload: function (files) {
|
572
|
+
console.log(files);
|
438
573
|
return this._renderTemplate(
|
439
574
|
this.options.downloadTemplate,
|
440
575
|
files
|
@@ -597,14 +732,54 @@
|
|
597
732
|
}
|
598
733
|
},
|
599
734
|
|
735
|
+
_stringToRegExp: function (str) {
|
736
|
+
var parts = str.split('/'),
|
737
|
+
modifiers = parts.pop();
|
738
|
+
parts.shift();
|
739
|
+
return new RegExp(parts.join('/'), modifiers);
|
740
|
+
},
|
741
|
+
|
742
|
+
_initRegExpOptions: function () {
|
743
|
+
var options = this.options;
|
744
|
+
if ($.type(options.acceptFileTypes) === 'string') {
|
745
|
+
options.acceptFileTypes = this._stringToRegExp(
|
746
|
+
options.acceptFileTypes
|
747
|
+
);
|
748
|
+
}
|
749
|
+
if ($.type(options.previewSourceFileTypes) === 'string') {
|
750
|
+
options.previewSourceFileTypes = this._stringToRegExp(
|
751
|
+
options.previewSourceFileTypes
|
752
|
+
);
|
753
|
+
}
|
754
|
+
},
|
755
|
+
|
600
756
|
_initSpecialOptions: function () {
|
601
757
|
this._super();
|
602
758
|
this._initFilesContainer();
|
603
759
|
this._initTemplates();
|
760
|
+
this._initRegExpOptions();
|
761
|
+
},
|
762
|
+
|
763
|
+
_setOption: function (key, value) {
|
764
|
+
this._super(key, value);
|
765
|
+
if (key === 'maxNumberOfFiles') {
|
766
|
+
this._adjustMaxNumberOfFiles(0);
|
767
|
+
}
|
604
768
|
},
|
605
769
|
|
606
770
|
_create: function () {
|
607
771
|
this._super();
|
772
|
+
this._refreshOptionsList.push(
|
773
|
+
'filesContainer',
|
774
|
+
'uploadTemplateId',
|
775
|
+
'downloadTemplateId'
|
776
|
+
);
|
777
|
+
if (!this._processingQueue) {
|
778
|
+
this._processingQueue = $.Deferred().resolveWith(this).promise();
|
779
|
+
this.process = function () {
|
780
|
+
return this._processingQueue;
|
781
|
+
};
|
782
|
+
}
|
608
783
|
this._resetFinishedDeferreds();
|
609
784
|
},
|
610
785
|
|