fileuploader-rails 3.0.0.1 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/fileuploader-rails/version.rb +1 -1
- data/vendor/assets/images/loading.gif +0 -0
- data/vendor/assets/images/processing.gif +0 -0
- data/vendor/assets/javascripts/fineuploader.jquery.js +872 -398
- data/vendor/assets/javascripts/fineuploader.js +792 -338
- data/vendor/assets/stylesheets/fineuploader.css +10 -1
- metadata +7 -6
@@ -8,8 +8,7 @@
|
|
8
8
|
*
|
9
9
|
* Licensed under MIT license, GNU GPL 2 or later, GNU LGPL 2 or later, see license.txt.
|
10
10
|
*/
|
11
|
-
|
12
|
-
var qq = qq || {};
|
11
|
+
/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest*/
|
13
12
|
var qq = function(element) {
|
14
13
|
"use strict";
|
15
14
|
|
@@ -42,13 +41,14 @@ var qq = function(element) {
|
|
42
41
|
|
43
42
|
contains: function(descendant) {
|
44
43
|
// compareposition returns false in this case
|
45
|
-
if (element
|
44
|
+
if (element === descendant) {
|
46
45
|
return true;
|
47
46
|
}
|
48
47
|
|
49
48
|
if (element.contains){
|
50
49
|
return element.contains(descendant);
|
51
50
|
} else {
|
51
|
+
/*jslint bitwise: true*/
|
52
52
|
return !!(descendant.compareDocumentPosition(element) & 8);
|
53
53
|
}
|
54
54
|
},
|
@@ -71,8 +71,8 @@ var qq = function(element) {
|
|
71
71
|
* Fixes opacity in IE6-8.
|
72
72
|
*/
|
73
73
|
css: function(styles) {
|
74
|
-
if (styles.opacity
|
75
|
-
if (typeof element.style.opacity
|
74
|
+
if (styles.opacity !== null){
|
75
|
+
if (typeof element.style.opacity !== 'string' && typeof(element.filters) !== 'undefined'){
|
76
76
|
styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
|
77
77
|
}
|
78
78
|
}
|
@@ -100,19 +100,20 @@ var qq = function(element) {
|
|
100
100
|
},
|
101
101
|
|
102
102
|
getByClass: function(className) {
|
103
|
+
var candidates,
|
104
|
+
result = [];
|
105
|
+
|
103
106
|
if (element.querySelectorAll){
|
104
107
|
return element.querySelectorAll('.' + className);
|
105
108
|
}
|
106
109
|
|
107
|
-
|
108
|
-
var candidates = element.getElementsByTagName("*");
|
109
|
-
var len = candidates.length;
|
110
|
+
candidates = element.getElementsByTagName("*");
|
110
111
|
|
111
|
-
|
112
|
-
if (qq(
|
113
|
-
result.push(
|
112
|
+
qq.each(candidates, function(idx, val) {
|
113
|
+
if (qq(val).hasClass(className)){
|
114
|
+
result.push(val);
|
114
115
|
}
|
115
|
-
}
|
116
|
+
});
|
116
117
|
return result;
|
117
118
|
},
|
118
119
|
|
@@ -121,7 +122,7 @@ var qq = function(element) {
|
|
121
122
|
child = element.firstChild;
|
122
123
|
|
123
124
|
while (child){
|
124
|
-
if (child.nodeType
|
125
|
+
if (child.nodeType === 1){
|
125
126
|
children.push(child);
|
126
127
|
}
|
127
128
|
child = child.nextSibling;
|
@@ -143,6 +144,8 @@ var qq = function(element) {
|
|
143
144
|
};
|
144
145
|
|
145
146
|
qq.log = function(message, level) {
|
147
|
+
"use strict";
|
148
|
+
|
146
149
|
if (window.console) {
|
147
150
|
if (!level || level === 'info') {
|
148
151
|
window.console.log(message);
|
@@ -164,22 +167,64 @@ qq.isObject = function(variable) {
|
|
164
167
|
return variable !== null && variable && typeof(variable) === "object" && variable.constructor === Object;
|
165
168
|
};
|
166
169
|
|
167
|
-
qq.
|
170
|
+
qq.isFunction = function(variable) {
|
168
171
|
"use strict";
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
172
|
+
return typeof(variable) === "function";
|
173
|
+
};
|
174
|
+
|
175
|
+
qq.isFileOrInput = function(maybeFileOrInput) {
|
176
|
+
"use strict";
|
177
|
+
if (window.File && maybeFileOrInput instanceof File) {
|
178
|
+
return true;
|
179
|
+
}
|
180
|
+
else if (window.HTMLInputElement) {
|
181
|
+
if (maybeFileOrInput instanceof HTMLInputElement) {
|
182
|
+
if (maybeFileOrInput.type && maybeFileOrInput.type.toLowerCase() === 'file') {
|
183
|
+
return true;
|
177
184
|
}
|
178
|
-
|
179
|
-
|
185
|
+
}
|
186
|
+
}
|
187
|
+
else if (maybeFileOrInput.tagName) {
|
188
|
+
if (maybeFileOrInput.tagName.toLowerCase() === 'input') {
|
189
|
+
if (maybeFileOrInput.type && maybeFileOrInput.type.toLowerCase() === 'file') {
|
190
|
+
return true;
|
180
191
|
}
|
181
192
|
}
|
182
193
|
}
|
194
|
+
|
195
|
+
return false;
|
196
|
+
};
|
197
|
+
|
198
|
+
qq.isXhrUploadSupported = function() {
|
199
|
+
"use strict";
|
200
|
+
var input = document.createElement('input');
|
201
|
+
input.type = 'file';
|
202
|
+
|
203
|
+
return (
|
204
|
+
input.multiple !== undefined &&
|
205
|
+
typeof File !== "undefined" &&
|
206
|
+
typeof FormData !== "undefined" &&
|
207
|
+
typeof (new XMLHttpRequest()).upload !== "undefined" );
|
208
|
+
};
|
209
|
+
|
210
|
+
qq.isFolderDropSupported = function(dataTransfer) {
|
211
|
+
"use strict";
|
212
|
+
return (dataTransfer.items && dataTransfer.items[0].webkitGetAsEntry);
|
213
|
+
};
|
214
|
+
|
215
|
+
qq.extend = function (first, second, extendNested) {
|
216
|
+
"use strict";
|
217
|
+
qq.each(second, function(prop, val) {
|
218
|
+
if (extendNested && qq.isObject(val)) {
|
219
|
+
if (first[prop] === undefined) {
|
220
|
+
first[prop] = {};
|
221
|
+
}
|
222
|
+
qq.extend(first[prop], val, true);
|
223
|
+
}
|
224
|
+
else {
|
225
|
+
first[prop] = val;
|
226
|
+
}
|
227
|
+
});
|
183
228
|
};
|
184
229
|
|
185
230
|
/**
|
@@ -187,15 +232,21 @@ qq.extend = function (first, second, extendNested) {
|
|
187
232
|
* @param {Number} [from] The index at which to begin the search
|
188
233
|
*/
|
189
234
|
qq.indexOf = function(arr, elt, from){
|
190
|
-
|
235
|
+
"use strict";
|
236
|
+
|
237
|
+
if (arr.indexOf) {
|
238
|
+
return arr.indexOf(elt, from);
|
239
|
+
}
|
191
240
|
|
192
241
|
from = from || 0;
|
193
242
|
var len = arr.length;
|
194
243
|
|
195
|
-
if (from < 0)
|
244
|
+
if (from < 0) {
|
245
|
+
from += len;
|
246
|
+
}
|
196
247
|
|
197
|
-
for (; from < len; from
|
198
|
-
if (from
|
248
|
+
for (null; from < len; from+=1){
|
249
|
+
if (arr.hasOwnProperty(from) && arr[from] === elt){
|
199
250
|
return from;
|
200
251
|
}
|
201
252
|
}
|
@@ -203,24 +254,48 @@ qq.indexOf = function(arr, elt, from){
|
|
203
254
|
};
|
204
255
|
|
205
256
|
qq.getUniqueId = (function(){
|
206
|
-
|
207
|
-
|
208
|
-
|
257
|
+
"use strict";
|
258
|
+
|
259
|
+
var id = -1;
|
260
|
+
return function(){
|
261
|
+
id += 1;
|
262
|
+
return id;
|
263
|
+
};
|
264
|
+
}());
|
209
265
|
|
210
266
|
//
|
211
267
|
// Browsers and platforms detection
|
212
268
|
|
213
|
-
qq.ie = function(){
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
qq.
|
218
|
-
|
269
|
+
qq.ie = function(){
|
270
|
+
"use strict";
|
271
|
+
return navigator.userAgent.indexOf('MSIE') !== -1;
|
272
|
+
};
|
273
|
+
qq.ie10 = function(){
|
274
|
+
"use strict";
|
275
|
+
return navigator.userAgent.indexOf('MSIE 10') !== -1;
|
276
|
+
};
|
277
|
+
qq.safari = function(){
|
278
|
+
"use strict";
|
279
|
+
return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1;
|
280
|
+
};
|
281
|
+
qq.chrome = function(){
|
282
|
+
"use strict";
|
283
|
+
return navigator.vendor !== undefined && navigator.vendor.indexOf('Google') !== -1;
|
284
|
+
};
|
285
|
+
qq.firefox = function(){
|
286
|
+
"use strict";
|
287
|
+
return (navigator.userAgent.indexOf('Mozilla') !== -1 && navigator.vendor !== undefined && navigator.vendor === '');
|
288
|
+
};
|
289
|
+
qq.windows = function(){
|
290
|
+
"use strict";
|
291
|
+
return navigator.platform === "Win32";
|
292
|
+
};
|
219
293
|
|
220
294
|
//
|
221
295
|
// Events
|
222
296
|
|
223
297
|
qq.preventDefault = function(e){
|
298
|
+
"use strict";
|
224
299
|
if (e.preventDefault){
|
225
300
|
e.preventDefault();
|
226
301
|
} else{
|
@@ -233,6 +308,7 @@ qq.preventDefault = function(e){
|
|
233
308
|
* Uses innerHTML to create an element
|
234
309
|
*/
|
235
310
|
qq.toElement = (function(){
|
311
|
+
"use strict";
|
236
312
|
var div = document.createElement('div');
|
237
313
|
return function(html){
|
238
314
|
div.innerHTML = html;
|
@@ -240,7 +316,23 @@ qq.toElement = (function(){
|
|
240
316
|
div.removeChild(element);
|
241
317
|
return element;
|
242
318
|
};
|
243
|
-
}
|
319
|
+
}());
|
320
|
+
|
321
|
+
//key and value are passed to callback for each item in the object or array
|
322
|
+
qq.each = function(obj, callback) {
|
323
|
+
"use strict";
|
324
|
+
var key, retVal;
|
325
|
+
if (obj) {
|
326
|
+
for (key in obj) {
|
327
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
328
|
+
retVal = callback(key, obj[key]);
|
329
|
+
if (retVal === false) {
|
330
|
+
break;
|
331
|
+
}
|
332
|
+
}
|
333
|
+
}
|
334
|
+
}
|
335
|
+
};
|
244
336
|
|
245
337
|
/**
|
246
338
|
* obj2url() takes a json-object as argument and generates
|
@@ -259,15 +351,17 @@ qq.toElement = (function(){
|
|
259
351
|
* @return String encoded querystring
|
260
352
|
*/
|
261
353
|
qq.obj2url = function(obj, temp, prefixDone){
|
262
|
-
|
263
|
-
|
264
|
-
|
354
|
+
"use strict";
|
355
|
+
var i, len,
|
356
|
+
uristrings = [],
|
357
|
+
prefix = '&',
|
358
|
+
add = function(nextObj, i){
|
265
359
|
var nextTemp = temp
|
266
360
|
? (/\[\]$/.test(temp)) // prevent double-encoding
|
267
361
|
? temp
|
268
362
|
: temp+'['+i+']'
|
269
363
|
: i;
|
270
|
-
if ((nextTemp
|
364
|
+
if ((nextTemp !== 'undefined') && (i !== 'undefined')) {
|
271
365
|
uristrings.push(
|
272
366
|
(typeof nextObj === 'object')
|
273
367
|
? qq.obj2url(nextObj, nextTemp, true)
|
@@ -282,15 +376,17 @@ qq.obj2url = function(obj, temp, prefixDone){
|
|
282
376
|
prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
|
283
377
|
uristrings.push(temp);
|
284
378
|
uristrings.push(qq.obj2url(obj));
|
285
|
-
} else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj
|
379
|
+
} else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj !== 'undefined') ) {
|
286
380
|
// we wont use a for-in-loop on an array (performance)
|
287
|
-
for (
|
381
|
+
for (i = -1, len = obj.length; i < len; i+=1){
|
288
382
|
add(obj[i], i);
|
289
383
|
}
|
290
|
-
} else if ((typeof obj
|
384
|
+
} else if ((typeof obj !== 'undefined') && (obj !== null) && (typeof obj === "object")){
|
291
385
|
// for anything else but a scalar, we will use for-in-loop
|
292
|
-
for (
|
293
|
-
|
386
|
+
for (i in obj){
|
387
|
+
if (obj.hasOwnProperty(i)) {
|
388
|
+
add(obj[i], i);
|
389
|
+
}
|
294
390
|
}
|
295
391
|
} else {
|
296
392
|
uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
|
@@ -305,29 +401,81 @@ qq.obj2url = function(obj, temp, prefixDone){
|
|
305
401
|
}
|
306
402
|
};
|
307
403
|
|
404
|
+
qq.obj2FormData = function(obj, formData, arrayKeyName) {
|
405
|
+
"use strict";
|
406
|
+
if (!formData) {
|
407
|
+
formData = new FormData();
|
408
|
+
}
|
409
|
+
|
410
|
+
qq.each(obj, function(key, val) {
|
411
|
+
key = arrayKeyName ? arrayKeyName + '[' + key + ']' : key;
|
412
|
+
|
413
|
+
if (qq.isObject(val)) {
|
414
|
+
qq.obj2FormData(val, formData, key);
|
415
|
+
}
|
416
|
+
else if (qq.isFunction(val)) {
|
417
|
+
formData.append(encodeURIComponent(key), encodeURIComponent(val()));
|
418
|
+
}
|
419
|
+
else {
|
420
|
+
formData.append(encodeURIComponent(key), encodeURIComponent(val));
|
421
|
+
}
|
422
|
+
});
|
423
|
+
|
424
|
+
return formData;
|
425
|
+
};
|
426
|
+
|
427
|
+
qq.obj2Inputs = function(obj, form) {
|
428
|
+
"use strict";
|
429
|
+
var input;
|
430
|
+
|
431
|
+
if (!form) {
|
432
|
+
form = document.createElement('form');
|
433
|
+
}
|
434
|
+
|
435
|
+
qq.obj2FormData(obj, {
|
436
|
+
append: function(key, val) {
|
437
|
+
input = document.createElement('input');
|
438
|
+
input.setAttribute('name', key);
|
439
|
+
input.setAttribute('value', val);
|
440
|
+
form.appendChild(input);
|
441
|
+
}
|
442
|
+
});
|
443
|
+
|
444
|
+
return form;
|
445
|
+
};
|
446
|
+
|
308
447
|
/**
|
309
448
|
* A generic module which supports object disposing in dispose() method.
|
310
449
|
* */
|
311
|
-
qq.DisposeSupport = {
|
312
|
-
|
450
|
+
qq.DisposeSupport = function() {
|
451
|
+
"use strict";
|
452
|
+
var disposers = [];
|
313
453
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
454
|
+
return {
|
455
|
+
/** Run all registered disposers */
|
456
|
+
dispose: function() {
|
457
|
+
var disposer;
|
458
|
+
do {
|
459
|
+
disposer = disposers.shift();
|
460
|
+
if (disposer) {
|
461
|
+
disposer();
|
462
|
+
}
|
463
|
+
}
|
464
|
+
while (disposer);
|
465
|
+
},
|
321
466
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
467
|
+
/** Attach event handler and register de-attacher as a disposer */
|
468
|
+
attach: function() {
|
469
|
+
var args = arguments;
|
470
|
+
/*jslint undef:true*/
|
471
|
+
this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));
|
472
|
+
},
|
326
473
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
474
|
+
/** Add disposer to the collection */
|
475
|
+
addDisposer: function(disposeFunction) {
|
476
|
+
disposers.push(disposeFunction);
|
477
|
+
}
|
478
|
+
};
|
331
479
|
};
|
332
480
|
qq.UploadButton = function(o){
|
333
481
|
this._options = {
|
@@ -343,7 +491,7 @@ qq.UploadButton = function(o){
|
|
343
491
|
};
|
344
492
|
|
345
493
|
qq.extend(this._options, o);
|
346
|
-
|
494
|
+
this._disposeSupport = new qq.DisposeSupport();
|
347
495
|
|
348
496
|
this._element = this._options.element;
|
349
497
|
|
@@ -404,20 +552,20 @@ qq.UploadButton.prototype = {
|
|
404
552
|
this._element.appendChild(input);
|
405
553
|
|
406
554
|
var self = this;
|
407
|
-
this.
|
555
|
+
this._disposeSupport.attach(input, 'change', function(){
|
408
556
|
self._options.onChange(input);
|
409
557
|
});
|
410
558
|
|
411
|
-
this.
|
559
|
+
this._disposeSupport.attach(input, 'mouseover', function(){
|
412
560
|
qq(self._element).addClass(self._options.hoverClass);
|
413
561
|
});
|
414
|
-
this.
|
562
|
+
this._disposeSupport.attach(input, 'mouseout', function(){
|
415
563
|
qq(self._element).removeClass(self._options.hoverClass);
|
416
564
|
});
|
417
|
-
this.
|
565
|
+
this._disposeSupport.attach(input, 'focus', function(){
|
418
566
|
qq(self._element).addClass(self._options.focusClass);
|
419
567
|
});
|
420
|
-
this.
|
568
|
+
this._disposeSupport.attach(input, 'blur', function(){
|
421
569
|
qq(self._element).removeClass(self._options.focusClass);
|
422
570
|
});
|
423
571
|
|
@@ -443,6 +591,7 @@ qq.FineUploaderBasic = function(o){
|
|
443
591
|
request: {
|
444
592
|
endpoint: '/server/upload',
|
445
593
|
params: {},
|
594
|
+
paramsInBody: false,
|
446
595
|
customHeaders: {},
|
447
596
|
forceMultipart: false,
|
448
597
|
inputName: 'qqfile'
|
@@ -477,12 +626,16 @@ qq.FineUploaderBasic = function(o){
|
|
477
626
|
maxAutoAttempts: 3,
|
478
627
|
autoAttemptDelay: 5,
|
479
628
|
preventRetryResponseProperty: 'preventRetry'
|
629
|
+
},
|
630
|
+
classes: {
|
631
|
+
buttonHover: 'qq-upload-button-hover',
|
632
|
+
buttonFocus: 'qq-upload-button-focus'
|
480
633
|
}
|
481
634
|
};
|
482
635
|
|
483
636
|
qq.extend(this._options, o, true);
|
484
637
|
this._wrapCallbacks();
|
485
|
-
|
638
|
+
this._disposeSupport = new qq.DisposeSupport();
|
486
639
|
|
487
640
|
// number of files being uploaded
|
488
641
|
this._filesInProgress = 0;
|
@@ -493,6 +646,8 @@ qq.FineUploaderBasic = function(o){
|
|
493
646
|
this._retryTimeouts = [];
|
494
647
|
this._preventRetries = [];
|
495
648
|
|
649
|
+
this._paramsStore = this._createParamsStore();
|
650
|
+
|
496
651
|
this._handler = this._createUploadHandler();
|
497
652
|
|
498
653
|
if (this._options.button){
|
@@ -512,8 +667,13 @@ qq.FineUploaderBasic.prototype = {
|
|
512
667
|
|
513
668
|
}
|
514
669
|
},
|
515
|
-
setParams: function(params){
|
516
|
-
|
670
|
+
setParams: function(params, fileId){
|
671
|
+
if (fileId === undefined) {
|
672
|
+
this._options.request.params = params;
|
673
|
+
}
|
674
|
+
else {
|
675
|
+
this._paramsStore.setParams(params, fileId);
|
676
|
+
}
|
517
677
|
},
|
518
678
|
getInProgress: function(){
|
519
679
|
return this._filesInProgress;
|
@@ -522,7 +682,7 @@ qq.FineUploaderBasic.prototype = {
|
|
522
682
|
"use strict";
|
523
683
|
while(this._storedFileIds.length) {
|
524
684
|
this._filesInProgress++;
|
525
|
-
this._handler.upload(this._storedFileIds.shift()
|
685
|
+
this._handler.upload(this._storedFileIds.shift());
|
526
686
|
}
|
527
687
|
},
|
528
688
|
clearStoredFiles: function(){
|
@@ -549,27 +709,55 @@ qq.FineUploaderBasic.prototype = {
|
|
549
709
|
this._retryTimeouts = [];
|
550
710
|
this._preventRetries = [];
|
551
711
|
this._button.reset();
|
712
|
+
this._paramsStore.reset();
|
713
|
+
},
|
714
|
+
addFiles: function(filesOrInputs) {
|
715
|
+
var self = this,
|
716
|
+
verifiedFilesOrInputs = [],
|
717
|
+
index, fileOrInput;
|
718
|
+
|
719
|
+
if (filesOrInputs) {
|
720
|
+
if (!window.FileList || !(filesOrInputs instanceof FileList)) {
|
721
|
+
filesOrInputs = [].concat(filesOrInputs);
|
722
|
+
}
|
723
|
+
|
724
|
+
for (index = 0; index < filesOrInputs.length; index+=1) {
|
725
|
+
fileOrInput = filesOrInputs[index];
|
726
|
+
|
727
|
+
if (qq.isFileOrInput(fileOrInput)) {
|
728
|
+
verifiedFilesOrInputs.push(fileOrInput);
|
729
|
+
}
|
730
|
+
else {
|
731
|
+
self.log(fileOrInput + ' is not a File or INPUT element! Ignoring!', 'warn');
|
732
|
+
}
|
733
|
+
}
|
734
|
+
|
735
|
+
this.log('Processing ' + verifiedFilesOrInputs.length + ' files or inputs...');
|
736
|
+
this._uploadFileList(verifiedFilesOrInputs);
|
737
|
+
}
|
552
738
|
},
|
553
739
|
_createUploadButton: function(element){
|
554
740
|
var self = this;
|
555
741
|
|
556
742
|
var button = new qq.UploadButton({
|
557
743
|
element: element,
|
558
|
-
multiple: this._options.multiple && qq.
|
744
|
+
multiple: this._options.multiple && qq.isXhrUploadSupported(),
|
559
745
|
acceptFiles: this._options.validation.acceptFiles,
|
560
746
|
onChange: function(input){
|
561
747
|
self._onInputChange(input);
|
562
|
-
}
|
748
|
+
},
|
749
|
+
hoverClass: this._options.classes.buttonHover,
|
750
|
+
focusClass: this._options.classes.buttonFocus
|
563
751
|
});
|
564
752
|
|
565
|
-
this.addDisposer(function() { button.dispose(); });
|
753
|
+
this._disposeSupport.addDisposer(function() { button.dispose(); });
|
566
754
|
return button;
|
567
755
|
},
|
568
756
|
_createUploadHandler: function(){
|
569
757
|
var self = this,
|
570
758
|
handlerClass;
|
571
759
|
|
572
|
-
if(qq.
|
760
|
+
if(qq.isXhrUploadSupported()){
|
573
761
|
handlerClass = 'UploadHandlerXhr';
|
574
762
|
} else {
|
575
763
|
handlerClass = 'UploadHandlerForm';
|
@@ -584,6 +772,8 @@ qq.FineUploaderBasic.prototype = {
|
|
584
772
|
inputName: this._options.request.inputName,
|
585
773
|
demoMode: this._options.demoMode,
|
586
774
|
log: this.log,
|
775
|
+
paramsInBody: this._options.request.paramsInBody,
|
776
|
+
paramsStore: this._paramsStore,
|
587
777
|
onProgress: function(id, fileName, loaded, total){
|
588
778
|
self._onProgress(id, fileName, loaded, total);
|
589
779
|
self._options.callbacks.onProgress(id, fileName, loaded, total);
|
@@ -625,7 +815,7 @@ qq.FineUploaderBasic.prototype = {
|
|
625
815
|
_preventLeaveInProgress: function(){
|
626
816
|
var self = this;
|
627
817
|
|
628
|
-
this.
|
818
|
+
this._disposeSupport.attach(window, 'beforeunload', function(e){
|
629
819
|
if (!self._filesInProgress){return;}
|
630
820
|
|
631
821
|
var e = e || window.event;
|
@@ -661,10 +851,10 @@ qq.FineUploaderBasic.prototype = {
|
|
661
851
|
},
|
662
852
|
_onInputChange: function(input){
|
663
853
|
if (this._handler instanceof qq.UploadHandlerXhr){
|
664
|
-
this.
|
854
|
+
this.addFiles(input.files);
|
665
855
|
} else {
|
666
856
|
if (this._validateFile(input)){
|
667
|
-
this.
|
857
|
+
this.addFiles(input);
|
668
858
|
}
|
669
859
|
}
|
670
860
|
this._button.reset();
|
@@ -726,9 +916,7 @@ qq.FineUploaderBasic.prototype = {
|
|
726
916
|
var validationDescriptors, index, batchInvalid;
|
727
917
|
|
728
918
|
validationDescriptors = this._getValidationDescriptors(files);
|
729
|
-
|
730
|
-
batchInvalid = this._options.callbacks.onValidate(validationDescriptors) === false;
|
731
|
-
}
|
919
|
+
batchInvalid = this._options.callbacks.onValidate(validationDescriptors) === false;
|
732
920
|
|
733
921
|
if (!batchInvalid) {
|
734
922
|
if (files.length > 0) {
|
@@ -754,7 +942,7 @@ qq.FineUploaderBasic.prototype = {
|
|
754
942
|
if (this._options.callbacks.onSubmit(id, fileName) !== false){
|
755
943
|
this._onSubmit(id, fileName);
|
756
944
|
if (this._options.autoUpload) {
|
757
|
-
this._handler.upload(id
|
945
|
+
this._handler.upload(id);
|
758
946
|
}
|
759
947
|
else {
|
760
948
|
this._storeFileForLater(id);
|
@@ -857,9 +1045,11 @@ qq.FineUploaderBasic.prototype = {
|
|
857
1045
|
|
858
1046
|
for (var prop in this._options.callbacks) {
|
859
1047
|
(function() {
|
860
|
-
var
|
861
|
-
|
862
|
-
|
1048
|
+
var callbackName, callbackFunc;
|
1049
|
+
callbackName = prop;
|
1050
|
+
callbackFunc = self._options.callbacks[callbackName];
|
1051
|
+
self._options.callbacks[callbackName] = function() {
|
1052
|
+
return safeCallback(callbackName, callbackFunc, arguments);
|
863
1053
|
}
|
864
1054
|
}());
|
865
1055
|
}
|
@@ -912,7 +1102,395 @@ qq.FineUploaderBasic.prototype = {
|
|
912
1102
|
}
|
913
1103
|
|
914
1104
|
return fileDescriptors;
|
1105
|
+
},
|
1106
|
+
_createParamsStore: function() {
|
1107
|
+
var paramsStore = {},
|
1108
|
+
self = this;
|
1109
|
+
|
1110
|
+
return {
|
1111
|
+
setParams: function(params, fileId) {
|
1112
|
+
var paramsCopy = {};
|
1113
|
+
qq.extend(paramsCopy, params);
|
1114
|
+
paramsStore[fileId] = paramsCopy;
|
1115
|
+
},
|
1116
|
+
|
1117
|
+
getParams: function(fileId) {
|
1118
|
+
var paramsCopy = {};
|
1119
|
+
|
1120
|
+
if (fileId !== undefined && paramsStore[fileId]) {
|
1121
|
+
qq.extend(paramsCopy, paramsStore[fileId]);
|
1122
|
+
}
|
1123
|
+
else {
|
1124
|
+
qq.extend(paramsCopy, self._options.request.params);
|
1125
|
+
}
|
1126
|
+
|
1127
|
+
return paramsCopy;
|
1128
|
+
},
|
1129
|
+
|
1130
|
+
remove: function(fileId) {
|
1131
|
+
return delete paramsStore[fileId];
|
1132
|
+
},
|
1133
|
+
|
1134
|
+
reset: function() {
|
1135
|
+
paramsStore = {};
|
1136
|
+
}
|
1137
|
+
}
|
1138
|
+
}
|
1139
|
+
};
|
1140
|
+
/*globals qq, document*/
|
1141
|
+
qq.DragAndDrop = function(o) {
|
1142
|
+
"use strict";
|
1143
|
+
|
1144
|
+
var options, dz, dirPending,
|
1145
|
+
droppedFiles = [],
|
1146
|
+
droppedEntriesCount = 0,
|
1147
|
+
droppedEntriesParsedCount = 0,
|
1148
|
+
disposeSupport = new qq.DisposeSupport();
|
1149
|
+
|
1150
|
+
options = {
|
1151
|
+
dropArea: null,
|
1152
|
+
extraDropzones: [],
|
1153
|
+
hideDropzones: true,
|
1154
|
+
multiple: true,
|
1155
|
+
classes: {
|
1156
|
+
dropActive: null
|
1157
|
+
},
|
1158
|
+
callbacks: {
|
1159
|
+
dropProcessing: function(isProcessing, files) {},
|
1160
|
+
error: function(code, filename) {},
|
1161
|
+
log: function(message, level) {}
|
1162
|
+
}
|
1163
|
+
};
|
1164
|
+
|
1165
|
+
qq.extend(options, o);
|
1166
|
+
|
1167
|
+
function maybeUploadDroppedFiles() {
|
1168
|
+
if (droppedEntriesCount === droppedEntriesParsedCount && !dirPending) {
|
1169
|
+
options.callbacks.log('Grabbed ' + droppedFiles.length + " files after tree traversal.");
|
1170
|
+
dz.dropDisabled(false);
|
1171
|
+
options.callbacks.dropProcessing(false, droppedFiles);
|
1172
|
+
}
|
1173
|
+
}
|
1174
|
+
function addDroppedFile(file) {
|
1175
|
+
droppedFiles.push(file);
|
1176
|
+
droppedEntriesParsedCount+=1;
|
1177
|
+
maybeUploadDroppedFiles();
|
1178
|
+
}
|
1179
|
+
|
1180
|
+
function traverseFileTree(entry) {
|
1181
|
+
var dirReader, i;
|
1182
|
+
|
1183
|
+
droppedEntriesCount+=1;
|
1184
|
+
|
1185
|
+
if (entry.isFile) {
|
1186
|
+
entry.file(function(file) {
|
1187
|
+
addDroppedFile(file);
|
1188
|
+
});
|
1189
|
+
}
|
1190
|
+
else if (entry.isDirectory) {
|
1191
|
+
dirPending = true;
|
1192
|
+
dirReader = entry.createReader();
|
1193
|
+
dirReader.readEntries(function(entries) {
|
1194
|
+
droppedEntriesParsedCount+=1;
|
1195
|
+
for (i = 0; i < entries.length; i+=1) {
|
1196
|
+
traverseFileTree(entries[i]);
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
dirPending = false;
|
1200
|
+
|
1201
|
+
if (!entries.length) {
|
1202
|
+
maybeUploadDroppedFiles();
|
1203
|
+
}
|
1204
|
+
});
|
1205
|
+
}
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
function handleDataTransfer(dataTransfer) {
|
1209
|
+
var i, items, entry;
|
1210
|
+
|
1211
|
+
options.callbacks.dropProcessing(true);
|
1212
|
+
dz.dropDisabled(true);
|
1213
|
+
|
1214
|
+
if (dataTransfer.files.length > 1 && !options.multiple) {
|
1215
|
+
options.callbacks.error('tooManyFilesError', "");
|
1216
|
+
}
|
1217
|
+
else {
|
1218
|
+
droppedFiles = [];
|
1219
|
+
droppedEntriesCount = 0;
|
1220
|
+
droppedEntriesParsedCount = 0;
|
1221
|
+
|
1222
|
+
if (qq.isFolderDropSupported(dataTransfer)) {
|
1223
|
+
items = dataTransfer.items;
|
1224
|
+
|
1225
|
+
for (i = 0; i < items.length; i+=1) {
|
1226
|
+
entry = items[i].webkitGetAsEntry();
|
1227
|
+
if (entry) {
|
1228
|
+
//due to a bug in Chrome's File System API impl - #149735
|
1229
|
+
if (entry.isFile) {
|
1230
|
+
droppedFiles.push(items[i].getAsFile());
|
1231
|
+
if (i === items.length-1) {
|
1232
|
+
maybeUploadDroppedFiles();
|
1233
|
+
}
|
1234
|
+
}
|
1235
|
+
|
1236
|
+
else {
|
1237
|
+
traverseFileTree(entry);
|
1238
|
+
}
|
1239
|
+
}
|
1240
|
+
}
|
1241
|
+
}
|
1242
|
+
else {
|
1243
|
+
options.callbacks.dropProcessing(false, dataTransfer.files);
|
1244
|
+
dz.dropDisabled(false);
|
1245
|
+
}
|
1246
|
+
}
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
function setupDropzone(dropArea){
|
1250
|
+
dz = new qq.UploadDropZone({
|
1251
|
+
element: dropArea,
|
1252
|
+
onEnter: function(e){
|
1253
|
+
qq(dropArea).addClass(options.classes.dropActive);
|
1254
|
+
e.stopPropagation();
|
1255
|
+
},
|
1256
|
+
onLeaveNotDescendants: function(e){
|
1257
|
+
qq(dropArea).removeClass(options.classes.dropActive);
|
1258
|
+
},
|
1259
|
+
onDrop: function(e){
|
1260
|
+
if (options.hideDropzones) {
|
1261
|
+
qq(dropArea).hide();
|
1262
|
+
}
|
1263
|
+
qq(dropArea).removeClass(options.classes.dropActive);
|
1264
|
+
|
1265
|
+
handleDataTransfer(e.dataTransfer);
|
1266
|
+
}
|
1267
|
+
});
|
1268
|
+
|
1269
|
+
disposeSupport.addDisposer(function() {
|
1270
|
+
dz.dispose();
|
1271
|
+
});
|
1272
|
+
|
1273
|
+
if (options.hideDropzones) {
|
1274
|
+
qq(dropArea).hide();
|
1275
|
+
}
|
1276
|
+
}
|
1277
|
+
|
1278
|
+
function isFileDrag(dragEvent) {
|
1279
|
+
var fileDrag;
|
1280
|
+
|
1281
|
+
qq.each(dragEvent.dataTransfer.types, function(key, val) {
|
1282
|
+
if (val === 'Files') {
|
1283
|
+
fileDrag = true;
|
1284
|
+
return false;
|
1285
|
+
}
|
1286
|
+
});
|
1287
|
+
|
1288
|
+
return fileDrag;
|
1289
|
+
}
|
1290
|
+
|
1291
|
+
function setupDragDrop(){
|
1292
|
+
if (options.dropArea) {
|
1293
|
+
options.extraDropzones.push(options.dropArea);
|
1294
|
+
}
|
1295
|
+
|
1296
|
+
var i, dropzones = options.extraDropzones;
|
1297
|
+
|
1298
|
+
for (i=0; i < dropzones.length; i+=1){
|
1299
|
+
setupDropzone(dropzones[i]);
|
1300
|
+
}
|
1301
|
+
|
1302
|
+
// IE <= 9 does not support the File API used for drag+drop uploads
|
1303
|
+
if (options.dropArea && (!qq.ie() || qq.ie10())) {
|
1304
|
+
disposeSupport.attach(document, 'dragenter', function(e) {
|
1305
|
+
if (!dz.dropDisabled() && isFileDrag(e)) {
|
1306
|
+
if (qq(options.dropArea).hasClass(options.classes.dropDisabled)) {
|
1307
|
+
return;
|
1308
|
+
}
|
1309
|
+
|
1310
|
+
options.dropArea.style.display = 'block';
|
1311
|
+
for (i=0; i < dropzones.length; i+=1) {
|
1312
|
+
dropzones[i].style.display = 'block';
|
1313
|
+
}
|
1314
|
+
}
|
1315
|
+
});
|
1316
|
+
}
|
1317
|
+
disposeSupport.attach(document, 'dragleave', function(e){
|
1318
|
+
if (options.hideDropzones && qq.FineUploader.prototype._leaving_document_out(e)) {
|
1319
|
+
for (i=0; i < dropzones.length; i+=1) {
|
1320
|
+
qq(dropzones[i]).hide();
|
1321
|
+
}
|
1322
|
+
}
|
1323
|
+
});
|
1324
|
+
disposeSupport.attach(document, 'drop', function(e){
|
1325
|
+
if (options.hideDropzones) {
|
1326
|
+
for (i=0; i < dropzones.length; i+=1) {
|
1327
|
+
qq(dropzones[i]).hide();
|
1328
|
+
}
|
1329
|
+
}
|
1330
|
+
e.preventDefault();
|
1331
|
+
});
|
1332
|
+
}
|
1333
|
+
|
1334
|
+
return {
|
1335
|
+
setup: function() {
|
1336
|
+
setupDragDrop();
|
1337
|
+
},
|
1338
|
+
|
1339
|
+
setupExtraDropzone: function(element) {
|
1340
|
+
options.extraDropzones.push(element);
|
1341
|
+
setupDropzone(element);
|
1342
|
+
},
|
1343
|
+
|
1344
|
+
removeExtraDropzone: function(element) {
|
1345
|
+
var i, dzs = options.extraDropzones;
|
1346
|
+
for(i in dzs) {
|
1347
|
+
if (dzs[i] === element) {
|
1348
|
+
return dzs.splice(i, 1);
|
1349
|
+
}
|
1350
|
+
}
|
1351
|
+
},
|
1352
|
+
|
1353
|
+
dispose: function() {
|
1354
|
+
disposeSupport.dispose();
|
1355
|
+
dz.dispose();
|
1356
|
+
}
|
1357
|
+
};
|
1358
|
+
};
|
1359
|
+
|
1360
|
+
|
1361
|
+
qq.UploadDropZone = function(o){
|
1362
|
+
"use strict";
|
1363
|
+
|
1364
|
+
var options, element, preventDrop, dropOutsideDisabled, disposeSupport = new qq.DisposeSupport();
|
1365
|
+
|
1366
|
+
options = {
|
1367
|
+
element: null,
|
1368
|
+
onEnter: function(e){},
|
1369
|
+
onLeave: function(e){},
|
1370
|
+
// is not fired when leaving element by hovering descendants
|
1371
|
+
onLeaveNotDescendants: function(e){},
|
1372
|
+
onDrop: function(e){}
|
1373
|
+
};
|
1374
|
+
|
1375
|
+
qq.extend(options, o);
|
1376
|
+
element = options.element;
|
1377
|
+
|
1378
|
+
function dragover_should_be_canceled(){
|
1379
|
+
return qq.safari() || (qq.firefox() && qq.windows());
|
1380
|
+
}
|
1381
|
+
|
1382
|
+
function disableDropOutside(e){
|
1383
|
+
// run only once for all instances
|
1384
|
+
if (!dropOutsideDisabled ){
|
1385
|
+
|
1386
|
+
// for these cases we need to catch onDrop to reset dropArea
|
1387
|
+
if (dragover_should_be_canceled){
|
1388
|
+
disposeSupport.attach(document, 'dragover', function(e){
|
1389
|
+
e.preventDefault();
|
1390
|
+
});
|
1391
|
+
} else {
|
1392
|
+
disposeSupport.attach(document, 'dragover', function(e){
|
1393
|
+
if (e.dataTransfer){
|
1394
|
+
e.dataTransfer.dropEffect = 'none';
|
1395
|
+
e.preventDefault();
|
1396
|
+
}
|
1397
|
+
});
|
1398
|
+
}
|
1399
|
+
|
1400
|
+
dropOutsideDisabled = true;
|
1401
|
+
}
|
915
1402
|
}
|
1403
|
+
|
1404
|
+
function isValidFileDrag(e){
|
1405
|
+
// e.dataTransfer currently causing IE errors
|
1406
|
+
// IE9 does NOT support file API, so drag-and-drop is not possible
|
1407
|
+
if (qq.ie() && !qq.ie10()) {
|
1408
|
+
return false;
|
1409
|
+
}
|
1410
|
+
|
1411
|
+
var effectTest, dt = e.dataTransfer,
|
1412
|
+
// do not check dt.types.contains in webkit, because it crashes safari 4
|
1413
|
+
isSafari = qq.safari();
|
1414
|
+
|
1415
|
+
// dt.effectAllowed is none in Safari 5
|
1416
|
+
// dt.types.contains check is for firefox
|
1417
|
+
effectTest = qq.ie10() ? true : dt.effectAllowed !== 'none';
|
1418
|
+
return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains('Files')));
|
1419
|
+
}
|
1420
|
+
|
1421
|
+
function isOrSetDropDisabled(isDisabled) {
|
1422
|
+
if (isDisabled !== undefined) {
|
1423
|
+
preventDrop = isDisabled;
|
1424
|
+
}
|
1425
|
+
return preventDrop;
|
1426
|
+
}
|
1427
|
+
|
1428
|
+
function attachEvents(){
|
1429
|
+
disposeSupport.attach(element, 'dragover', function(e){
|
1430
|
+
if (!isValidFileDrag(e)) {
|
1431
|
+
return;
|
1432
|
+
}
|
1433
|
+
|
1434
|
+
var effect = qq.ie() ? null : e.dataTransfer.effectAllowed;
|
1435
|
+
if (effect === 'move' || effect === 'linkMove'){
|
1436
|
+
e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
|
1437
|
+
} else {
|
1438
|
+
e.dataTransfer.dropEffect = 'copy'; // for Chrome
|
1439
|
+
}
|
1440
|
+
|
1441
|
+
e.stopPropagation();
|
1442
|
+
e.preventDefault();
|
1443
|
+
});
|
1444
|
+
|
1445
|
+
disposeSupport.attach(element, 'dragenter', function(e){
|
1446
|
+
if (!isOrSetDropDisabled()) {
|
1447
|
+
if (!isValidFileDrag(e)) {
|
1448
|
+
return;
|
1449
|
+
}
|
1450
|
+
options.onEnter(e);
|
1451
|
+
}
|
1452
|
+
});
|
1453
|
+
|
1454
|
+
disposeSupport.attach(element, 'dragleave', function(e){
|
1455
|
+
if (!isValidFileDrag(e)) {
|
1456
|
+
return;
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
options.onLeave(e);
|
1460
|
+
|
1461
|
+
var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
|
1462
|
+
// do not fire when moving a mouse over a descendant
|
1463
|
+
if (qq(this).contains(relatedTarget)) {
|
1464
|
+
return;
|
1465
|
+
}
|
1466
|
+
|
1467
|
+
options.onLeaveNotDescendants(e);
|
1468
|
+
});
|
1469
|
+
|
1470
|
+
disposeSupport.attach(element, 'drop', function(e){
|
1471
|
+
if (!isOrSetDropDisabled()) {
|
1472
|
+
if (!isValidFileDrag(e)) {
|
1473
|
+
return;
|
1474
|
+
}
|
1475
|
+
|
1476
|
+
e.preventDefault();
|
1477
|
+
options.onDrop(e);
|
1478
|
+
}
|
1479
|
+
});
|
1480
|
+
}
|
1481
|
+
|
1482
|
+
disableDropOutside();
|
1483
|
+
attachEvents();
|
1484
|
+
|
1485
|
+
return {
|
1486
|
+
dropDisabled: function(isDisabled) {
|
1487
|
+
return isOrSetDropDisabled(isDisabled);
|
1488
|
+
},
|
1489
|
+
|
1490
|
+
dispose: function() {
|
1491
|
+
disposeSupport.dispose();
|
1492
|
+
}
|
1493
|
+
};
|
916
1494
|
};
|
917
1495
|
/**
|
918
1496
|
* Class that creates upload widget with drag-and-drop and file list
|
@@ -937,12 +1515,14 @@ qq.FineUploader = function(o){
|
|
937
1515
|
retryButton: 'Retry',
|
938
1516
|
failUpload: 'Upload failed',
|
939
1517
|
dragZone: 'Drop files here to upload',
|
1518
|
+
dropProcessing: 'Processing dropped files...',
|
940
1519
|
formatProgress: "{percent}% of {total_size}",
|
941
1520
|
waitingForResponse: "Processing..."
|
942
1521
|
},
|
943
1522
|
template: '<div class="qq-uploader">' +
|
944
1523
|
((!this._options.dragAndDrop || !this._options.dragAndDrop.disableDefaultDropzone) ? '<div class="qq-upload-drop-area"><span>{dragZoneText}</span></div>' : '') +
|
945
1524
|
(!this._options.button ? '<div class="qq-upload-button"><div>{uploadButtonText}</div></div>' : '') +
|
1525
|
+
'<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>' +
|
946
1526
|
(!this._options.listElement ? '<ul class="qq-upload-list"></ul>' : '') +
|
947
1527
|
'</div>',
|
948
1528
|
|
@@ -958,7 +1538,6 @@ qq.FineUploader = function(o){
|
|
958
1538
|
'<span class="qq-upload-status-text">{statusText}</span>' +
|
959
1539
|
'</li>',
|
960
1540
|
classes: {
|
961
|
-
// used to get elements from templates
|
962
1541
|
button: 'qq-upload-button',
|
963
1542
|
drop: 'qq-upload-drop-area',
|
964
1543
|
dropActive: 'qq-upload-drop-area-active',
|
@@ -975,13 +1554,14 @@ qq.FineUploader = function(o){
|
|
975
1554
|
retry: 'qq-upload-retry',
|
976
1555
|
statusText: 'qq-upload-status-text',
|
977
1556
|
|
978
|
-
// added to list item <li> when upload completes
|
979
|
-
// used in css to hide progress spinner
|
980
1557
|
success: 'qq-upload-success',
|
981
1558
|
fail: 'qq-upload-fail',
|
982
1559
|
|
983
1560
|
successIcon: null,
|
984
|
-
failIcon: null
|
1561
|
+
failIcon: null,
|
1562
|
+
|
1563
|
+
dropProcessing: 'qq-drop-processing',
|
1564
|
+
dropProcessingSpinner: 'qq-drop-processing-spinner'
|
985
1565
|
},
|
986
1566
|
failedUploadTextDisplay: {
|
987
1567
|
mode: 'default', //default, custom, or none
|
@@ -1010,6 +1590,7 @@ qq.FineUploader = function(o){
|
|
1010
1590
|
// same for the Cancel button and Fail message text
|
1011
1591
|
this._options.template = this._options.template.replace(/\{dragZoneText\}/g, this._options.text.dragZone);
|
1012
1592
|
this._options.template = this._options.template.replace(/\{uploadButtonText\}/g, this._options.text.uploadButton);
|
1593
|
+
this._options.template = this._options.template.replace(/\{dropProcessingText\}/g, this._options.text.dropProcessing);
|
1013
1594
|
this._options.fileTemplate = this._options.fileTemplate.replace(/\{cancelButtonText\}/g, this._options.text.cancelButton);
|
1014
1595
|
this._options.fileTemplate = this._options.fileTemplate.replace(/\{retryButtonText\}/g, this._options.text.retryButton);
|
1015
1596
|
this._options.fileTemplate = this._options.fileTemplate.replace(/\{statusText\}/g, "");
|
@@ -1025,7 +1606,8 @@ qq.FineUploader = function(o){
|
|
1025
1606
|
}
|
1026
1607
|
|
1027
1608
|
this._bindCancelAndRetryEvents();
|
1028
|
-
|
1609
|
+
|
1610
|
+
this._dnd = this._setupDragAndDrop();
|
1029
1611
|
};
|
1030
1612
|
|
1031
1613
|
// inherit from Basic Uploader
|
@@ -1037,11 +1619,10 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1037
1619
|
this._listElement.innerHTML = "";
|
1038
1620
|
},
|
1039
1621
|
addExtraDropzone: function(element){
|
1040
|
-
this.
|
1622
|
+
this._dnd.setupExtraDropzone(element);
|
1041
1623
|
},
|
1042
1624
|
removeExtraDropzone: function(element){
|
1043
|
-
|
1044
|
-
for(var i in dzs) if (dzs[i] === element) return this._options.dragAndDrop.extraDropzones.splice(i,1);
|
1625
|
+
return this._dnd.removeExtraDropzone(element);
|
1045
1626
|
},
|
1046
1627
|
getItemByFileId: function(id){
|
1047
1628
|
var item = this._listElement.firstChild;
|
@@ -1053,6 +1634,11 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1053
1634
|
item = item.nextSibling;
|
1054
1635
|
}
|
1055
1636
|
},
|
1637
|
+
cancel: function(fileId) {
|
1638
|
+
qq.FineUploaderBasic.prototype.cancel.apply(this, arguments);
|
1639
|
+
var item = this.getItemByFileId(fileId);
|
1640
|
+
qq(item).remove();
|
1641
|
+
},
|
1056
1642
|
reset: function() {
|
1057
1643
|
qq.FineUploaderBasic.prototype.reset.apply(this, arguments);
|
1058
1644
|
this._element.innerHTML = this._options.template;
|
@@ -1061,7 +1647,59 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1061
1647
|
this._button = this._createUploadButton(this._find(this._element, 'button'));
|
1062
1648
|
}
|
1063
1649
|
this._bindCancelAndRetryEvents();
|
1064
|
-
this.
|
1650
|
+
this._dnd.dispose();
|
1651
|
+
this._dnd = this._setupDragAndDrop();
|
1652
|
+
},
|
1653
|
+
_setupDragAndDrop: function() {
|
1654
|
+
var self = this,
|
1655
|
+
dropProcessingEl = this._find(this._element, 'dropProcessing'),
|
1656
|
+
dnd, preventSelectFiles, defaultDropAreaEl;
|
1657
|
+
|
1658
|
+
preventSelectFiles = function(event) {
|
1659
|
+
event.preventDefault();
|
1660
|
+
};
|
1661
|
+
|
1662
|
+
if (!this._options.dragAndDrop.disableDefaultDropzone) {
|
1663
|
+
defaultDropAreaEl = this._find(this._options.element, 'drop');
|
1664
|
+
}
|
1665
|
+
|
1666
|
+
dnd = new qq.DragAndDrop({
|
1667
|
+
dropArea: defaultDropAreaEl,
|
1668
|
+
extraDropzones: this._options.dragAndDrop.extraDropzones,
|
1669
|
+
hideDropzones: this._options.dragAndDrop.hideDropzones,
|
1670
|
+
multiple: this._options.multiple,
|
1671
|
+
classes: {
|
1672
|
+
dropActive: this._options.classes.dropActive
|
1673
|
+
},
|
1674
|
+
callbacks: {
|
1675
|
+
dropProcessing: function(isProcessing, files) {
|
1676
|
+
var input = self._button.getInput();
|
1677
|
+
|
1678
|
+
if (isProcessing) {
|
1679
|
+
qq(dropProcessingEl).css({display: 'block'});
|
1680
|
+
qq(input).attach('click', preventSelectFiles);
|
1681
|
+
}
|
1682
|
+
else {
|
1683
|
+
qq(dropProcessingEl).hide();
|
1684
|
+
qq(input).detach('click', preventSelectFiles);
|
1685
|
+
}
|
1686
|
+
|
1687
|
+
if (files) {
|
1688
|
+
self.addFiles(files);
|
1689
|
+
}
|
1690
|
+
},
|
1691
|
+
error: function(code, filename) {
|
1692
|
+
self._error(code, filename);
|
1693
|
+
},
|
1694
|
+
log: function(message, level) {
|
1695
|
+
self.log(message, level);
|
1696
|
+
}
|
1697
|
+
}
|
1698
|
+
});
|
1699
|
+
|
1700
|
+
dnd.setup();
|
1701
|
+
|
1702
|
+
return dnd;
|
1065
1703
|
},
|
1066
1704
|
_leaving_document_out: function(e){
|
1067
1705
|
return ((qq.chrome() || (qq.safari() && qq.windows())) && e.clientX == 0 && e.clientY == 0) // null coords for Chrome and Safari Windows
|
@@ -1083,88 +1721,6 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1083
1721
|
|
1084
1722
|
return element;
|
1085
1723
|
},
|
1086
|
-
_setupExtraDropzone: function(element){
|
1087
|
-
this._options.dragAndDrop.extraDropzones.push(element);
|
1088
|
-
this._setupDropzone(element);
|
1089
|
-
},
|
1090
|
-
_setupDropzone: function(dropArea){
|
1091
|
-
var self = this;
|
1092
|
-
|
1093
|
-
var dz = new qq.UploadDropZone({
|
1094
|
-
element: dropArea,
|
1095
|
-
onEnter: function(e){
|
1096
|
-
qq(dropArea).addClass(self._classes.dropActive);
|
1097
|
-
e.stopPropagation();
|
1098
|
-
},
|
1099
|
-
onLeave: function(e){
|
1100
|
-
//e.stopPropagation();
|
1101
|
-
},
|
1102
|
-
onLeaveNotDescendants: function(e){
|
1103
|
-
qq(dropArea).removeClass(self._classes.dropActive);
|
1104
|
-
},
|
1105
|
-
onDrop: function(e){
|
1106
|
-
if (self._options.dragAndDrop.hideDropzones) {
|
1107
|
-
qq(dropArea).hide();
|
1108
|
-
}
|
1109
|
-
|
1110
|
-
qq(dropArea).removeClass(self._classes.dropActive);
|
1111
|
-
if (e.dataTransfer.files.length > 1 && !self._options.multiple) {
|
1112
|
-
self._error('tooManyFilesError', "");
|
1113
|
-
}
|
1114
|
-
else {
|
1115
|
-
self._uploadFileList(e.dataTransfer.files);
|
1116
|
-
}
|
1117
|
-
}
|
1118
|
-
});
|
1119
|
-
|
1120
|
-
this.addDisposer(function() { dz.dispose(); });
|
1121
|
-
|
1122
|
-
if (this._options.dragAndDrop.hideDropzones) {
|
1123
|
-
qq(dropArea).hide();
|
1124
|
-
}
|
1125
|
-
},
|
1126
|
-
_setupDragDrop: function(){
|
1127
|
-
var self, dropArea;
|
1128
|
-
|
1129
|
-
self = this;
|
1130
|
-
|
1131
|
-
if (!this._options.dragAndDrop.disableDefaultDropzone) {
|
1132
|
-
dropArea = this._find(this._element, 'drop');
|
1133
|
-
this._options.dragAndDrop.extraDropzones.push(dropArea);
|
1134
|
-
}
|
1135
|
-
|
1136
|
-
var dropzones = this._options.dragAndDrop.extraDropzones;
|
1137
|
-
var i;
|
1138
|
-
for (i=0; i < dropzones.length; i++){
|
1139
|
-
this._setupDropzone(dropzones[i]);
|
1140
|
-
}
|
1141
|
-
|
1142
|
-
// IE <= 9 does not support the File API used for drag+drop uploads
|
1143
|
-
if (!this._options.dragAndDrop.disableDefaultDropzone && (!qq.ie() || qq.ie10())) {
|
1144
|
-
this._attach(document, 'dragenter', function(e){
|
1145
|
-
if (qq(dropArea).hasClass(self._classes.dropDisabled)) return;
|
1146
|
-
|
1147
|
-
dropArea.style.display = 'block';
|
1148
|
-
for (i=0; i < dropzones.length; i++){ dropzones[i].style.display = 'block'; }
|
1149
|
-
|
1150
|
-
});
|
1151
|
-
}
|
1152
|
-
this._attach(document, 'dragleave', function(e){
|
1153
|
-
if (self._options.dragAndDrop.hideDropzones && qq.FineUploader.prototype._leaving_document_out(e)) {
|
1154
|
-
for (i=0; i < dropzones.length; i++) {
|
1155
|
-
qq(dropzones[i]).hide();
|
1156
|
-
}
|
1157
|
-
}
|
1158
|
-
});
|
1159
|
-
qq(document).attach('drop', function(e){
|
1160
|
-
if (self._options.dragAndDrop.hideDropzones) {
|
1161
|
-
for (i=0; i < dropzones.length; i++) {
|
1162
|
-
qq(dropzones[i]).hide();
|
1163
|
-
}
|
1164
|
-
}
|
1165
|
-
e.preventDefault();
|
1166
|
-
});
|
1167
|
-
},
|
1168
1724
|
_onSubmit: function(id, fileName){
|
1169
1725
|
qq.FineUploaderBasic.prototype._onSubmit.apply(this, arguments);
|
1170
1726
|
this._addToList(id, fileName);
|
@@ -1213,7 +1769,7 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1213
1769
|
qq(item).removeClass(this._classes.retrying);
|
1214
1770
|
qq(this._find(item, 'progressBar')).hide();
|
1215
1771
|
|
1216
|
-
if (!this._options.disableCancelForFormUploads || qq.
|
1772
|
+
if (!this._options.disableCancelForFormUploads || qq.isXhrUploadSupported()) {
|
1217
1773
|
qq(this._find(item, 'cancel')).hide();
|
1218
1774
|
}
|
1219
1775
|
qq(this._find(item, 'spinner')).hide();
|
@@ -1282,7 +1838,7 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1282
1838
|
},
|
1283
1839
|
_addToList: function(id, fileName){
|
1284
1840
|
var item = qq.toElement(this._options.fileTemplate);
|
1285
|
-
if (this._options.disableCancelForFormUploads && !qq.
|
1841
|
+
if (this._options.disableCancelForFormUploads && !qq.isXhrUploadSupported()) {
|
1286
1842
|
var cancelLink = this._find(item, 'cancel');
|
1287
1843
|
qq(cancelLink).remove();
|
1288
1844
|
}
|
@@ -1306,7 +1862,7 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1306
1862
|
var self = this,
|
1307
1863
|
list = this._listElement;
|
1308
1864
|
|
1309
|
-
this.
|
1865
|
+
this._disposeSupport.attach(list, 'click', function(e){
|
1310
1866
|
e = e || window.event;
|
1311
1867
|
var target = e.target || e.srcElement;
|
1312
1868
|
|
@@ -1320,7 +1876,6 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1320
1876
|
|
1321
1877
|
if (qq(target).hasClass(self._classes.cancel)) {
|
1322
1878
|
self.cancel(item.qqFileId);
|
1323
|
-
qq(item).remove();
|
1324
1879
|
}
|
1325
1880
|
else {
|
1326
1881
|
qq(item).removeClass(self._classes.retryable);
|
@@ -1378,7 +1933,7 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1378
1933
|
spinnerEl.style.display = "inline-block";
|
1379
1934
|
},
|
1380
1935
|
_showCancelLink: function(item) {
|
1381
|
-
if (!this._options.disableCancelForFormUploads || qq.
|
1936
|
+
if (!this._options.disableCancelForFormUploads || qq.isXhrUploadSupported()) {
|
1382
1937
|
var cancelLink = this._find(item, 'cancel');
|
1383
1938
|
cancelLink.style.display = 'inline';
|
1384
1939
|
}
|
@@ -1388,107 +1943,6 @@ qq.extend(qq.FineUploader.prototype, {
|
|
1388
1943
|
this._options.showMessage(message);
|
1389
1944
|
}
|
1390
1945
|
});
|
1391
|
-
|
1392
|
-
qq.UploadDropZone = function(o){
|
1393
|
-
this._options = {
|
1394
|
-
element: null,
|
1395
|
-
onEnter: function(e){},
|
1396
|
-
onLeave: function(e){},
|
1397
|
-
// is not fired when leaving element by hovering descendants
|
1398
|
-
onLeaveNotDescendants: function(e){},
|
1399
|
-
onDrop: function(e){}
|
1400
|
-
};
|
1401
|
-
qq.extend(this._options, o);
|
1402
|
-
qq.extend(this, qq.DisposeSupport);
|
1403
|
-
|
1404
|
-
this._element = this._options.element;
|
1405
|
-
|
1406
|
-
this._disableDropOutside();
|
1407
|
-
this._attachEvents();
|
1408
|
-
};
|
1409
|
-
|
1410
|
-
qq.UploadDropZone.prototype = {
|
1411
|
-
_dragover_should_be_canceled: function(){
|
1412
|
-
return qq.safari() || (qq.firefox() && qq.windows());
|
1413
|
-
},
|
1414
|
-
_disableDropOutside: function(e){
|
1415
|
-
// run only once for all instances
|
1416
|
-
if (!qq.UploadDropZone.dropOutsideDisabled ){
|
1417
|
-
|
1418
|
-
// for these cases we need to catch onDrop to reset dropArea
|
1419
|
-
if (this._dragover_should_be_canceled){
|
1420
|
-
qq(document).attach('dragover', function(e){
|
1421
|
-
e.preventDefault();
|
1422
|
-
});
|
1423
|
-
} else {
|
1424
|
-
qq(document).attach('dragover', function(e){
|
1425
|
-
if (e.dataTransfer){
|
1426
|
-
e.dataTransfer.dropEffect = 'none';
|
1427
|
-
e.preventDefault();
|
1428
|
-
}
|
1429
|
-
});
|
1430
|
-
}
|
1431
|
-
|
1432
|
-
qq.UploadDropZone.dropOutsideDisabled = true;
|
1433
|
-
}
|
1434
|
-
},
|
1435
|
-
_attachEvents: function(){
|
1436
|
-
var self = this;
|
1437
|
-
|
1438
|
-
self._attach(self._element, 'dragover', function(e){
|
1439
|
-
if (!self._isValidFileDrag(e)) return;
|
1440
|
-
|
1441
|
-
var effect = qq.ie() ? null : e.dataTransfer.effectAllowed;
|
1442
|
-
if (effect == 'move' || effect == 'linkMove'){
|
1443
|
-
e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
|
1444
|
-
} else {
|
1445
|
-
e.dataTransfer.dropEffect = 'copy'; // for Chrome
|
1446
|
-
}
|
1447
|
-
|
1448
|
-
e.stopPropagation();
|
1449
|
-
e.preventDefault();
|
1450
|
-
});
|
1451
|
-
|
1452
|
-
self._attach(self._element, 'dragenter', function(e){
|
1453
|
-
if (!self._isValidFileDrag(e)) return;
|
1454
|
-
|
1455
|
-
self._options.onEnter(e);
|
1456
|
-
});
|
1457
|
-
|
1458
|
-
self._attach(self._element, 'dragleave', function(e){
|
1459
|
-
if (!self._isValidFileDrag(e)) return;
|
1460
|
-
|
1461
|
-
self._options.onLeave(e);
|
1462
|
-
|
1463
|
-
var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
|
1464
|
-
// do not fire when moving a mouse over a descendant
|
1465
|
-
if (qq(this).contains(relatedTarget)) return;
|
1466
|
-
|
1467
|
-
self._options.onLeaveNotDescendants(e);
|
1468
|
-
});
|
1469
|
-
|
1470
|
-
self._attach(self._element, 'drop', function(e){
|
1471
|
-
if (!self._isValidFileDrag(e)) return;
|
1472
|
-
|
1473
|
-
e.preventDefault();
|
1474
|
-
self._options.onDrop(e);
|
1475
|
-
});
|
1476
|
-
},
|
1477
|
-
_isValidFileDrag: function(e){
|
1478
|
-
// e.dataTransfer currently causing IE errors
|
1479
|
-
// IE9 does NOT support file API, so drag-and-drop is not possible
|
1480
|
-
if (qq.ie() && !qq.ie10()) return false;
|
1481
|
-
|
1482
|
-
var dt = e.dataTransfer,
|
1483
|
-
// do not check dt.types.contains in webkit, because it crashes safari 4
|
1484
|
-
isSafari = qq.safari();
|
1485
|
-
|
1486
|
-
// dt.effectAllowed is none in Safari 5
|
1487
|
-
// dt.types.contains check is for firefox
|
1488
|
-
var effectTest = qq.ie10() ? true : dt.effectAllowed != 'none';
|
1489
|
-
return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains('Files')));
|
1490
|
-
}
|
1491
|
-
};
|
1492
1946
|
/**
|
1493
1947
|
* Class for uploading files, uploading itself is handled by child classes
|
1494
1948
|
*/
|
@@ -1497,6 +1951,7 @@ qq.UploadHandlerAbstract = function(o){
|
|
1497
1951
|
this._options = {
|
1498
1952
|
debug: false,
|
1499
1953
|
endpoint: '/upload.php',
|
1954
|
+
paramsInBody: false,
|
1500
1955
|
// maximum number of concurrent uploads
|
1501
1956
|
maxConnections: 999,
|
1502
1957
|
log: function(str, level) {},
|
@@ -1510,8 +1965,6 @@ qq.UploadHandlerAbstract = function(o){
|
|
1510
1965
|
qq.extend(this._options, o);
|
1511
1966
|
|
1512
1967
|
this._queue = [];
|
1513
|
-
// params for files in queue
|
1514
|
-
this._params = [];
|
1515
1968
|
|
1516
1969
|
this.log = this._options.log;
|
1517
1970
|
};
|
@@ -1522,27 +1975,23 @@ qq.UploadHandlerAbstract.prototype = {
|
|
1522
1975
|
**/
|
1523
1976
|
add: function(file){},
|
1524
1977
|
/**
|
1525
|
-
* Sends the file identified by id
|
1978
|
+
* Sends the file identified by id
|
1526
1979
|
*/
|
1527
|
-
upload: function(id
|
1980
|
+
upload: function(id){
|
1528
1981
|
var len = this._queue.push(id);
|
1529
1982
|
|
1530
|
-
var copy = {};
|
1531
|
-
qq.extend(copy, params);
|
1532
|
-
this._params[id] = copy;
|
1533
|
-
|
1534
1983
|
// if too many active uploads, wait...
|
1535
1984
|
if (len <= this._options.maxConnections){
|
1536
|
-
this._upload(id
|
1985
|
+
this._upload(id);
|
1537
1986
|
}
|
1538
1987
|
},
|
1539
1988
|
retry: function(id) {
|
1540
1989
|
var i = qq.indexOf(this._queue, id);
|
1541
1990
|
if (i >= 0) {
|
1542
|
-
this._upload(id
|
1991
|
+
this._upload(id);
|
1543
1992
|
}
|
1544
1993
|
else {
|
1545
|
-
this.upload(id
|
1994
|
+
this.upload(id);
|
1546
1995
|
}
|
1547
1996
|
},
|
1548
1997
|
/**
|
@@ -1550,6 +1999,7 @@ qq.UploadHandlerAbstract.prototype = {
|
|
1550
1999
|
*/
|
1551
2000
|
cancel: function(id){
|
1552
2001
|
this.log('Cancelling ' + id);
|
2002
|
+
this._options.paramsStore.remove(id);
|
1553
2003
|
this._cancel(id);
|
1554
2004
|
this._dequeue(id);
|
1555
2005
|
},
|
@@ -1580,7 +2030,6 @@ qq.UploadHandlerAbstract.prototype = {
|
|
1580
2030
|
reset: function() {
|
1581
2031
|
this.log('Resetting upload handler');
|
1582
2032
|
this._queue = [];
|
1583
|
-
this._params = [];
|
1584
2033
|
},
|
1585
2034
|
/**
|
1586
2035
|
* Actual upload method
|
@@ -1601,7 +2050,7 @@ qq.UploadHandlerAbstract.prototype = {
|
|
1601
2050
|
|
1602
2051
|
if (this._queue.length >= max && i < max){
|
1603
2052
|
var nextId = this._queue[max-1];
|
1604
|
-
this._upload(nextId
|
2053
|
+
this._upload(nextId);
|
1605
2054
|
}
|
1606
2055
|
},
|
1607
2056
|
/**
|
@@ -1625,7 +2074,7 @@ qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
|
|
1625
2074
|
qq.extend(qq.UploadHandlerForm.prototype, {
|
1626
2075
|
add: function(fileInput){
|
1627
2076
|
fileInput.setAttribute('name', this._options.inputName);
|
1628
|
-
var id =
|
2077
|
+
var id = qq.getUniqueId();
|
1629
2078
|
|
1630
2079
|
this._inputs[id] = fileInput;
|
1631
2080
|
|
@@ -1664,7 +2113,7 @@ qq.extend(qq.UploadHandlerForm.prototype, {
|
|
1664
2113
|
qq(iframe).remove();
|
1665
2114
|
}
|
1666
2115
|
},
|
1667
|
-
_upload: function(id
|
2116
|
+
_upload: function(id){
|
1668
2117
|
this._options.onUpload(id, this.getName(id), false);
|
1669
2118
|
var input = this._inputs[id];
|
1670
2119
|
|
@@ -1673,10 +2122,9 @@ qq.extend(qq.UploadHandlerForm.prototype, {
|
|
1673
2122
|
}
|
1674
2123
|
|
1675
2124
|
var fileName = this.getName(id);
|
1676
|
-
params[this._options.inputName] = fileName;
|
1677
2125
|
|
1678
2126
|
var iframe = this._createIframe(id);
|
1679
|
-
var form = this._createForm(iframe,
|
2127
|
+
var form = this._createForm(iframe, this._options.paramsStore.getParams(id));
|
1680
2128
|
form.appendChild(input);
|
1681
2129
|
|
1682
2130
|
var self = this;
|
@@ -1793,12 +2241,18 @@ qq.extend(qq.UploadHandlerForm.prototype, {
|
|
1793
2241
|
// form.setAttribute('method', 'post');
|
1794
2242
|
// form.setAttribute('enctype', 'multipart/form-data');
|
1795
2243
|
// Because in this case file won't be attached to request
|
1796
|
-
var protocol = this._options.demoMode ? "GET" : "POST"
|
1797
|
-
|
2244
|
+
var protocol = this._options.demoMode ? "GET" : "POST",
|
2245
|
+
form = qq.toElement('<form method="' + protocol + '" enctype="multipart/form-data"></form>'),
|
2246
|
+
url = this._options.endpoint;
|
1798
2247
|
|
1799
|
-
|
2248
|
+
if (!this._options.paramsInBody) {
|
2249
|
+
url = qq.obj2url(params, this._options.endpoint);
|
2250
|
+
}
|
2251
|
+
else {
|
2252
|
+
qq.obj2Inputs(params, form);
|
2253
|
+
}
|
1800
2254
|
|
1801
|
-
form.setAttribute('action',
|
2255
|
+
form.setAttribute('action', url);
|
1802
2256
|
form.setAttribute('target', iframe.name);
|
1803
2257
|
form.style.display = 'none';
|
1804
2258
|
document.body.appendChild(form);
|
@@ -1820,18 +2274,6 @@ qq.UploadHandlerXhr = function(o){
|
|
1820
2274
|
this._loaded = [];
|
1821
2275
|
};
|
1822
2276
|
|
1823
|
-
// static method
|
1824
|
-
qq.UploadHandlerXhr.isSupported = function(){
|
1825
|
-
var input = document.createElement('input');
|
1826
|
-
input.type = 'file';
|
1827
|
-
|
1828
|
-
return (
|
1829
|
-
'multiple' in input &&
|
1830
|
-
typeof File != "undefined" &&
|
1831
|
-
typeof FormData != "undefined" &&
|
1832
|
-
typeof (new XMLHttpRequest()).upload != "undefined" );
|
1833
|
-
};
|
1834
|
-
|
1835
2277
|
// @inherits qq.UploadHandlerAbstract
|
1836
2278
|
qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
|
1837
2279
|
|
@@ -1873,20 +2315,22 @@ qq.extend(qq.UploadHandlerXhr.prototype, {
|
|
1873
2315
|
this._loaded = [];
|
1874
2316
|
},
|
1875
2317
|
/**
|
1876
|
-
* Sends the file identified by id
|
1877
|
-
* @param {Object} params name-value string pairs
|
2318
|
+
* Sends the file identified by id to the server
|
1878
2319
|
*/
|
1879
|
-
_upload: function(id
|
1880
|
-
this._options.onUpload(id, this.getName(id), true);
|
1881
|
-
|
2320
|
+
_upload: function(id){
|
1882
2321
|
var file = this._files[id],
|
1883
2322
|
name = this.getName(id),
|
1884
|
-
size = this.getSize(id)
|
2323
|
+
size = this.getSize(id),
|
2324
|
+
self = this,
|
2325
|
+
url = this._options.endpoint,
|
2326
|
+
protocol = this._options.demoMode ? "GET" : "POST",
|
2327
|
+
xhr, formData, paramName, key, params;
|
2328
|
+
|
2329
|
+
this._options.onUpload(id, this.getName(id), true);
|
1885
2330
|
|
1886
2331
|
this._loaded[id] = 0;
|
1887
2332
|
|
1888
|
-
|
1889
|
-
var self = this;
|
2333
|
+
xhr = this._xhrs[id] = new XMLHttpRequest();
|
1890
2334
|
|
1891
2335
|
xhr.upload.onprogress = function(e){
|
1892
2336
|
if (e.lengthComputable){
|
@@ -1896,33 +2340,43 @@ qq.extend(qq.UploadHandlerXhr.prototype, {
|
|
1896
2340
|
};
|
1897
2341
|
|
1898
2342
|
xhr.onreadystatechange = function(){
|
1899
|
-
if (xhr.readyState
|
2343
|
+
if (xhr.readyState === 4){
|
1900
2344
|
self._onComplete(id, xhr);
|
1901
2345
|
}
|
1902
2346
|
};
|
1903
2347
|
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
2348
|
+
params = this._options.paramsStore.getParams(id);
|
2349
|
+
|
2350
|
+
//build query string
|
2351
|
+
if (!this._options.paramsInBody) {
|
2352
|
+
params[this._options.inputName] = name;
|
2353
|
+
url = qq.obj2url(params, this._options.endpoint);
|
2354
|
+
}
|
1908
2355
|
|
1909
|
-
|
1910
|
-
xhr.open(protocol, queryString, true);
|
2356
|
+
xhr.open(protocol, url, true);
|
1911
2357
|
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
1912
2358
|
xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
|
1913
2359
|
xhr.setRequestHeader("Cache-Control", "no-cache");
|
1914
|
-
if (this._options.forceMultipart) {
|
1915
|
-
|
2360
|
+
if (this._options.forceMultipart || this._options.paramsInBody) {
|
2361
|
+
formData = new FormData();
|
2362
|
+
|
2363
|
+
if (this._options.paramsInBody) {
|
2364
|
+
qq.obj2FormData(params, formData);
|
2365
|
+
}
|
2366
|
+
|
1916
2367
|
formData.append(this._options.inputName, file);
|
1917
2368
|
file = formData;
|
1918
2369
|
} else {
|
1919
2370
|
xhr.setRequestHeader("Content-Type", "application/octet-stream");
|
1920
2371
|
//NOTE: return mime type in xhr works on chrome 16.0.9 firefox 11.0a2
|
1921
|
-
xhr.setRequestHeader("X-Mime-Type",file.type
|
2372
|
+
xhr.setRequestHeader("X-Mime-Type", file.type);
|
1922
2373
|
}
|
2374
|
+
|
1923
2375
|
for (key in this._options.customHeaders){
|
1924
|
-
|
1925
|
-
|
2376
|
+
if (this._options.customHeaders.hasOwnProperty(key)) {
|
2377
|
+
xhr.setRequestHeader(key, this._options.customHeaders[key]);
|
2378
|
+
}
|
2379
|
+
}
|
1926
2380
|
|
1927
2381
|
this.log('Sending upload request for ' + id);
|
1928
2382
|
xhr.send(file);
|