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.
@@ -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
- alert(message);
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._error(code, filename);
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
- _storeFileForLater: function(id) {
215
- qq.FineUploaderBasic.prototype._storeFileForLater.apply(this, arguments);
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, fileName){
278
+ _onSubmit: function(id, name){
231
279
  qq.FineUploaderBasic.prototype._onSubmit.apply(this, arguments);
232
- this._addToList(id, fileName);
280
+ this._addToList(id, name);
233
281
  },
234
282
  // Update the progress bar & percentage as the file is uploaded
235
- _onProgress: function(id, fileName, loaded, total){
283
+ _onProgress: function(id, name, loaded, total){
236
284
  qq.FineUploaderBasic.prototype._onProgress.apply(this, arguments);
237
285
 
238
- var item, progressBar, text, percent, cancelLink, size;
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, just display final size
252
- text = this._formatSize(total);
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
- text = this._formatProgress(loaded, total);
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, fileName, result, xhr){
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, fileName, xhr){
349
+ _onUpload: function(id, name){
302
350
  qq.FineUploaderBasic.prototype._onUpload.apply(this, arguments);
303
351
 
304
- var item = this.getItemByFileId(id);
305
- this._showSpinner(item);
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, cancelLink, failTextEl, retryNumForDisplay, maxAuto, retryNote;
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._showSpinner(item);
391
+ qq(this._find(item, 'statusText')).clearText();
392
+ this._showSpinner(id);
340
393
  this._showCancelLink(item);
341
394
  return true;
342
395
  }
343
- return false;
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
- _addToList: function(id, fileName){
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._formatFileName(fileName));
464
+ qq(fileElement).setText(this._options.formatFileName(name));
356
465
  qq(this._find(item, 'size')).hide();
357
- if (!this._options.multiple) this._clearList();
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 == undefined) {
509
+ while(item.qqFileId === undefined) {
380
510
  item = target = target.parentNode;
381
511
  }
382
512
 
383
- if (qq(target).hasClass(self._classes.cancel)) {
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(item) {
438
- var spinnerEl = this._find(item, 'spinner');
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
- cancelLink.style.display = 'inline';
578
+
579
+ qq(cancelLink).css({display: 'inline'});
445
580
  }
446
581
  },
447
- _error: function(code, fileName){
448
- var message = qq.FineUploaderBasic.prototype._error.apply(this, arguments);
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 (null; from < len; from+=1){
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
- qq.getUniqueId = (function(){
271
+ //this is a version 4 UUID
272
+ qq.getUniqueId = function(){
247
273
  "use strict";
248
274
 
249
- var id = -1;
250
- return function(){
251
- id += 1;
252
- return id;
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(encodeURIComponent(key), encodeURIComponent(val()));
438
+ formData.append(key, val());
408
439
  }
409
440
  else {
410
- formData.append(encodeURIComponent(key), encodeURIComponent(val));
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'