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.
@@ -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'