fine_uploader 3.1.1 → 3.4.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/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'
|