fine_uploader 3.1.1 → 3.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +1 -3
- data/Vendorfile +16 -5
- data/lib/fine_uploader/version.rb +1 -1
- data/vendor/assets/javascripts/fine_uploader/ajax.requester.js +184 -0
- data/vendor/assets/javascripts/fine_uploader/button.js +62 -58
- data/vendor/assets/javascripts/fine_uploader/deletefile.ajax.requester.js +44 -0
- data/vendor/assets/javascripts/fine_uploader/dnd.js +2 -0
- data/vendor/assets/javascripts/fine_uploader/handler.base.js +164 -92
- data/vendor/assets/javascripts/fine_uploader/handler.form.js +220 -133
- data/vendor/assets/javascripts/fine_uploader/handler.xhr.js +594 -132
- data/vendor/assets/javascripts/fine_uploader/header.js +3 -4
- data/vendor/assets/javascripts/fine_uploader/iframe.xss.response.js +6 -0
- data/vendor/assets/javascripts/fine_uploader/jquery-plugin.js +13 -4
- data/vendor/assets/javascripts/fine_uploader/paste.js +49 -0
- data/vendor/assets/javascripts/fine_uploader/promise.js +45 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.basic.js +547 -175
- data/vendor/assets/javascripts/fine_uploader/uploader.js +197 -42
- data/vendor/assets/javascripts/fine_uploader/util.js +117 -12
- data/vendor/assets/javascripts/fine_uploader/window.receive.message.js +32 -0
- data/vendor/assets/javascripts/fine_uploader.js +17 -0
- data/vendor/assets/stylesheets/fine_uploader.css.scss +6 -7
- metadata +9 -2
@@ -19,6 +19,7 @@ qq.FineUploader = function(o){
|
|
19
19
|
uploadButton: 'Upload a file',
|
20
20
|
cancelButton: 'Cancel',
|
21
21
|
retryButton: 'Retry',
|
22
|
+
deleteButton: 'Delete',
|
22
23
|
failUpload: 'Upload failed',
|
23
24
|
dragZone: 'Drop files here to upload',
|
24
25
|
dropProcessing: 'Processing dropped files...',
|
@@ -41,6 +42,7 @@ qq.FineUploader = function(o){
|
|
41
42
|
'<span class="qq-upload-size"></span>' +
|
42
43
|
'<a class="qq-upload-cancel" href="#">{cancelButtonText}</a>' +
|
43
44
|
'<a class="qq-upload-retry" href="#">{retryButtonText}</a>' +
|
45
|
+
'<a class="qq-upload-delete" href="#">{deleteButtonText}</a>' +
|
44
46
|
'<span class="qq-upload-status-text">{statusText}</span>' +
|
45
47
|
'</li>',
|
46
48
|
classes: {
|
@@ -57,6 +59,7 @@ qq.FineUploader = function(o){
|
|
57
59
|
retryable: 'qq-upload-retryable',
|
58
60
|
size: 'qq-upload-size',
|
59
61
|
cancel: 'qq-upload-cancel',
|
62
|
+
deleteButton: 'qq-upload-delete',
|
60
63
|
retry: 'qq-upload-retry',
|
61
64
|
statusText: 'qq-upload-status-text',
|
62
65
|
|
@@ -83,8 +86,49 @@ qq.FineUploader = function(o){
|
|
83
86
|
autoRetryNote: "Retrying {retryNum}/{maxAuto}...",
|
84
87
|
showButton: false
|
85
88
|
},
|
89
|
+
deleteFile: {
|
90
|
+
forceConfirm: false,
|
91
|
+
confirmMessage: "Are you sure you want to delete {filename}?",
|
92
|
+
deletingStatusText: "Deleting...",
|
93
|
+
deletingFailedText: "Delete failed"
|
94
|
+
|
95
|
+
},
|
96
|
+
display: {
|
97
|
+
fileSizeOnSubmit: false
|
98
|
+
},
|
99
|
+
paste: {
|
100
|
+
promptForName: false,
|
101
|
+
namePromptMessage: "Please name this image"
|
102
|
+
},
|
86
103
|
showMessage: function(message){
|
87
|
-
|
104
|
+
setTimeout(function() {
|
105
|
+
window.alert(message);
|
106
|
+
}, 0);
|
107
|
+
},
|
108
|
+
showConfirm: function(message, okCallback, cancelCallback) {
|
109
|
+
setTimeout(function() {
|
110
|
+
var result = window.confirm(message);
|
111
|
+
if (result) {
|
112
|
+
okCallback();
|
113
|
+
}
|
114
|
+
else if (cancelCallback) {
|
115
|
+
cancelCallback();
|
116
|
+
}
|
117
|
+
}, 0);
|
118
|
+
},
|
119
|
+
showPrompt: function(message, defaultValue) {
|
120
|
+
var promise = new qq.Promise(),
|
121
|
+
retVal = window.prompt(message, defaultValue);
|
122
|
+
|
123
|
+
/*jshint eqeqeq: true, eqnull: true*/
|
124
|
+
if (retVal != null && qq.trimStr(retVal).length > 0) {
|
125
|
+
promise.success(retVal);
|
126
|
+
}
|
127
|
+
else {
|
128
|
+
promise.failure("Undefined or invalid user-supplied value.");
|
129
|
+
}
|
130
|
+
|
131
|
+
return promise;
|
88
132
|
}
|
89
133
|
}, true);
|
90
134
|
|
@@ -99,6 +143,7 @@ qq.FineUploader = function(o){
|
|
99
143
|
this._options.template = this._options.template.replace(/\{dropProcessingText\}/g, this._options.text.dropProcessing);
|
100
144
|
this._options.fileTemplate = this._options.fileTemplate.replace(/\{cancelButtonText\}/g, this._options.text.cancelButton);
|
101
145
|
this._options.fileTemplate = this._options.fileTemplate.replace(/\{retryButtonText\}/g, this._options.text.retryButton);
|
146
|
+
this._options.fileTemplate = this._options.fileTemplate.replace(/\{deleteButtonText\}/g, this._options.text.deleteButton);
|
102
147
|
this._options.fileTemplate = this._options.fileTemplate.replace(/\{statusText\}/g, "");
|
103
148
|
|
104
149
|
this._element = this._options.element;
|
@@ -114,6 +159,10 @@ qq.FineUploader = function(o){
|
|
114
159
|
this._bindCancelAndRetryEvents();
|
115
160
|
|
116
161
|
this._dnd = this._setupDragAndDrop();
|
162
|
+
|
163
|
+
if (this._options.paste.targetElement && this._options.paste.promptForName) {
|
164
|
+
this._setupPastePrompt();
|
165
|
+
}
|
117
166
|
};
|
118
167
|
|
119
168
|
// inherit from Basic Uploader
|
@@ -140,11 +189,6 @@ qq.extend(qq.FineUploader.prototype, {
|
|
140
189
|
item = item.nextSibling;
|
141
190
|
}
|
142
191
|
},
|
143
|
-
cancel: function(fileId) {
|
144
|
-
qq.FineUploaderBasic.prototype.cancel.apply(this, arguments);
|
145
|
-
var item = this.getItemByFileId(fileId);
|
146
|
-
qq(item).remove();
|
147
|
-
},
|
148
192
|
reset: function() {
|
149
193
|
qq.FineUploaderBasic.prototype.reset.apply(this, arguments);
|
150
194
|
this._element.innerHTML = this._options.template;
|
@@ -156,6 +200,10 @@ qq.extend(qq.FineUploader.prototype, {
|
|
156
200
|
this._dnd.dispose();
|
157
201
|
this._dnd = this._setupDragAndDrop();
|
158
202
|
},
|
203
|
+
_removeFileItem: function(fileId) {
|
204
|
+
var item = this.getItemByFileId(fileId);
|
205
|
+
qq(item).remove();
|
206
|
+
},
|
159
207
|
_setupDragAndDrop: function() {
|
160
208
|
var self = this,
|
161
209
|
dropProcessingEl = this._find(this._element, 'dropProcessing'),
|
@@ -195,7 +243,7 @@ qq.extend(qq.FineUploader.prototype, {
|
|
195
243
|
}
|
196
244
|
},
|
197
245
|
error: function(code, filename) {
|
198
|
-
self.
|
246
|
+
self._itemError(code, filename);
|
199
247
|
},
|
200
248
|
log: function(message, level) {
|
201
249
|
self.log(message, level);
|
@@ -211,8 +259,8 @@ qq.extend(qq.FineUploader.prototype, {
|
|
211
259
|
return ((qq.chrome() || (qq.safari() && qq.windows())) && e.clientX == 0 && e.clientY == 0) // null coords for Chrome and Safari Windows
|
212
260
|
|| (qq.firefox() && !e.relatedTarget); // null e.relatedTarget for Firefox
|
213
261
|
},
|
214
|
-
|
215
|
-
qq.FineUploaderBasic.prototype.
|
262
|
+
_storeForLater: function(id) {
|
263
|
+
qq.FineUploaderBasic.prototype._storeForLater.apply(this, arguments);
|
216
264
|
var item = this.getItemByFileId(id);
|
217
265
|
qq(this._find(item, 'spinner')).hide();
|
218
266
|
},
|
@@ -227,15 +275,15 @@ qq.extend(qq.FineUploader.prototype, {
|
|
227
275
|
|
228
276
|
return element;
|
229
277
|
},
|
230
|
-
_onSubmit: function(id,
|
278
|
+
_onSubmit: function(id, name){
|
231
279
|
qq.FineUploaderBasic.prototype._onSubmit.apply(this, arguments);
|
232
|
-
this._addToList(id,
|
280
|
+
this._addToList(id, name);
|
233
281
|
},
|
234
282
|
// Update the progress bar & percentage as the file is uploaded
|
235
|
-
_onProgress: function(id,
|
283
|
+
_onProgress: function(id, name, loaded, total){
|
236
284
|
qq.FineUploaderBasic.prototype._onProgress.apply(this, arguments);
|
237
285
|
|
238
|
-
var item, progressBar,
|
286
|
+
var item, progressBar, percent, cancelLink;
|
239
287
|
|
240
288
|
item = this.getItemByFileId(id);
|
241
289
|
progressBar = this._find(item, 'progressBar');
|
@@ -248,24 +296,20 @@ qq.extend(qq.FineUploader.prototype, {
|
|
248
296
|
qq(progressBar).hide();
|
249
297
|
qq(this._find(item, 'statusText')).setText(this._options.text.waitingForResponse);
|
250
298
|
|
251
|
-
// If last byte was sent,
|
252
|
-
|
299
|
+
// If last byte was sent, display total file size
|
300
|
+
this._displayFileSize(id);
|
253
301
|
}
|
254
302
|
else {
|
255
|
-
// If still uploading, display percentage
|
256
|
-
|
303
|
+
// If still uploading, display percentage - total size is actually the total request(s) size
|
304
|
+
this._displayFileSize(id, loaded, total);
|
257
305
|
|
258
306
|
qq(progressBar).css({display: 'block'});
|
259
307
|
}
|
260
308
|
|
261
309
|
// Update progress bar element
|
262
310
|
qq(progressBar).css({width: percent + '%'});
|
263
|
-
|
264
|
-
size = this._find(item, 'size');
|
265
|
-
qq(size).css({display: 'inline'});
|
266
|
-
qq(size).setText(text);
|
267
311
|
},
|
268
|
-
_onComplete: function(id,
|
312
|
+
_onComplete: function(id, name, result, xhr){
|
269
313
|
qq.FineUploaderBasic.prototype._onComplete.apply(this, arguments);
|
270
314
|
|
271
315
|
var item = this.getItemByFileId(id);
|
@@ -280,7 +324,11 @@ qq.extend(qq.FineUploader.prototype, {
|
|
280
324
|
}
|
281
325
|
qq(this._find(item, 'spinner')).hide();
|
282
326
|
|
283
|
-
if (result.success){
|
327
|
+
if (result.success) {
|
328
|
+
if (this._isDeletePossible()) {
|
329
|
+
this._showDeleteLink(id);
|
330
|
+
}
|
331
|
+
|
284
332
|
qq(item).addClass(this._classes.success);
|
285
333
|
if (this._classes.successIcon) {
|
286
334
|
this._find(item, 'finished').style.display = "inline-block";
|
@@ -298,14 +346,17 @@ qq.extend(qq.FineUploader.prototype, {
|
|
298
346
|
this._controlFailureTextDisplay(item, result);
|
299
347
|
}
|
300
348
|
},
|
301
|
-
_onUpload: function(id,
|
349
|
+
_onUpload: function(id, name){
|
302
350
|
qq.FineUploaderBasic.prototype._onUpload.apply(this, arguments);
|
303
351
|
|
304
|
-
|
305
|
-
|
352
|
+
this._showSpinner(id);
|
353
|
+
},
|
354
|
+
_onCancel: function(id, name) {
|
355
|
+
qq.FineUploaderBasic.prototype._onCancel.apply(this, arguments);
|
356
|
+
this._removeFileItem(id);
|
306
357
|
},
|
307
358
|
_onBeforeAutoRetry: function(id) {
|
308
|
-
var item, progressBar,
|
359
|
+
var item, progressBar, failTextEl, retryNumForDisplay, maxAuto, retryNote;
|
309
360
|
|
310
361
|
qq.FineUploaderBasic.prototype._onBeforeAutoRetry.apply(this, arguments);
|
311
362
|
|
@@ -332,17 +383,75 @@ qq.extend(qq.FineUploader.prototype, {
|
|
332
383
|
},
|
333
384
|
//return false if we should not attempt the requested retry
|
334
385
|
_onBeforeManualRetry: function(id) {
|
386
|
+
var item = this.getItemByFileId(id);
|
387
|
+
|
335
388
|
if (qq.FineUploaderBasic.prototype._onBeforeManualRetry.apply(this, arguments)) {
|
336
|
-
var item = this.getItemByFileId(id);
|
337
389
|
this._find(item, 'progressBar').style.width = 0;
|
338
390
|
qq(item).removeClass(this._classes.fail);
|
339
|
-
this.
|
391
|
+
qq(this._find(item, 'statusText')).clearText();
|
392
|
+
this._showSpinner(id);
|
340
393
|
this._showCancelLink(item);
|
341
394
|
return true;
|
342
395
|
}
|
343
|
-
|
396
|
+
else {
|
397
|
+
qq(item).addClass(this._classes.retryable);
|
398
|
+
return false;
|
399
|
+
}
|
400
|
+
},
|
401
|
+
_onSubmitDelete: function(id) {
|
402
|
+
if (this._isDeletePossible()) {
|
403
|
+
if (this._options.callbacks.onSubmitDelete(id) !== false) {
|
404
|
+
if (this._options.deleteFile.forceConfirm) {
|
405
|
+
this._showDeleteConfirm(id);
|
406
|
+
}
|
407
|
+
else {
|
408
|
+
this._sendDeleteRequest(id);
|
409
|
+
}
|
410
|
+
}
|
411
|
+
}
|
412
|
+
else {
|
413
|
+
this.log("Delete request ignored for file ID " + id + ", delete feature is disabled.", "warn");
|
414
|
+
return false;
|
415
|
+
}
|
344
416
|
},
|
345
|
-
|
417
|
+
_onDeleteComplete: function(id, xhr, isError) {
|
418
|
+
qq.FineUploaderBasic.prototype._onDeleteComplete.apply(this, arguments);
|
419
|
+
|
420
|
+
var item = this.getItemByFileId(id),
|
421
|
+
spinnerEl = this._find(item, 'spinner'),
|
422
|
+
statusTextEl = this._find(item, 'statusText');
|
423
|
+
|
424
|
+
qq(spinnerEl).hide();
|
425
|
+
|
426
|
+
if (isError) {
|
427
|
+
qq(statusTextEl).setText(this._options.deleteFile.deletingFailedText);
|
428
|
+
this._showDeleteLink(id);
|
429
|
+
}
|
430
|
+
else {
|
431
|
+
this._removeFileItem(id);
|
432
|
+
}
|
433
|
+
},
|
434
|
+
_sendDeleteRequest: function(id) {
|
435
|
+
var item = this.getItemByFileId(id),
|
436
|
+
deleteLink = this._find(item, 'deleteButton'),
|
437
|
+
statusTextEl = this._find(item, 'statusText');
|
438
|
+
|
439
|
+
qq(deleteLink).hide();
|
440
|
+
this._showSpinner(id);
|
441
|
+
qq(statusTextEl).setText(this._options.deleteFile.deletingStatusText);
|
442
|
+
this._deleteHandler.sendDelete(id, this.getUuid(id));
|
443
|
+
},
|
444
|
+
_showDeleteConfirm: function(id) {
|
445
|
+
var fileName = this._handler.getName(id),
|
446
|
+
confirmMessage = this._options.deleteFile.confirmMessage.replace(/\{filename\}/g, fileName),
|
447
|
+
uuid = this.getUuid(id),
|
448
|
+
self = this;
|
449
|
+
|
450
|
+
this._options.showConfirm(confirmMessage, function() {
|
451
|
+
self._sendDeleteRequest(id);
|
452
|
+
});
|
453
|
+
},
|
454
|
+
_addToList: function(id, name){
|
346
455
|
var item = qq.toElement(this._options.fileTemplate);
|
347
456
|
if (this._options.disableCancelForFormUploads && !qq.isXhrUploadSupported()) {
|
348
457
|
var cancelLink = this._find(item, 'cancel');
|
@@ -352,15 +461,36 @@ qq.extend(qq.FineUploader.prototype, {
|
|
352
461
|
item.qqFileId = id;
|
353
462
|
|
354
463
|
var fileElement = this._find(item, 'file');
|
355
|
-
qq(fileElement).setText(this.
|
464
|
+
qq(fileElement).setText(this._options.formatFileName(name));
|
356
465
|
qq(this._find(item, 'size')).hide();
|
357
|
-
if (!this._options.multiple)
|
466
|
+
if (!this._options.multiple) {
|
467
|
+
this._handler.cancelAll();
|
468
|
+
this._clearList();
|
469
|
+
}
|
470
|
+
|
358
471
|
this._listElement.appendChild(item);
|
472
|
+
|
473
|
+
if (this._options.display.fileSizeOnSubmit && qq.isXhrUploadSupported()) {
|
474
|
+
this._displayFileSize(id);
|
475
|
+
}
|
359
476
|
},
|
360
477
|
_clearList: function(){
|
361
478
|
this._listElement.innerHTML = '';
|
362
479
|
this.clearStoredFiles();
|
363
480
|
},
|
481
|
+
_displayFileSize: function(id, loadedSize, totalSize) {
|
482
|
+
var item = this.getItemByFileId(id),
|
483
|
+
size = this.getSize(id),
|
484
|
+
sizeForDisplay = this._formatSize(size),
|
485
|
+
sizeEl = this._find(item, 'size');
|
486
|
+
|
487
|
+
if (loadedSize !== undefined && totalSize !== undefined) {
|
488
|
+
sizeForDisplay = this._formatProgress(loadedSize, totalSize);
|
489
|
+
}
|
490
|
+
|
491
|
+
qq(sizeEl).css({display: 'inline'});
|
492
|
+
qq(sizeEl).setText(sizeForDisplay);
|
493
|
+
},
|
364
494
|
/**
|
365
495
|
* delegate click event for cancel & retry links
|
366
496
|
**/
|
@@ -372,15 +502,18 @@ qq.extend(qq.FineUploader.prototype, {
|
|
372
502
|
e = e || window.event;
|
373
503
|
var target = e.target || e.srcElement;
|
374
504
|
|
375
|
-
if (qq(target).hasClass(self._classes.cancel) || qq(target).hasClass(self._classes.retry)){
|
505
|
+
if (qq(target).hasClass(self._classes.cancel) || qq(target).hasClass(self._classes.retry) || qq(target).hasClass(self._classes.deleteButton)){
|
376
506
|
qq.preventDefault(e);
|
377
507
|
|
378
508
|
var item = target.parentNode;
|
379
|
-
while(item.qqFileId
|
509
|
+
while(item.qqFileId === undefined) {
|
380
510
|
item = target = target.parentNode;
|
381
511
|
}
|
382
512
|
|
383
|
-
if (qq(target).hasClass(self._classes.
|
513
|
+
if (qq(target).hasClass(self._classes.deleteButton)) {
|
514
|
+
self.deleteFile(item.qqFileId);
|
515
|
+
}
|
516
|
+
else if (qq(target).hasClass(self._classes.cancel)) {
|
384
517
|
self.cancel(item.qqFileId);
|
385
518
|
}
|
386
519
|
else {
|
@@ -430,22 +563,44 @@ qq.extend(qq.FineUploader.prototype, {
|
|
430
563
|
this.log("failedUploadTextDisplay.mode value of '" + mode + "' is not valid", 'warn');
|
431
564
|
}
|
432
565
|
},
|
433
|
-
//TODO turn this into a real tooltip, with click trigger (so it is usable on mobile devices). See case #355 for details.
|
434
566
|
_showTooltip: function(item, text) {
|
435
567
|
item.title = text;
|
436
568
|
},
|
437
|
-
_showSpinner: function(
|
438
|
-
var
|
569
|
+
_showSpinner: function(id) {
|
570
|
+
var item = this.getItemByFileId(id),
|
571
|
+
spinnerEl = this._find(item, 'spinner');
|
572
|
+
|
439
573
|
spinnerEl.style.display = "inline-block";
|
440
574
|
},
|
441
575
|
_showCancelLink: function(item) {
|
442
576
|
if (!this._options.disableCancelForFormUploads || qq.isXhrUploadSupported()) {
|
443
577
|
var cancelLink = this._find(item, 'cancel');
|
444
|
-
|
578
|
+
|
579
|
+
qq(cancelLink).css({display: 'inline'});
|
445
580
|
}
|
446
581
|
},
|
447
|
-
|
448
|
-
var
|
582
|
+
_showDeleteLink: function(id) {
|
583
|
+
var item = this.getItemByFileId(id),
|
584
|
+
deleteLink = this._find(item, 'deleteButton');
|
585
|
+
|
586
|
+
qq(deleteLink).css({display: 'inline'});
|
587
|
+
},
|
588
|
+
_itemError: function(code, name){
|
589
|
+
var message = qq.FineUploaderBasic.prototype._itemError.apply(this, arguments);
|
590
|
+
this._options.showMessage(message);
|
591
|
+
},
|
592
|
+
_batchError: function(message) {
|
593
|
+
qq.FineUploaderBasic.prototype._batchError.apply(this, arguments);
|
449
594
|
this._options.showMessage(message);
|
595
|
+
},
|
596
|
+
_setupPastePrompt: function() {
|
597
|
+
var self = this;
|
598
|
+
|
599
|
+
this._options.callbacks.onPasteReceived = function() {
|
600
|
+
var message = self._options.paste.namePromptMessage,
|
601
|
+
defaultVal = self._options.paste.defaultName;
|
602
|
+
|
603
|
+
return self._options.showPrompt(message, defaultVal);
|
604
|
+
};
|
450
605
|
}
|
451
606
|
});
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest*/
|
1
|
+
/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob*/
|
2
2
|
var qq = function(element) {
|
3
3
|
"use strict";
|
4
4
|
|
@@ -162,9 +162,22 @@ qq.isFunction = function(variable) {
|
|
162
162
|
return typeof(variable) === "function";
|
163
163
|
};
|
164
164
|
|
165
|
+
qq.isString = function(maybeString) {
|
166
|
+
"use strict";
|
167
|
+
return Object.prototype.toString.call(maybeString) === '[object String]';
|
168
|
+
};
|
169
|
+
|
170
|
+
qq.trimStr = function(string) {
|
171
|
+
if (String.prototype.trim) {
|
172
|
+
return string.trim();
|
173
|
+
}
|
174
|
+
|
175
|
+
return string.replace(/^\s+|\s+$/g,'');
|
176
|
+
};
|
177
|
+
|
165
178
|
qq.isFileOrInput = function(maybeFileOrInput) {
|
166
179
|
"use strict";
|
167
|
-
if (window.File && maybeFileOrInput instanceof File) {
|
180
|
+
if (qq.isBlob(maybeFileOrInput) && window.File && maybeFileOrInput instanceof File) {
|
168
181
|
return true;
|
169
182
|
}
|
170
183
|
else if (window.HTMLInputElement) {
|
@@ -185,6 +198,11 @@ qq.isFileOrInput = function(maybeFileOrInput) {
|
|
185
198
|
return false;
|
186
199
|
};
|
187
200
|
|
201
|
+
qq.isBlob = function(maybeBlob) {
|
202
|
+
"use strict";
|
203
|
+
return window.Blob && maybeBlob instanceof Blob;
|
204
|
+
};
|
205
|
+
|
188
206
|
qq.isXhrUploadSupported = function() {
|
189
207
|
"use strict";
|
190
208
|
var input = document.createElement('input');
|
@@ -202,6 +220,13 @@ qq.isFolderDropSupported = function(dataTransfer) {
|
|
202
220
|
return (dataTransfer.items && dataTransfer.items[0].webkitGetAsEntry);
|
203
221
|
};
|
204
222
|
|
223
|
+
qq.isFileChunkingSupported = function() {
|
224
|
+
"use strict";
|
225
|
+
return !qq.android() && //android's impl of Blob.slice is broken
|
226
|
+
qq.isXhrUploadSupported() &&
|
227
|
+
(File.prototype.slice || File.prototype.webkitSlice || File.prototype.mozSlice);
|
228
|
+
};
|
229
|
+
|
205
230
|
qq.extend = function (first, second, extendNested) {
|
206
231
|
"use strict";
|
207
232
|
qq.each(second, function(prop, val) {
|
@@ -235,7 +260,7 @@ qq.indexOf = function(arr, elt, from){
|
|
235
260
|
from += len;
|
236
261
|
}
|
237
262
|
|
238
|
-
for (
|
263
|
+
for (; from < len; from+=1){
|
239
264
|
if (arr.hasOwnProperty(from) && arr[from] === elt){
|
240
265
|
return from;
|
241
266
|
}
|
@@ -243,15 +268,16 @@ qq.indexOf = function(arr, elt, from){
|
|
243
268
|
return -1;
|
244
269
|
};
|
245
270
|
|
246
|
-
|
271
|
+
//this is a version 4 UUID
|
272
|
+
qq.getUniqueId = function(){
|
247
273
|
"use strict";
|
248
274
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
return
|
253
|
-
};
|
254
|
-
}
|
275
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
276
|
+
/*jslint eqeq: true, bitwise: true*/
|
277
|
+
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
278
|
+
return v.toString(16);
|
279
|
+
});
|
280
|
+
};
|
255
281
|
|
256
282
|
//
|
257
283
|
// Browsers and platforms detection
|
@@ -280,6 +306,10 @@ qq.windows = function(){
|
|
280
306
|
"use strict";
|
281
307
|
return navigator.platform === "Win32";
|
282
308
|
};
|
309
|
+
qq.android = function(){
|
310
|
+
"use strict";
|
311
|
+
return navigator.userAgent.toLowerCase().indexOf('android') !== -1;
|
312
|
+
};
|
283
313
|
|
284
314
|
//
|
285
315
|
// Events
|
@@ -342,6 +372,7 @@ qq.each = function(obj, callback) {
|
|
342
372
|
*/
|
343
373
|
qq.obj2url = function(obj, temp, prefixDone){
|
344
374
|
"use strict";
|
375
|
+
/*jshint laxbreak: true*/
|
345
376
|
var i, len,
|
346
377
|
uristrings = [],
|
347
378
|
prefix = '&',
|
@@ -404,10 +435,10 @@ qq.obj2FormData = function(obj, formData, arrayKeyName) {
|
|
404
435
|
qq.obj2FormData(val, formData, key);
|
405
436
|
}
|
406
437
|
else if (qq.isFunction(val)) {
|
407
|
-
formData.append(
|
438
|
+
formData.append(key, val());
|
408
439
|
}
|
409
440
|
else {
|
410
|
-
formData.append(
|
441
|
+
formData.append(key, val);
|
411
442
|
}
|
412
443
|
});
|
413
444
|
|
@@ -434,6 +465,80 @@ qq.obj2Inputs = function(obj, form) {
|
|
434
465
|
return form;
|
435
466
|
};
|
436
467
|
|
468
|
+
qq.setCookie = function(name, value, days) {
|
469
|
+
var date = new Date(),
|
470
|
+
expires = "";
|
471
|
+
|
472
|
+
if (days) {
|
473
|
+
date.setTime(date.getTime()+(days*24*60*60*1000));
|
474
|
+
expires = "; expires="+date.toGMTString();
|
475
|
+
}
|
476
|
+
|
477
|
+
document.cookie = name+"="+value+expires+"; path=/";
|
478
|
+
};
|
479
|
+
|
480
|
+
qq.getCookie = function(name) {
|
481
|
+
var nameEQ = name + "=",
|
482
|
+
ca = document.cookie.split(';'),
|
483
|
+
c;
|
484
|
+
|
485
|
+
for(var i=0;i < ca.length;i++) {
|
486
|
+
c = ca[i];
|
487
|
+
while (c.charAt(0)==' ') {
|
488
|
+
c = c.substring(1,c.length);
|
489
|
+
}
|
490
|
+
if (c.indexOf(nameEQ) === 0) {
|
491
|
+
return c.substring(nameEQ.length,c.length);
|
492
|
+
}
|
493
|
+
}
|
494
|
+
};
|
495
|
+
|
496
|
+
qq.getCookieNames = function(regexp) {
|
497
|
+
var cookies = document.cookie.split(';'),
|
498
|
+
cookieNames = [];
|
499
|
+
|
500
|
+
qq.each(cookies, function(idx, cookie) {
|
501
|
+
cookie = qq.trimStr(cookie);
|
502
|
+
|
503
|
+
var equalsIdx = cookie.indexOf("=");
|
504
|
+
|
505
|
+
if (cookie.match(regexp)) {
|
506
|
+
cookieNames.push(cookie.substr(0, equalsIdx));
|
507
|
+
}
|
508
|
+
});
|
509
|
+
|
510
|
+
return cookieNames;
|
511
|
+
};
|
512
|
+
|
513
|
+
qq.deleteCookie = function(name) {
|
514
|
+
qq.setCookie(name, "", -1);
|
515
|
+
};
|
516
|
+
|
517
|
+
qq.areCookiesEnabled = function() {
|
518
|
+
var randNum = Math.random() * 100000,
|
519
|
+
name = "qqCookieTest:" + randNum;
|
520
|
+
qq.setCookie(name, 1);
|
521
|
+
|
522
|
+
if (qq.getCookie(name)) {
|
523
|
+
qq.deleteCookie(name);
|
524
|
+
return true;
|
525
|
+
}
|
526
|
+
return false;
|
527
|
+
};
|
528
|
+
|
529
|
+
/**
|
530
|
+
* Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not
|
531
|
+
* implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.
|
532
|
+
*/
|
533
|
+
qq.parseJson = function(json) {
|
534
|
+
/*jshint evil: true*/
|
535
|
+
if (window.JSON && qq.isFunction(JSON.parse)) {
|
536
|
+
return JSON.parse(json);
|
537
|
+
} else {
|
538
|
+
return eval("(" + json + ")");
|
539
|
+
}
|
540
|
+
};
|
541
|
+
|
437
542
|
/**
|
438
543
|
* A generic module which supports object disposing in dispose() method.
|
439
544
|
* */
|
@@ -0,0 +1,32 @@
|
|
1
|
+
qq.WindowReceiveMessage = function(o) {
|
2
|
+
var options = {
|
3
|
+
log: function(message, level) {}
|
4
|
+
},
|
5
|
+
callbackWrapperDetachers = {};
|
6
|
+
|
7
|
+
qq.extend(options, o);
|
8
|
+
|
9
|
+
return {
|
10
|
+
receiveMessage : function(id, callback) {
|
11
|
+
var onMessageCallbackWrapper = function(event) {
|
12
|
+
callback(event.data);
|
13
|
+
};
|
14
|
+
|
15
|
+
if (window.postMessage) {
|
16
|
+
callbackWrapperDetachers[id] = qq(window).attach("message", onMessageCallbackWrapper);
|
17
|
+
}
|
18
|
+
else {
|
19
|
+
log("iframe message passing not supported in this browser!", "error");
|
20
|
+
}
|
21
|
+
},
|
22
|
+
|
23
|
+
stopReceivingMessages : function(id) {
|
24
|
+
if (window.postMessage) {
|
25
|
+
var detacher = callbackWrapperDetachers[id];
|
26
|
+
if (detacher) {
|
27
|
+
detacher();
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
};
|
32
|
+
};
|
@@ -8,3 +8,20 @@
|
|
8
8
|
//= require fine_uploader/dnd.js
|
9
9
|
//= require fine_uploader/uploader
|
10
10
|
//= require fine_uploader/jquery-plugin
|
11
|
+
//
|
12
|
+
file 'vendor/assets/javascripts/fine_uploader/ajax.requester.js', 'client/js/ajax.requester.js'
|
13
|
+
file 'vendor/assets/javascripts/fine_uploader/button.js', 'client/js/button.js'
|
14
|
+
file 'vendor/assets/javascripts/fine_uploader/deletefile.ajax.requester.js', 'client/js/deletefile.ajax.requester.js'
|
15
|
+
file 'vendor/assets/javascripts/fine_uploader/dnd.js', 'client/js/dnd.js'
|
16
|
+
file 'vendor/assets/javascripts/fine_uploader/handler.base.js', 'client/js/handler.base.js'
|
17
|
+
file 'vendor/assets/javascripts/fine_uploader/handler.form.js', 'client/js/handler.form.js'
|
18
|
+
file 'vendor/assets/javascripts/fine_uploader/handler.xhr.js', 'client/js/handler.xhr.js'
|
19
|
+
file 'vendor/assets/javascripts/fine_uploader/header.js', 'client/js/header.js'
|
20
|
+
file 'vendor/assets/javascripts/fine_uploader/iframe.xss.response.js', 'client/js/iframe.xss.response.js'
|
21
|
+
file 'vendor/assets/javascripts/fine_uploader/jquery-plugin.js', 'client/js/jquery-plugin.js'
|
22
|
+
file 'vendor/assets/javascripts/fine_uploader/paste.js', 'client/js/paste.js'
|
23
|
+
file 'vendor/assets/javascripts/fine_uploader/promise.js', 'client/js/promise.js'
|
24
|
+
file 'vendor/assets/javascripts/fine_uploader/uploader.basic.js', 'client/js/uploader.basic.js'
|
25
|
+
file 'vendor/assets/javascripts/fine_uploader/uploader.js', 'client/js/uploader.js'
|
26
|
+
file 'vendor/assets/javascripts/fine_uploader/util.js', 'client/js/util.js'
|
27
|
+
file 'vendor/assets/javascripts/fine_uploader/window.receive.message.js', 'client/js/window.receive.message.js'
|