jquery.fileupload-rails 0.1.0 → 0.1.1
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 +13 -3
- data/jquery.fileupload-rails.gemspec +1 -3
- data/lib/jquery.fileupload-rails/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.fileupload-fp.js +219 -0
- data/vendor/assets/javascripts/jquery.fileupload-ui.js +113 -40
- data/vendor/assets/javascripts/jquery.fileupload.js +108 -25
- data/vendor/assets/javascripts/jquery.iframe-transport.js +11 -5
- metadata +21 -5
data/Readme.md
CHANGED
@@ -5,10 +5,20 @@ The plugin is developed by Sebastian Tschan (@blueimp) and well maintained.
|
|
5
5
|
|
6
6
|
This is a simple gem package for this plugin.
|
7
7
|
|
8
|
-
[See the original project page]
|
8
|
+
[See the original project page][1] for reference & documentation.
|
9
9
|
|
10
10
|
## Changelog
|
11
11
|
|
12
|
-
0.1.
|
12
|
+
0.1.1. Core 5.11.2, UI 6.9.1, minor gemspec change.
|
13
13
|
|
14
|
-
0.
|
14
|
+
0.1.0. Core 5.9.0, UI 6.6.2, added readme.
|
15
|
+
|
16
|
+
0.0.1. Core 5.5.2, UI 5.1.1.
|
17
|
+
|
18
|
+
## Todo
|
19
|
+
|
20
|
+
* Add convinient file-package with jquery.fileupload and all it's dependencies.
|
21
|
+
* Add example usage in Rails here.
|
22
|
+
* Add script to automate updating the library from [the official repo][1].
|
23
|
+
|
24
|
+
[1]: https://github.com/blueimp/jQuery-File-Upload
|
@@ -18,7 +18,5 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
22
|
-
# s.add_development_dependency "rspec"
|
23
|
-
# s.add_runtime_dependency "rest-client"
|
21
|
+
s.add_dependency 'sprockets', '~> 2.0'
|
24
22
|
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery File Upload File Processing Plugin 1.0
|
3
|
+
* https://github.com/blueimp/jQuery-File-Upload
|
4
|
+
*
|
5
|
+
* Copyright 2012, Sebastian Tschan
|
6
|
+
* https://blueimp.net
|
7
|
+
*
|
8
|
+
* Licensed under the MIT license:
|
9
|
+
* http://www.opensource.org/licenses/MIT
|
10
|
+
*/
|
11
|
+
|
12
|
+
/*jslint nomen: true, unparam: true, regexp: true */
|
13
|
+
/*global define, window, document */
|
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
|
+
'load-image',
|
22
|
+
'canvas-to-blob',
|
23
|
+
'./jquery.fileupload'
|
24
|
+
], factory);
|
25
|
+
} else {
|
26
|
+
// Browser globals:
|
27
|
+
factory(
|
28
|
+
window.jQuery,
|
29
|
+
window.loadImage
|
30
|
+
);
|
31
|
+
}
|
32
|
+
}(function ($, loadImage) {
|
33
|
+
'use strict';
|
34
|
+
|
35
|
+
// The File Upload IP version extends the basic fileupload widget
|
36
|
+
// with file processing functionality:
|
37
|
+
$.widget('blueimpFP.fileupload', $.blueimp.fileupload, {
|
38
|
+
|
39
|
+
options: {
|
40
|
+
// The list of file processing actions:
|
41
|
+
process: [
|
42
|
+
/*
|
43
|
+
{
|
44
|
+
action: 'load',
|
45
|
+
fileTypes: /^image\/(gif|jpeg|png)$/,
|
46
|
+
maxFileSize: 20000000 // 20MB
|
47
|
+
},
|
48
|
+
{
|
49
|
+
action: 'resize',
|
50
|
+
maxWidth: 1920,
|
51
|
+
maxHeight: 1200,
|
52
|
+
minWidth: 800,
|
53
|
+
minHeight: 600
|
54
|
+
},
|
55
|
+
{
|
56
|
+
action: 'save'
|
57
|
+
}
|
58
|
+
*/
|
59
|
+
],
|
60
|
+
|
61
|
+
// The add callback is invoked as soon as files are added to the
|
62
|
+
// fileupload widget (via file input selection, drag & drop or add
|
63
|
+
// API call). See the basic file upload widget for more information:
|
64
|
+
add: function (e, data) {
|
65
|
+
$(this).fileupload('process', data).done(function () {
|
66
|
+
data.submit();
|
67
|
+
});
|
68
|
+
}
|
69
|
+
},
|
70
|
+
|
71
|
+
processActions: {
|
72
|
+
// Loads the image given via data.files and data.index
|
73
|
+
// as canvas element.
|
74
|
+
// Accepts the options fileTypes (regular expression)
|
75
|
+
// and maxFileSize (integer) to limit the files to load:
|
76
|
+
load: function (data, options) {
|
77
|
+
var that = this,
|
78
|
+
file = data.files[data.index],
|
79
|
+
dfd = $.Deferred();
|
80
|
+
if (window.HTMLCanvasElement &&
|
81
|
+
window.HTMLCanvasElement.prototype.toBlob &&
|
82
|
+
($.type(options.maxFileSize) !== 'number' ||
|
83
|
+
file.size < options.maxFileSize) &&
|
84
|
+
(!options.fileTypes ||
|
85
|
+
options.fileTypes.test(file.type))) {
|
86
|
+
loadImage(
|
87
|
+
file,
|
88
|
+
function (canvas) {
|
89
|
+
data.canvas = canvas;
|
90
|
+
dfd.resolveWith(that, [data]);
|
91
|
+
},
|
92
|
+
{canvas: true}
|
93
|
+
);
|
94
|
+
} else {
|
95
|
+
dfd.rejectWith(that, [data]);
|
96
|
+
}
|
97
|
+
return dfd.promise();
|
98
|
+
},
|
99
|
+
// Resizes the image given as data.canvas and updates
|
100
|
+
// data.canvas with the resized image.
|
101
|
+
// Accepts the options maxWidth, maxHeight, minWidth and
|
102
|
+
// minHeight to scale the given image:
|
103
|
+
resize: function (data, options) {
|
104
|
+
if (data.canvas) {
|
105
|
+
var canvas = loadImage.scale(data.canvas, options);
|
106
|
+
if (canvas.width !== data.canvas.width ||
|
107
|
+
canvas.height !== data.canvas.height) {
|
108
|
+
data.canvas = canvas;
|
109
|
+
data.processed = true;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
return data;
|
113
|
+
},
|
114
|
+
// Saves the processed image given as data.canvas
|
115
|
+
// inplace at data.index of data.files:
|
116
|
+
save: function (data, options) {
|
117
|
+
// Do nothing if no processing has happened:
|
118
|
+
if (!data.canvas || !data.processed) {
|
119
|
+
return data;
|
120
|
+
}
|
121
|
+
var that = this,
|
122
|
+
file = data.files[data.index],
|
123
|
+
name = file.name,
|
124
|
+
dfd = $.Deferred(),
|
125
|
+
callback = function (blob) {
|
126
|
+
if (!blob.name) {
|
127
|
+
if (file.type === blob.type) {
|
128
|
+
blob.name = file.name;
|
129
|
+
} else if (file.name) {
|
130
|
+
blob.name = file.name.replace(
|
131
|
+
/\..+$/,
|
132
|
+
'.' + blob.type.substr(6)
|
133
|
+
);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
// Store the created blob at the position
|
137
|
+
// of the original file in the files list:
|
138
|
+
data.files[data.index] = blob;
|
139
|
+
dfd.resolveWith(that, [data]);
|
140
|
+
};
|
141
|
+
// Use canvas.mozGetAsFile directly, to retain the filename, as
|
142
|
+
// Gecko doesn't support the filename option for FormData.append:
|
143
|
+
if (data.canvas.mozGetAsFile) {
|
144
|
+
callback(data.canvas.mozGetAsFile(
|
145
|
+
(/^image\/(jpeg|png)$/.test(file.type) && name) ||
|
146
|
+
((name && name.replace(/\..+$/, '')) ||
|
147
|
+
'blob') + '.png',
|
148
|
+
file.type
|
149
|
+
));
|
150
|
+
} else {
|
151
|
+
data.canvas.toBlob(callback, file.type);
|
152
|
+
}
|
153
|
+
return dfd.promise();
|
154
|
+
}
|
155
|
+
},
|
156
|
+
|
157
|
+
// Resizes the file at the given index and stores the created blob at
|
158
|
+
// the original position of the files list, returns a Promise object:
|
159
|
+
_processFile: function (files, index, options) {
|
160
|
+
var that = this,
|
161
|
+
dfd = $.Deferred().resolveWith(that, [{
|
162
|
+
files: files,
|
163
|
+
index: index
|
164
|
+
}]),
|
165
|
+
chain = dfd.promise();
|
166
|
+
that._processing += 1;
|
167
|
+
$.each(options.process, function (i, settings) {
|
168
|
+
chain = chain.pipe(function (data) {
|
169
|
+
return that.processActions[settings.action]
|
170
|
+
.call(this, data, settings);
|
171
|
+
});
|
172
|
+
});
|
173
|
+
chain.always(function () {
|
174
|
+
that._processing -= 1;
|
175
|
+
if (that._processing === 0) {
|
176
|
+
that.element
|
177
|
+
.removeClass('fileupload-processing');
|
178
|
+
}
|
179
|
+
});
|
180
|
+
if (that._processing === 1) {
|
181
|
+
that.element.addClass('fileupload-processing');
|
182
|
+
}
|
183
|
+
return chain;
|
184
|
+
},
|
185
|
+
|
186
|
+
// Processes the files given as files property of the data parameter,
|
187
|
+
// returns a Promise object that allows to bind a done handler, which
|
188
|
+
// will be invoked after processing all files (inplace) is done:
|
189
|
+
process: function (data) {
|
190
|
+
var that = this,
|
191
|
+
options = $.extend({}, this.options, data);
|
192
|
+
if (options.process && options.process.length &&
|
193
|
+
this._isXHRUpload(options)) {
|
194
|
+
$.each(data.files, function (index, file) {
|
195
|
+
that._processingQueue = that._processingQueue.pipe(
|
196
|
+
function () {
|
197
|
+
var dfd = $.Deferred();
|
198
|
+
that._processFile(data.files, index, options)
|
199
|
+
.always(function () {
|
200
|
+
dfd.resolveWith(that);
|
201
|
+
});
|
202
|
+
return dfd.promise();
|
203
|
+
}
|
204
|
+
);
|
205
|
+
});
|
206
|
+
}
|
207
|
+
return this._processingQueue;
|
208
|
+
},
|
209
|
+
|
210
|
+
_create: function () {
|
211
|
+
$.blueimp.fileupload.prototype._create.call(this);
|
212
|
+
this._processing = 0;
|
213
|
+
this._processingQueue = $.Deferred().resolveWith(this)
|
214
|
+
.promise();
|
215
|
+
}
|
216
|
+
|
217
|
+
});
|
218
|
+
|
219
|
+
}));
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* jQuery File Upload User Interface Plugin 6.
|
2
|
+
* jQuery File Upload User Interface Plugin 6.9.1
|
3
3
|
* https://github.com/blueimp/jQuery-File-Upload
|
4
4
|
*
|
5
5
|
* Copyright 2010, Sebastian Tschan
|
@@ -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,9 +33,9 @@
|
|
33
33
|
}(function ($, tmpl, loadImage) {
|
34
34
|
'use strict';
|
35
35
|
|
36
|
-
// The UI version extends the
|
36
|
+
// The UI version extends the FP (file processing) version or the basic
|
37
37
|
// file upload widget and adds complete user interface interaction:
|
38
|
-
var parentWidget = ($.
|
38
|
+
var parentWidget = ($.blueimpFP || $.blueimp).fileupload;
|
39
39
|
$.widget('blueimpUI.fileupload', parentWidget, {
|
40
40
|
|
41
41
|
options: {
|
@@ -70,6 +70,12 @@
|
|
70
70
|
uploadTemplateId: 'template-upload',
|
71
71
|
// The ID of the download template:
|
72
72
|
downloadTemplateId: 'template-download',
|
73
|
+
// The container for the list of files. If undefined, it is set to
|
74
|
+
// an element with class "files" inside of the widget element:
|
75
|
+
filesContainer: undefined,
|
76
|
+
// By default, files are appended to the files container.
|
77
|
+
// Set the following option to true, to prepend files instead:
|
78
|
+
prependFiles: false,
|
73
79
|
// The expected data type of the upload response, sets the dataType
|
74
80
|
// option of the $.ajax upload requests:
|
75
81
|
dataType: 'json',
|
@@ -81,13 +87,14 @@
|
|
81
87
|
var that = $(this).data('fileupload'),
|
82
88
|
options = that.options,
|
83
89
|
files = data.files;
|
84
|
-
|
85
|
-
|
86
|
-
|
90
|
+
$(this).fileupload('process', data).done(function () {
|
91
|
+
that._adjustMaxNumberOfFiles(-files.length);
|
92
|
+
data.isAdjusted = true;
|
87
93
|
data.files.valid = data.isValidated = that._validate(files);
|
88
|
-
data.context = that._renderUpload(files)
|
89
|
-
|
90
|
-
.
|
94
|
+
data.context = that._renderUpload(files).data('data', data);
|
95
|
+
options.filesContainer[
|
96
|
+
options.prependFiles ? 'prepend' : 'append'
|
97
|
+
](data.context);
|
91
98
|
that._renderPreviews(files, data.context);
|
92
99
|
that._forceReflow(data.context);
|
93
100
|
that._transition(data.context).done(
|
@@ -121,9 +128,10 @@
|
|
121
128
|
.find('.progress').addClass(
|
122
129
|
!$.support.transition && 'progress-animated'
|
123
130
|
)
|
131
|
+
.attr('aria-valuenow', 100)
|
124
132
|
.find('.bar').css(
|
125
133
|
'width',
|
126
|
-
|
134
|
+
'100%'
|
127
135
|
);
|
128
136
|
}
|
129
137
|
return that._trigger('sent', e, data);
|
@@ -131,8 +139,7 @@
|
|
131
139
|
// Callback for successful uploads:
|
132
140
|
done: function (e, data) {
|
133
141
|
var that = $(this).data('fileupload'),
|
134
|
-
template
|
135
|
-
preview;
|
142
|
+
template;
|
136
143
|
if (data.context) {
|
137
144
|
data.context.each(function (index) {
|
138
145
|
var file = ($.isArray(data.result) &&
|
@@ -221,23 +228,39 @@
|
|
221
228
|
// Callback for upload progress events:
|
222
229
|
progress: function (e, data) {
|
223
230
|
if (data.context) {
|
224
|
-
data.
|
225
|
-
|
226
|
-
|
227
|
-
|
231
|
+
var progress = parseInt(data.loaded / data.total * 100, 10);
|
232
|
+
data.context.find('.progress')
|
233
|
+
.attr('aria-valuenow', progress)
|
234
|
+
.find('.bar').css(
|
235
|
+
'width',
|
236
|
+
progress + '%'
|
237
|
+
);
|
228
238
|
}
|
229
239
|
},
|
230
240
|
// Callback for global upload progress events:
|
231
241
|
progressall: function (e, data) {
|
232
|
-
$
|
233
|
-
|
234
|
-
|
235
|
-
|
242
|
+
var $this = $(this),
|
243
|
+
progress = parseInt(data.loaded / data.total * 100, 10),
|
244
|
+
globalProgressNode = $this.find('.fileupload-progress'),
|
245
|
+
extendedProgressNode = globalProgressNode
|
246
|
+
.find('.progress-extended');
|
247
|
+
if (extendedProgressNode.length) {
|
248
|
+
extendedProgressNode.html(
|
249
|
+
$this.data('fileupload')._renderExtendedProgress(data)
|
250
|
+
);
|
251
|
+
}
|
252
|
+
globalProgressNode
|
253
|
+
.find('.progress')
|
254
|
+
.attr('aria-valuenow', progress)
|
255
|
+
.find('.bar').css(
|
256
|
+
'width',
|
257
|
+
progress + '%'
|
258
|
+
);
|
236
259
|
},
|
237
260
|
// Callback for uploads start, equivalent to the global ajaxStart event:
|
238
261
|
start: function (e) {
|
239
262
|
var that = $(this).data('fileupload');
|
240
|
-
that._transition($(this).find('.fileupload-
|
263
|
+
that._transition($(this).find('.fileupload-progress')).done(
|
241
264
|
function () {
|
242
265
|
that._trigger('started', e);
|
243
266
|
}
|
@@ -246,9 +269,12 @@
|
|
246
269
|
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
247
270
|
stop: function (e) {
|
248
271
|
var that = $(this).data('fileupload');
|
249
|
-
that._transition($(this).find('.fileupload-
|
272
|
+
that._transition($(this).find('.fileupload-progress')).done(
|
250
273
|
function () {
|
251
|
-
$(this).find('.
|
274
|
+
$(this).find('.progress')
|
275
|
+
.attr('aria-valuenow', '0')
|
276
|
+
.find('.bar').css('width', '0%');
|
277
|
+
$(this).find('.progress-extended').html(' ');
|
252
278
|
that._trigger('stopped', e);
|
253
279
|
}
|
254
280
|
);
|
@@ -258,8 +284,8 @@
|
|
258
284
|
var that = $(this).data('fileupload');
|
259
285
|
if (data.url) {
|
260
286
|
$.ajax(data);
|
287
|
+
that._adjustMaxNumberOfFiles(1);
|
261
288
|
}
|
262
|
-
that._adjustMaxNumberOfFiles(1);
|
263
289
|
that._transition(data.context).done(
|
264
290
|
function () {
|
265
291
|
$(this).remove();
|
@@ -310,6 +336,48 @@
|
|
310
336
|
return (bytes / 1000).toFixed(2) + ' KB';
|
311
337
|
},
|
312
338
|
|
339
|
+
_formatBitrate: function (bits) {
|
340
|
+
if (typeof bits !== 'number') {
|
341
|
+
return '';
|
342
|
+
}
|
343
|
+
if (bits >= 1000000000) {
|
344
|
+
return (bits / 1000000000).toFixed(2) + ' Gbit/s';
|
345
|
+
}
|
346
|
+
if (bits >= 1000000) {
|
347
|
+
return (bits / 1000000).toFixed(2) + ' Mbit/s';
|
348
|
+
}
|
349
|
+
if (bits >= 1000) {
|
350
|
+
return (bits / 1000).toFixed(2) + ' kbit/s';
|
351
|
+
}
|
352
|
+
return bits + ' bit/s';
|
353
|
+
},
|
354
|
+
|
355
|
+
_formatTime: function (seconds) {
|
356
|
+
var date = new Date(seconds * 1000),
|
357
|
+
days = parseInt(seconds / 86400, 10);
|
358
|
+
days = days ? days + 'd ' : '';
|
359
|
+
return days +
|
360
|
+
('0' + date.getUTCHours()).slice(-2) + ':' +
|
361
|
+
('0' + date.getUTCMinutes()).slice(-2) + ':' +
|
362
|
+
('0' + date.getUTCSeconds()).slice(-2);
|
363
|
+
},
|
364
|
+
|
365
|
+
_formatPercentage: function (floatValue) {
|
366
|
+
return (floatValue * 100).toFixed(2) + ' %';
|
367
|
+
},
|
368
|
+
|
369
|
+
_renderExtendedProgress: function (data) {
|
370
|
+
return this._formatBitrate(data.bitrate) + ' | ' +
|
371
|
+
this._formatTime(
|
372
|
+
(data.total - data.loaded) * 8 / data.bitrate
|
373
|
+
) + ' | ' +
|
374
|
+
this._formatPercentage(
|
375
|
+
data.loaded / data.total
|
376
|
+
) + ' | ' +
|
377
|
+
this._formatFileSize(data.loaded) + ' / ' +
|
378
|
+
this._formatFileSize(data.total);
|
379
|
+
},
|
380
|
+
|
313
381
|
_hasError: function (file) {
|
314
382
|
if (file.error) {
|
315
383
|
return file.error;
|
@@ -368,22 +436,28 @@
|
|
368
436
|
_renderPreview: function (file, node) {
|
369
437
|
var that = this,
|
370
438
|
options = this.options,
|
371
|
-
|
439
|
+
dfd = $.Deferred();
|
372
440
|
return ((loadImage && loadImage(
|
373
441
|
file,
|
374
442
|
function (img) {
|
375
443
|
node.append(img);
|
376
444
|
that._forceReflow(node);
|
377
445
|
that._transition(node).done(function () {
|
378
|
-
|
446
|
+
dfd.resolveWith(node);
|
379
447
|
});
|
448
|
+
if (!$.contains(document.body, node[0])) {
|
449
|
+
// If the element is not part of the DOM,
|
450
|
+
// transition events are not triggered,
|
451
|
+
// so we have to resolve manually:
|
452
|
+
dfd.resolveWith(node);
|
453
|
+
}
|
380
454
|
},
|
381
455
|
{
|
382
456
|
maxWidth: options.previewMaxWidth,
|
383
457
|
maxHeight: options.previewMaxHeight,
|
384
458
|
canvas: options.previewAsCanvas
|
385
459
|
}
|
386
|
-
)) ||
|
460
|
+
)) || dfd.resolveWith(node)) && dfd;
|
387
461
|
},
|
388
462
|
|
389
463
|
_renderPreviews: function (files, nodes) {
|
@@ -395,13 +469,13 @@
|
|
395
469
|
($.type(options.previewSourceMaxFileSize) !== 'number' ||
|
396
470
|
file.size < options.previewSourceMaxFileSize)) {
|
397
471
|
that._processingQueue = that._processingQueue.pipe(function () {
|
398
|
-
var
|
472
|
+
var dfd = $.Deferred();
|
399
473
|
that._renderPreview(file, $(element)).done(
|
400
474
|
function () {
|
401
|
-
|
475
|
+
dfd.resolveWith(that);
|
402
476
|
}
|
403
477
|
);
|
404
|
-
return
|
478
|
+
return dfd.promise();
|
405
479
|
});
|
406
480
|
}
|
407
481
|
});
|
@@ -456,13 +530,12 @@
|
|
456
530
|
},
|
457
531
|
|
458
532
|
_forceReflow: function (node) {
|
459
|
-
|
460
|
-
node
|
533
|
+
return $.support.transition && node.length &&
|
534
|
+
node[0].offsetWidth;
|
461
535
|
},
|
462
536
|
|
463
537
|
_transition: function (node) {
|
464
|
-
var
|
465
|
-
deferred = $.Deferred();
|
538
|
+
var dfd = $.Deferred();
|
466
539
|
if ($.support.transition && node.hasClass('fade')) {
|
467
540
|
node.bind(
|
468
541
|
$.support.transition.end,
|
@@ -471,15 +544,15 @@
|
|
471
544
|
// in the container element, e.g. from button elements:
|
472
545
|
if (e.target === node[0]) {
|
473
546
|
node.unbind($.support.transition.end);
|
474
|
-
|
547
|
+
dfd.resolveWith(node);
|
475
548
|
}
|
476
549
|
}
|
477
550
|
).toggleClass('in');
|
478
551
|
} else {
|
479
552
|
node.toggleClass('in');
|
480
|
-
|
553
|
+
dfd.resolveWith(node);
|
481
554
|
}
|
482
|
-
return
|
555
|
+
return dfd;
|
483
556
|
},
|
484
557
|
|
485
558
|
_initButtonBarEventHandlers: function () {
|
@@ -604,9 +677,9 @@
|
|
604
677
|
'uploadTemplateId',
|
605
678
|
'downloadTemplateId'
|
606
679
|
);
|
607
|
-
if (!$.
|
680
|
+
if (!$.blueimpFP) {
|
608
681
|
this._processingQueue = $.Deferred().resolveWith(this).promise();
|
609
|
-
this.
|
682
|
+
this.process = function () {
|
610
683
|
return this._processingQueue;
|
611
684
|
};
|
612
685
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* jQuery File Upload Plugin 5.
|
2
|
+
* jQuery File Upload Plugin 5.11.2
|
3
3
|
* https://github.com/blueimp/jQuery-File-Upload
|
4
4
|
*
|
5
5
|
* Copyright 2010, Sebastian Tschan
|
@@ -63,7 +63,8 @@
|
|
63
63
|
replaceFileInput: true,
|
64
64
|
// The parameter name for the file form data (the request argument name).
|
65
65
|
// If undefined or empty, the name property of the file input field is
|
66
|
-
// used, or "files[]" if the file input name property is also empty
|
66
|
+
// used, or "files[]" if the file input name property is also empty,
|
67
|
+
// can be a string or an array of strings:
|
67
68
|
paramName: undefined,
|
68
69
|
// By default, each file of a selection is uploaded using an individual
|
69
70
|
// request for XHR type uploads. Set to false to upload file
|
@@ -108,6 +109,10 @@
|
|
108
109
|
// global progress calculation. Set the following option to false to
|
109
110
|
// prevent recalculating the global progress data:
|
110
111
|
recalculateProgress: true,
|
112
|
+
// Interval in milliseconds to calculate and trigger progress events:
|
113
|
+
progressInterval: 100,
|
114
|
+
// Interval in milliseconds to calculate progress bitrate:
|
115
|
+
bitrateInterval: 500,
|
111
116
|
|
112
117
|
// Additional form data to be sent along with the file uploads can be set
|
113
118
|
// using this option, which accepts an array of objects with name and
|
@@ -179,6 +184,21 @@
|
|
179
184
|
'forceIframeTransport'
|
180
185
|
],
|
181
186
|
|
187
|
+
_BitrateTimer: function () {
|
188
|
+
this.timestamp = +(new Date());
|
189
|
+
this.loaded = 0;
|
190
|
+
this.bitrate = 0;
|
191
|
+
this.getBitrate = function (now, loaded, interval) {
|
192
|
+
var timeDiff = now - this.timestamp;
|
193
|
+
if (!this.bitrate || !interval || timeDiff > interval) {
|
194
|
+
this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
|
195
|
+
this.loaded = loaded;
|
196
|
+
this.timestamp = now;
|
197
|
+
}
|
198
|
+
return this.bitrate;
|
199
|
+
};
|
200
|
+
},
|
201
|
+
|
182
202
|
_isXHRUpload: function (options) {
|
183
203
|
return !options.forceIframeTransport &&
|
184
204
|
((!options.multipart && $.support.xhrFileUpload) ||
|
@@ -189,9 +209,11 @@
|
|
189
209
|
var formData;
|
190
210
|
if (typeof options.formData === 'function') {
|
191
211
|
return options.formData(options.form);
|
192
|
-
}
|
212
|
+
}
|
213
|
+
if ($.isArray(options.formData)) {
|
193
214
|
return options.formData;
|
194
|
-
}
|
215
|
+
}
|
216
|
+
if (options.formData) {
|
195
217
|
formData = [];
|
196
218
|
$.each(options.formData, function (name, value) {
|
197
219
|
formData.push({name: name, value: value});
|
@@ -211,15 +233,29 @@
|
|
211
233
|
|
212
234
|
_onProgress: function (e, data) {
|
213
235
|
if (e.lengthComputable) {
|
214
|
-
var
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
236
|
+
var now = +(new Date()),
|
237
|
+
total,
|
238
|
+
loaded;
|
239
|
+
if (data._time && data.progressInterval &&
|
240
|
+
(now - data._time < data.progressInterval) &&
|
241
|
+
e.loaded !== e.total) {
|
242
|
+
return;
|
243
|
+
}
|
244
|
+
data._time = now;
|
245
|
+
total = data.total || this._getTotal(data.files);
|
246
|
+
loaded = parseInt(
|
247
|
+
e.loaded / e.total * (data.chunkSize || total),
|
248
|
+
10
|
249
|
+
) + (data.uploadedBytes || 0);
|
219
250
|
this._loaded += loaded - (data.loaded || data.uploadedBytes || 0);
|
220
251
|
data.lengthComputable = true;
|
221
252
|
data.loaded = loaded;
|
222
253
|
data.total = total;
|
254
|
+
data.bitrate = data._bitrateTimer.getBitrate(
|
255
|
+
now,
|
256
|
+
loaded,
|
257
|
+
data.bitrateInterval
|
258
|
+
);
|
223
259
|
// Trigger a custom progress event with a total data property set
|
224
260
|
// to the file size(s) of the current upload and a loaded data
|
225
261
|
// property calculated accordingly:
|
@@ -229,7 +265,12 @@
|
|
229
265
|
this._trigger('progressall', e, {
|
230
266
|
lengthComputable: true,
|
231
267
|
loaded: this._loaded,
|
232
|
-
total: this._total
|
268
|
+
total: this._total,
|
269
|
+
bitrate: this._bitrateTimer.getBitrate(
|
270
|
+
now,
|
271
|
+
this._loaded,
|
272
|
+
data.bitrateInterval
|
273
|
+
)
|
233
274
|
});
|
234
275
|
}
|
235
276
|
},
|
@@ -258,7 +299,8 @@
|
|
258
299
|
var formData,
|
259
300
|
file = options.files[0],
|
260
301
|
// Ignore non-multipart setting if not supported:
|
261
|
-
multipart = options.multipart || !$.support.xhrFileUpload
|
302
|
+
multipart = options.multipart || !$.support.xhrFileUpload,
|
303
|
+
paramName = options.paramName[0];
|
262
304
|
if (!multipart || options.blob) {
|
263
305
|
// For non-multipart uploads and chunked uploads,
|
264
306
|
// file meta data is not part of the request body,
|
@@ -290,13 +332,13 @@
|
|
290
332
|
formData = this._getFormData(options);
|
291
333
|
if (options.blob) {
|
292
334
|
formData.push({
|
293
|
-
name:
|
335
|
+
name: paramName,
|
294
336
|
value: options.blob
|
295
337
|
});
|
296
338
|
} else {
|
297
339
|
$.each(options.files, function (index, file) {
|
298
340
|
formData.push({
|
299
|
-
name: options.paramName,
|
341
|
+
name: options.paramName[index] || paramName,
|
300
342
|
value: file
|
301
343
|
});
|
302
344
|
});
|
@@ -311,14 +353,18 @@
|
|
311
353
|
});
|
312
354
|
}
|
313
355
|
if (options.blob) {
|
314
|
-
formData.append(
|
356
|
+
formData.append(paramName, options.blob, file.name);
|
315
357
|
} else {
|
316
358
|
$.each(options.files, function (index, file) {
|
317
359
|
// File objects are also Blob instances.
|
318
360
|
// This check allows the tests to run with
|
319
361
|
// dummy objects:
|
320
362
|
if (file instanceof Blob) {
|
321
|
-
formData.append(
|
363
|
+
formData.append(
|
364
|
+
options.paramName[index] || paramName,
|
365
|
+
file,
|
366
|
+
file.name
|
367
|
+
);
|
322
368
|
}
|
323
369
|
});
|
324
370
|
}
|
@@ -362,16 +408,36 @@
|
|
362
408
|
}
|
363
409
|
},
|
364
410
|
|
411
|
+
_getParamName: function (options) {
|
412
|
+
var fileInput = $(options.fileInput),
|
413
|
+
paramName = options.paramName;
|
414
|
+
if (!paramName) {
|
415
|
+
paramName = [];
|
416
|
+
fileInput.each(function () {
|
417
|
+
var input = $(this),
|
418
|
+
name = input.prop('name') || 'files[]',
|
419
|
+
i = (input.prop('files') || [1]).length;
|
420
|
+
while (i) {
|
421
|
+
paramName.push(name);
|
422
|
+
i -= 1;
|
423
|
+
}
|
424
|
+
});
|
425
|
+
if (!paramName.length) {
|
426
|
+
paramName = [fileInput.prop('name') || 'files[]'];
|
427
|
+
}
|
428
|
+
} else if (!$.isArray(paramName)) {
|
429
|
+
paramName = [paramName];
|
430
|
+
}
|
431
|
+
return paramName;
|
432
|
+
},
|
433
|
+
|
365
434
|
_initFormSettings: function (options) {
|
366
435
|
// Retrieve missing options from the input field and the
|
367
436
|
// associated form, if available:
|
368
437
|
if (!options.form || !options.form.length) {
|
369
438
|
options.form = $(options.fileInput.prop('form'));
|
370
439
|
}
|
371
|
-
|
372
|
-
options.paramName = options.fileInput.prop('name') ||
|
373
|
-
'files[]';
|
374
|
-
}
|
440
|
+
options.paramName = this._getParamName(options);
|
375
441
|
if (!options.url) {
|
376
442
|
options.url = options.form.prop('action') || location.href;
|
377
443
|
}
|
@@ -504,6 +570,8 @@
|
|
504
570
|
// and no other uploads are currently running,
|
505
571
|
// equivalent to the global ajaxStart event:
|
506
572
|
this._trigger('start');
|
573
|
+
// Set timer for global bitrate progress calculation:
|
574
|
+
this._bitrateTimer = new this._BitrateTimer();
|
507
575
|
}
|
508
576
|
this._active += 1;
|
509
577
|
// Initialize the global progress values:
|
@@ -556,6 +624,7 @@
|
|
556
624
|
this._trigger('stop');
|
557
625
|
// Reset the global progress values:
|
558
626
|
this._loaded = this._total = 0;
|
627
|
+
this._bitrateTimer = null;
|
559
628
|
}
|
560
629
|
},
|
561
630
|
|
@@ -567,6 +636,8 @@
|
|
567
636
|
options = that._getAJAXSettings(data),
|
568
637
|
send = function (resolve, args) {
|
569
638
|
that._sending += 1;
|
639
|
+
// Set timer for bitrate progress calculation:
|
640
|
+
options._bitrateTimer = new that._BitrateTimer();
|
570
641
|
jqXHR = jqXHR || (
|
571
642
|
(resolve !== false &&
|
572
643
|
that._trigger('send', e, options) !== false &&
|
@@ -634,21 +705,34 @@
|
|
634
705
|
result = true,
|
635
706
|
options = $.extend({}, this.options, data),
|
636
707
|
limit = options.limitMultiFileUploads,
|
708
|
+
paramName = this._getParamName(options),
|
709
|
+
paramNameSet,
|
710
|
+
paramNameSlice,
|
637
711
|
fileSet,
|
638
712
|
i;
|
639
713
|
if (!(options.singleFileUploads || limit) ||
|
640
714
|
!this._isXHRUpload(options)) {
|
641
715
|
fileSet = [data.files];
|
716
|
+
paramNameSet = [paramName];
|
642
717
|
} else if (!options.singleFileUploads && limit) {
|
643
718
|
fileSet = [];
|
719
|
+
paramNameSet = [];
|
644
720
|
for (i = 0; i < data.files.length; i += limit) {
|
645
721
|
fileSet.push(data.files.slice(i, i + limit));
|
722
|
+
paramNameSlice = paramName.slice(i, i + limit);
|
723
|
+
if (!paramNameSlice.length) {
|
724
|
+
paramNameSlice = paramName;
|
725
|
+
}
|
726
|
+
paramNameSet.push(paramNameSlice);
|
646
727
|
}
|
728
|
+
} else {
|
729
|
+
paramNameSet = paramName;
|
647
730
|
}
|
648
731
|
data.originalFiles = data.files;
|
649
732
|
$.each(fileSet || data.files, function (index, element) {
|
650
|
-
var
|
651
|
-
|
733
|
+
var newData = $.extend({}, data);
|
734
|
+
newData.files = fileSet ? element : [element];
|
735
|
+
newData.paramName = paramNameSet[index];
|
652
736
|
newData.submit = function () {
|
653
737
|
newData.jqXHR = this.jqXHR =
|
654
738
|
(that._trigger('submit', e, this) !== false) &&
|
@@ -807,10 +891,9 @@
|
|
807
891
|
},
|
808
892
|
|
809
893
|
_create: function () {
|
810
|
-
var options = this.options
|
811
|
-
|
812
|
-
|
813
|
-
$.extend(options, dataOpts);
|
894
|
+
var options = this.options;
|
895
|
+
// Initialize options set via HTML5 data-attributes:
|
896
|
+
$.extend(options, $(this.element[0].cloneNode(false)).data());
|
814
897
|
options.namespace = options.namespace || this.widgetName;
|
815
898
|
this._initSpecialOptions();
|
816
899
|
this._slots = [];
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* jQuery Iframe Transport Plugin 1.
|
2
|
+
* jQuery Iframe Transport Plugin 1.4
|
3
3
|
* https://github.com/blueimp/jQuery-File-Upload
|
4
4
|
*
|
5
5
|
* Copyright 2011, Sebastian Tschan
|
@@ -30,7 +30,8 @@
|
|
30
30
|
// The iframe transport accepts three additional options:
|
31
31
|
// options.fileInput: a jQuery collection of file input fields
|
32
32
|
// options.paramName: the parameter name for the file form data,
|
33
|
-
// overrides the name property of the file input field(s)
|
33
|
+
// overrides the name property of the file input field(s),
|
34
|
+
// can be a string or an array of strings.
|
34
35
|
// options.formData: an array of objects with name and value properties,
|
35
36
|
// equivalent to the return data of .serializeArray(), e.g.:
|
36
37
|
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
|
@@ -50,7 +51,9 @@
|
|
50
51
|
'<iframe src="javascript:false;" name="iframe-transport-' +
|
51
52
|
(counter += 1) + '"></iframe>'
|
52
53
|
).bind('load', function () {
|
53
|
-
var fileInputClones
|
54
|
+
var fileInputClones,
|
55
|
+
paramNames = $.isArray(options.paramName) ?
|
56
|
+
options.paramName : [options.paramName];
|
54
57
|
iframe
|
55
58
|
.unbind('load')
|
56
59
|
.bind('load', function () {
|
@@ -101,8 +104,11 @@
|
|
101
104
|
return fileInputClones[index];
|
102
105
|
});
|
103
106
|
if (options.paramName) {
|
104
|
-
options.fileInput.each(function () {
|
105
|
-
$(this).prop(
|
107
|
+
options.fileInput.each(function (index) {
|
108
|
+
$(this).prop(
|
109
|
+
'name',
|
110
|
+
paramNames[index] || options.paramName
|
111
|
+
);
|
106
112
|
});
|
107
113
|
}
|
108
114
|
// Appending the file input fields to the hidden form
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jquery.fileupload-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
13
|
-
dependencies:
|
12
|
+
date: 2012-06-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sprockets
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
14
30
|
description: This gem packages jQuery File Upload plugin and it's dependencies for
|
15
31
|
Rails asset pipeline.
|
16
32
|
email:
|
@@ -26,6 +42,7 @@ files:
|
|
26
42
|
- jquery.fileupload-rails.gemspec
|
27
43
|
- lib/jquery.fileupload-rails.rb
|
28
44
|
- lib/jquery.fileupload-rails/version.rb
|
45
|
+
- vendor/assets/javascripts/jquery.fileupload-fp.js
|
29
46
|
- vendor/assets/javascripts/jquery.fileupload-ip.js
|
30
47
|
- vendor/assets/javascripts/jquery.fileupload-ui.js
|
31
48
|
- vendor/assets/javascripts/jquery.fileupload.js
|
@@ -53,9 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
70
|
version: '0'
|
54
71
|
requirements: []
|
55
72
|
rubyforge_project: jquery.fileupload-rails
|
56
|
-
rubygems_version: 1.8.
|
73
|
+
rubygems_version: 1.8.23
|
57
74
|
signing_key:
|
58
75
|
specification_version: 3
|
59
76
|
summary: Use jQuery File Upload plugin with Rails 3
|
60
77
|
test_files: []
|
61
|
-
has_rdoc:
|