fine_uploader 2.1.1 → 3.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 +9 -3
- data/Vendorfile +17 -5
- data/lib/fine_uploader/version.rb +1 -1
- data/vendor/assets/images/{loading.gif → fine_uploader/loading.gif} +0 -0
- data/vendor/assets/images/fine_uploader/processing.gif +0 -0
- data/vendor/assets/javascripts/fine_uploader/button.js +102 -0
- data/vendor/assets/javascripts/fine_uploader/dnd.js +355 -0
- data/vendor/assets/javascripts/fine_uploader/handler.base.js +115 -0
- data/vendor/assets/javascripts/fine_uploader/handler.form.js +202 -0
- data/vendor/assets/javascripts/fine_uploader/handler.xhr.js +168 -0
- data/vendor/assets/javascripts/fine_uploader/header.js +10 -0
- data/vendor/assets/javascripts/fine_uploader/jquery-plugin.js +168 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.basic.js +558 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.js +451 -0
- data/vendor/assets/javascripts/fine_uploader/util.js +469 -0
- data/vendor/assets/javascripts/fine_uploader.js +10 -1634
- data/vendor/assets/stylesheets/fine_uploader.css.scss +27 -5
- metadata +14 -3
@@ -0,0 +1,469 @@
|
|
1
|
+
/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest*/
|
2
|
+
var qq = function(element) {
|
3
|
+
"use strict";
|
4
|
+
|
5
|
+
return {
|
6
|
+
hide: function() {
|
7
|
+
element.style.display = 'none';
|
8
|
+
return this;
|
9
|
+
},
|
10
|
+
|
11
|
+
/** Returns the function which detaches attached event */
|
12
|
+
attach: function(type, fn) {
|
13
|
+
if (element.addEventListener){
|
14
|
+
element.addEventListener(type, fn, false);
|
15
|
+
} else if (element.attachEvent){
|
16
|
+
element.attachEvent('on' + type, fn);
|
17
|
+
}
|
18
|
+
return function() {
|
19
|
+
qq(element).detach(type, fn);
|
20
|
+
};
|
21
|
+
},
|
22
|
+
|
23
|
+
detach: function(type, fn) {
|
24
|
+
if (element.removeEventListener){
|
25
|
+
element.removeEventListener(type, fn, false);
|
26
|
+
} else if (element.attachEvent){
|
27
|
+
element.detachEvent('on' + type, fn);
|
28
|
+
}
|
29
|
+
return this;
|
30
|
+
},
|
31
|
+
|
32
|
+
contains: function(descendant) {
|
33
|
+
// compareposition returns false in this case
|
34
|
+
if (element === descendant) {
|
35
|
+
return true;
|
36
|
+
}
|
37
|
+
|
38
|
+
if (element.contains){
|
39
|
+
return element.contains(descendant);
|
40
|
+
} else {
|
41
|
+
/*jslint bitwise: true*/
|
42
|
+
return !!(descendant.compareDocumentPosition(element) & 8);
|
43
|
+
}
|
44
|
+
},
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Insert this element before elementB.
|
48
|
+
*/
|
49
|
+
insertBefore: function(elementB) {
|
50
|
+
elementB.parentNode.insertBefore(element, elementB);
|
51
|
+
return this;
|
52
|
+
},
|
53
|
+
|
54
|
+
remove: function() {
|
55
|
+
element.parentNode.removeChild(element);
|
56
|
+
return this;
|
57
|
+
},
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Sets styles for an element.
|
61
|
+
* Fixes opacity in IE6-8.
|
62
|
+
*/
|
63
|
+
css: function(styles) {
|
64
|
+
if (styles.opacity !== null){
|
65
|
+
if (typeof element.style.opacity !== 'string' && typeof(element.filters) !== 'undefined'){
|
66
|
+
styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
|
67
|
+
}
|
68
|
+
}
|
69
|
+
qq.extend(element.style, styles);
|
70
|
+
|
71
|
+
return this;
|
72
|
+
},
|
73
|
+
|
74
|
+
hasClass: function(name) {
|
75
|
+
var re = new RegExp('(^| )' + name + '( |$)');
|
76
|
+
return re.test(element.className);
|
77
|
+
},
|
78
|
+
|
79
|
+
addClass: function(name) {
|
80
|
+
if (!qq(element).hasClass(name)){
|
81
|
+
element.className += ' ' + name;
|
82
|
+
}
|
83
|
+
return this;
|
84
|
+
},
|
85
|
+
|
86
|
+
removeClass: function(name) {
|
87
|
+
var re = new RegExp('(^| )' + name + '( |$)');
|
88
|
+
element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
|
89
|
+
return this;
|
90
|
+
},
|
91
|
+
|
92
|
+
getByClass: function(className) {
|
93
|
+
var candidates,
|
94
|
+
result = [];
|
95
|
+
|
96
|
+
if (element.querySelectorAll){
|
97
|
+
return element.querySelectorAll('.' + className);
|
98
|
+
}
|
99
|
+
|
100
|
+
candidates = element.getElementsByTagName("*");
|
101
|
+
|
102
|
+
qq.each(candidates, function(idx, val) {
|
103
|
+
if (qq(val).hasClass(className)){
|
104
|
+
result.push(val);
|
105
|
+
}
|
106
|
+
});
|
107
|
+
return result;
|
108
|
+
},
|
109
|
+
|
110
|
+
children: function() {
|
111
|
+
var children = [],
|
112
|
+
child = element.firstChild;
|
113
|
+
|
114
|
+
while (child){
|
115
|
+
if (child.nodeType === 1){
|
116
|
+
children.push(child);
|
117
|
+
}
|
118
|
+
child = child.nextSibling;
|
119
|
+
}
|
120
|
+
|
121
|
+
return children;
|
122
|
+
},
|
123
|
+
|
124
|
+
setText: function(text) {
|
125
|
+
element.innerText = text;
|
126
|
+
element.textContent = text;
|
127
|
+
return this;
|
128
|
+
},
|
129
|
+
|
130
|
+
clearText: function() {
|
131
|
+
return qq(element).setText("");
|
132
|
+
}
|
133
|
+
};
|
134
|
+
};
|
135
|
+
|
136
|
+
qq.log = function(message, level) {
|
137
|
+
"use strict";
|
138
|
+
|
139
|
+
if (window.console) {
|
140
|
+
if (!level || level === 'info') {
|
141
|
+
window.console.log(message);
|
142
|
+
}
|
143
|
+
else
|
144
|
+
{
|
145
|
+
if (window.console[level]) {
|
146
|
+
window.console[level](message);
|
147
|
+
}
|
148
|
+
else {
|
149
|
+
window.console.log('<' + level + '> ' + message);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
};
|
154
|
+
|
155
|
+
qq.isObject = function(variable) {
|
156
|
+
"use strict";
|
157
|
+
return variable !== null && variable && typeof(variable) === "object" && variable.constructor === Object;
|
158
|
+
};
|
159
|
+
|
160
|
+
qq.isFunction = function(variable) {
|
161
|
+
"use strict";
|
162
|
+
return typeof(variable) === "function";
|
163
|
+
};
|
164
|
+
|
165
|
+
qq.isFileOrInput = function(maybeFileOrInput) {
|
166
|
+
"use strict";
|
167
|
+
if (window.File && maybeFileOrInput instanceof File) {
|
168
|
+
return true;
|
169
|
+
}
|
170
|
+
else if (window.HTMLInputElement) {
|
171
|
+
if (maybeFileOrInput instanceof HTMLInputElement) {
|
172
|
+
if (maybeFileOrInput.type && maybeFileOrInput.type.toLowerCase() === 'file') {
|
173
|
+
return true;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
else if (maybeFileOrInput.tagName) {
|
178
|
+
if (maybeFileOrInput.tagName.toLowerCase() === 'input') {
|
179
|
+
if (maybeFileOrInput.type && maybeFileOrInput.type.toLowerCase() === 'file') {
|
180
|
+
return true;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
return false;
|
186
|
+
};
|
187
|
+
|
188
|
+
qq.isXhrUploadSupported = function() {
|
189
|
+
"use strict";
|
190
|
+
var input = document.createElement('input');
|
191
|
+
input.type = 'file';
|
192
|
+
|
193
|
+
return (
|
194
|
+
input.multiple !== undefined &&
|
195
|
+
typeof File !== "undefined" &&
|
196
|
+
typeof FormData !== "undefined" &&
|
197
|
+
typeof (new XMLHttpRequest()).upload !== "undefined" );
|
198
|
+
};
|
199
|
+
|
200
|
+
qq.isFolderDropSupported = function(dataTransfer) {
|
201
|
+
"use strict";
|
202
|
+
return (dataTransfer.items && dataTransfer.items[0].webkitGetAsEntry);
|
203
|
+
};
|
204
|
+
|
205
|
+
qq.extend = function (first, second, extendNested) {
|
206
|
+
"use strict";
|
207
|
+
qq.each(second, function(prop, val) {
|
208
|
+
if (extendNested && qq.isObject(val)) {
|
209
|
+
if (first[prop] === undefined) {
|
210
|
+
first[prop] = {};
|
211
|
+
}
|
212
|
+
qq.extend(first[prop], val, true);
|
213
|
+
}
|
214
|
+
else {
|
215
|
+
first[prop] = val;
|
216
|
+
}
|
217
|
+
});
|
218
|
+
};
|
219
|
+
|
220
|
+
/**
|
221
|
+
* Searches for a given element in the array, returns -1 if it is not present.
|
222
|
+
* @param {Number} [from] The index at which to begin the search
|
223
|
+
*/
|
224
|
+
qq.indexOf = function(arr, elt, from){
|
225
|
+
"use strict";
|
226
|
+
|
227
|
+
if (arr.indexOf) {
|
228
|
+
return arr.indexOf(elt, from);
|
229
|
+
}
|
230
|
+
|
231
|
+
from = from || 0;
|
232
|
+
var len = arr.length;
|
233
|
+
|
234
|
+
if (from < 0) {
|
235
|
+
from += len;
|
236
|
+
}
|
237
|
+
|
238
|
+
for (null; from < len; from+=1){
|
239
|
+
if (arr.hasOwnProperty(from) && arr[from] === elt){
|
240
|
+
return from;
|
241
|
+
}
|
242
|
+
}
|
243
|
+
return -1;
|
244
|
+
};
|
245
|
+
|
246
|
+
qq.getUniqueId = (function(){
|
247
|
+
"use strict";
|
248
|
+
|
249
|
+
var id = -1;
|
250
|
+
return function(){
|
251
|
+
id += 1;
|
252
|
+
return id;
|
253
|
+
};
|
254
|
+
}());
|
255
|
+
|
256
|
+
//
|
257
|
+
// Browsers and platforms detection
|
258
|
+
|
259
|
+
qq.ie = function(){
|
260
|
+
"use strict";
|
261
|
+
return navigator.userAgent.indexOf('MSIE') !== -1;
|
262
|
+
};
|
263
|
+
qq.ie10 = function(){
|
264
|
+
"use strict";
|
265
|
+
return navigator.userAgent.indexOf('MSIE 10') !== -1;
|
266
|
+
};
|
267
|
+
qq.safari = function(){
|
268
|
+
"use strict";
|
269
|
+
return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1;
|
270
|
+
};
|
271
|
+
qq.chrome = function(){
|
272
|
+
"use strict";
|
273
|
+
return navigator.vendor !== undefined && navigator.vendor.indexOf('Google') !== -1;
|
274
|
+
};
|
275
|
+
qq.firefox = function(){
|
276
|
+
"use strict";
|
277
|
+
return (navigator.userAgent.indexOf('Mozilla') !== -1 && navigator.vendor !== undefined && navigator.vendor === '');
|
278
|
+
};
|
279
|
+
qq.windows = function(){
|
280
|
+
"use strict";
|
281
|
+
return navigator.platform === "Win32";
|
282
|
+
};
|
283
|
+
|
284
|
+
//
|
285
|
+
// Events
|
286
|
+
|
287
|
+
qq.preventDefault = function(e){
|
288
|
+
"use strict";
|
289
|
+
if (e.preventDefault){
|
290
|
+
e.preventDefault();
|
291
|
+
} else{
|
292
|
+
e.returnValue = false;
|
293
|
+
}
|
294
|
+
};
|
295
|
+
|
296
|
+
/**
|
297
|
+
* Creates and returns element from html string
|
298
|
+
* Uses innerHTML to create an element
|
299
|
+
*/
|
300
|
+
qq.toElement = (function(){
|
301
|
+
"use strict";
|
302
|
+
var div = document.createElement('div');
|
303
|
+
return function(html){
|
304
|
+
div.innerHTML = html;
|
305
|
+
var element = div.firstChild;
|
306
|
+
div.removeChild(element);
|
307
|
+
return element;
|
308
|
+
};
|
309
|
+
}());
|
310
|
+
|
311
|
+
//key and value are passed to callback for each item in the object or array
|
312
|
+
qq.each = function(obj, callback) {
|
313
|
+
"use strict";
|
314
|
+
var key, retVal;
|
315
|
+
if (obj) {
|
316
|
+
for (key in obj) {
|
317
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
318
|
+
retVal = callback(key, obj[key]);
|
319
|
+
if (retVal === false) {
|
320
|
+
break;
|
321
|
+
}
|
322
|
+
}
|
323
|
+
}
|
324
|
+
}
|
325
|
+
};
|
326
|
+
|
327
|
+
/**
|
328
|
+
* obj2url() takes a json-object as argument and generates
|
329
|
+
* a querystring. pretty much like jQuery.param()
|
330
|
+
*
|
331
|
+
* how to use:
|
332
|
+
*
|
333
|
+
* `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
|
334
|
+
*
|
335
|
+
* will result in:
|
336
|
+
*
|
337
|
+
* `http://any.url/upload?otherParam=value&a=b&c=d`
|
338
|
+
*
|
339
|
+
* @param Object JSON-Object
|
340
|
+
* @param String current querystring-part
|
341
|
+
* @return String encoded querystring
|
342
|
+
*/
|
343
|
+
qq.obj2url = function(obj, temp, prefixDone){
|
344
|
+
"use strict";
|
345
|
+
var i, len,
|
346
|
+
uristrings = [],
|
347
|
+
prefix = '&',
|
348
|
+
add = function(nextObj, i){
|
349
|
+
var nextTemp = temp
|
350
|
+
? (/\[\]$/.test(temp)) // prevent double-encoding
|
351
|
+
? temp
|
352
|
+
: temp+'['+i+']'
|
353
|
+
: i;
|
354
|
+
if ((nextTemp !== 'undefined') && (i !== 'undefined')) {
|
355
|
+
uristrings.push(
|
356
|
+
(typeof nextObj === 'object')
|
357
|
+
? qq.obj2url(nextObj, nextTemp, true)
|
358
|
+
: (Object.prototype.toString.call(nextObj) === '[object Function]')
|
359
|
+
? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
|
360
|
+
: encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)
|
361
|
+
);
|
362
|
+
}
|
363
|
+
};
|
364
|
+
|
365
|
+
if (!prefixDone && temp) {
|
366
|
+
prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
|
367
|
+
uristrings.push(temp);
|
368
|
+
uristrings.push(qq.obj2url(obj));
|
369
|
+
} else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj !== 'undefined') ) {
|
370
|
+
// we wont use a for-in-loop on an array (performance)
|
371
|
+
for (i = -1, len = obj.length; i < len; i+=1){
|
372
|
+
add(obj[i], i);
|
373
|
+
}
|
374
|
+
} else if ((typeof obj !== 'undefined') && (obj !== null) && (typeof obj === "object")){
|
375
|
+
// for anything else but a scalar, we will use for-in-loop
|
376
|
+
for (i in obj){
|
377
|
+
if (obj.hasOwnProperty(i)) {
|
378
|
+
add(obj[i], i);
|
379
|
+
}
|
380
|
+
}
|
381
|
+
} else {
|
382
|
+
uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
|
383
|
+
}
|
384
|
+
|
385
|
+
if (temp) {
|
386
|
+
return uristrings.join(prefix);
|
387
|
+
} else {
|
388
|
+
return uristrings.join(prefix)
|
389
|
+
.replace(/^&/, '')
|
390
|
+
.replace(/%20/g, '+');
|
391
|
+
}
|
392
|
+
};
|
393
|
+
|
394
|
+
qq.obj2FormData = function(obj, formData, arrayKeyName) {
|
395
|
+
"use strict";
|
396
|
+
if (!formData) {
|
397
|
+
formData = new FormData();
|
398
|
+
}
|
399
|
+
|
400
|
+
qq.each(obj, function(key, val) {
|
401
|
+
key = arrayKeyName ? arrayKeyName + '[' + key + ']' : key;
|
402
|
+
|
403
|
+
if (qq.isObject(val)) {
|
404
|
+
qq.obj2FormData(val, formData, key);
|
405
|
+
}
|
406
|
+
else if (qq.isFunction(val)) {
|
407
|
+
formData.append(encodeURIComponent(key), encodeURIComponent(val()));
|
408
|
+
}
|
409
|
+
else {
|
410
|
+
formData.append(encodeURIComponent(key), encodeURIComponent(val));
|
411
|
+
}
|
412
|
+
});
|
413
|
+
|
414
|
+
return formData;
|
415
|
+
};
|
416
|
+
|
417
|
+
qq.obj2Inputs = function(obj, form) {
|
418
|
+
"use strict";
|
419
|
+
var input;
|
420
|
+
|
421
|
+
if (!form) {
|
422
|
+
form = document.createElement('form');
|
423
|
+
}
|
424
|
+
|
425
|
+
qq.obj2FormData(obj, {
|
426
|
+
append: function(key, val) {
|
427
|
+
input = document.createElement('input');
|
428
|
+
input.setAttribute('name', key);
|
429
|
+
input.setAttribute('value', val);
|
430
|
+
form.appendChild(input);
|
431
|
+
}
|
432
|
+
});
|
433
|
+
|
434
|
+
return form;
|
435
|
+
};
|
436
|
+
|
437
|
+
/**
|
438
|
+
* A generic module which supports object disposing in dispose() method.
|
439
|
+
* */
|
440
|
+
qq.DisposeSupport = function() {
|
441
|
+
"use strict";
|
442
|
+
var disposers = [];
|
443
|
+
|
444
|
+
return {
|
445
|
+
/** Run all registered disposers */
|
446
|
+
dispose: function() {
|
447
|
+
var disposer;
|
448
|
+
do {
|
449
|
+
disposer = disposers.shift();
|
450
|
+
if (disposer) {
|
451
|
+
disposer();
|
452
|
+
}
|
453
|
+
}
|
454
|
+
while (disposer);
|
455
|
+
},
|
456
|
+
|
457
|
+
/** Attach event handler and register de-attacher as a disposer */
|
458
|
+
attach: function() {
|
459
|
+
var args = arguments;
|
460
|
+
/*jslint undef:true*/
|
461
|
+
this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));
|
462
|
+
},
|
463
|
+
|
464
|
+
/** Add disposer to the collection */
|
465
|
+
addDisposer: function(disposeFunction) {
|
466
|
+
disposers.push(disposeFunction);
|
467
|
+
}
|
468
|
+
};
|
469
|
+
};
|