fileuploader-rails 3.0.0 → 3.0.0.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.
@@ -1,168 +0,0 @@
1
- /**
2
- * Class for uploading files using xhr
3
- * @inherits qq.UploadHandlerAbstract
4
- */
5
- qq.UploadHandlerXhr = function(o){
6
- qq.UploadHandlerAbstract.apply(this, arguments);
7
-
8
- this._files = [];
9
- this._xhrs = [];
10
-
11
- // current loaded size in bytes for each file
12
- this._loaded = [];
13
- };
14
-
15
- // static method
16
- qq.UploadHandlerXhr.isSupported = function(){
17
- var input = document.createElement('input');
18
- input.type = 'file';
19
-
20
- return (
21
- 'multiple' in input &&
22
- typeof File != "undefined" &&
23
- typeof FormData != "undefined" &&
24
- typeof (new XMLHttpRequest()).upload != "undefined" );
25
- };
26
-
27
- // @inherits qq.UploadHandlerAbstract
28
- qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
29
-
30
- qq.extend(qq.UploadHandlerXhr.prototype, {
31
- /**
32
- * Adds file to the queue
33
- * Returns id to use with upload, cancel
34
- **/
35
- add: function(file){
36
- if (!(file instanceof File)){
37
- throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
38
- }
39
-
40
- return this._files.push(file) - 1;
41
- },
42
- getName: function(id){
43
- var file = this._files[id];
44
- // fix missing name in Safari 4
45
- //NOTE: fixed missing name firefox 11.0a2 file.fileName is actually undefined
46
- return (file.fileName !== null && file.fileName !== undefined) ? file.fileName : file.name;
47
- },
48
- getSize: function(id){
49
- var file = this._files[id];
50
- return file.fileSize != null ? file.fileSize : file.size;
51
- },
52
- /**
53
- * Returns uploaded bytes for file identified by id
54
- */
55
- getLoaded: function(id){
56
- return this._loaded[id] || 0;
57
- },
58
- isValid: function(id) {
59
- return this._files[id] !== undefined;
60
- },
61
- reset: function() {
62
- qq.UploadHandlerAbstract.prototype.reset.apply(this, arguments);
63
- this._files = [];
64
- this._xhrs = [];
65
- this._loaded = [];
66
- },
67
- /**
68
- * Sends the file identified by id and additional query params to the server
69
- * @param {Object} params name-value string pairs
70
- */
71
- _upload: function(id, params){
72
- this._options.onUpload(id, this.getName(id), true);
73
-
74
- var file = this._files[id],
75
- name = this.getName(id),
76
- size = this.getSize(id);
77
-
78
- this._loaded[id] = 0;
79
-
80
- var xhr = this._xhrs[id] = new XMLHttpRequest();
81
- var self = this;
82
-
83
- xhr.upload.onprogress = function(e){
84
- if (e.lengthComputable){
85
- self._loaded[id] = e.loaded;
86
- self._options.onProgress(id, name, e.loaded, e.total);
87
- }
88
- };
89
-
90
- xhr.onreadystatechange = function(){
91
- if (xhr.readyState == 4){
92
- self._onComplete(id, xhr);
93
- }
94
- };
95
-
96
- // build query string
97
- params = params || {};
98
- params[this._options.inputName] = name;
99
- var queryString = qq.obj2url(params, this._options.endpoint);
100
-
101
- var protocol = this._options.demoMode ? "GET" : "POST";
102
- xhr.open(protocol, queryString, true);
103
- xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
104
- xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
105
- xhr.setRequestHeader("Cache-Control", "no-cache");
106
- if (this._options.forceMultipart) {
107
- var formData = new FormData();
108
- formData.append(this._options.inputName, file);
109
- file = formData;
110
- } else {
111
- xhr.setRequestHeader("Content-Type", "application/octet-stream");
112
- //NOTE: return mime type in xhr works on chrome 16.0.9 firefox 11.0a2
113
- xhr.setRequestHeader("X-Mime-Type",file.type );
114
- }
115
- for (key in this._options.customHeaders){
116
- xhr.setRequestHeader(key, this._options.customHeaders[key]);
117
- };
118
-
119
- this.log('Sending upload request for ' + id);
120
- xhr.send(file);
121
- },
122
- _onComplete: function(id, xhr){
123
- "use strict";
124
- // the request was aborted/cancelled
125
- if (!this._files[id]) { return; }
126
-
127
- var name = this.getName(id);
128
- var size = this.getSize(id);
129
- var response; //the parsed JSON response from the server, or the empty object if parsing failed.
130
-
131
- this._options.onProgress(id, name, size, size);
132
-
133
- this.log("xhr - server response received for " + id);
134
- this.log("responseText = " + xhr.responseText);
135
-
136
- try {
137
- if (typeof JSON.parse === "function") {
138
- response = JSON.parse(xhr.responseText);
139
- } else {
140
- response = eval("(" + xhr.responseText + ")");
141
- }
142
- } catch(error){
143
- this.log('Error when attempting to parse xhr response text (' + error + ')', 'error');
144
- response = {};
145
- }
146
-
147
- if (xhr.status !== 200 || !response.success){
148
- if (this._options.onAutoRetry(id, name, response, xhr)) {
149
- return;
150
- }
151
- }
152
-
153
- this._options.onComplete(id, name, response, xhr);
154
-
155
- this._xhrs[id] = null;
156
- this._dequeue(id);
157
- },
158
- _cancel: function(id){
159
- this._options.onCancel(id, this.getName(id));
160
-
161
- this._files[id] = null;
162
-
163
- if (this._xhrs[id]){
164
- this._xhrs[id].abort();
165
- this._xhrs[id] = null;
166
- }
167
- }
168
- });
@@ -1,12 +0,0 @@
1
- /**
2
- * http://github.com/Valums-File-Uploader/file-uploader
3
- *
4
- * Multiple file upload component with progress-bar, drag-and-drop, support for all modern browsers.
5
- *
6
- * Original version: 1.0 © 2010 Andrew Valums ( andrew(at)valums.com )
7
- * Current Maintainer (2.0+): © 2012, Ray Nicholus ( fineuploader(at)garstasio.com )
8
- *
9
- * Licensed under MIT license, GNU GPL 2 or later, GNU LGPL 2 or later, see license.txt.
10
- */
11
-
12
- var qq = qq || {};
@@ -1,148 +0,0 @@
1
- (function($) {
2
- "use strict";
3
- var uploader, $el, init, dataStore, pluginOption, pluginOptions, addCallbacks, transformOptions, isValidCommand,
4
- delegateCommand;
5
-
6
- pluginOptions = ['uploaderType'];
7
-
8
- init = function (options) {
9
- if (options) {
10
- var xformedOpts = transformOptions(options);
11
- addCallbacks(xformedOpts);
12
-
13
- if (pluginOption('uploaderType') === 'basic') {
14
- uploader(new qq.FineUploaderBasic(xformedOpts));
15
- }
16
- else {
17
- uploader(new qq.FineUploader(xformedOpts));
18
- }
19
- }
20
-
21
- return $el;
22
- };
23
-
24
- dataStore = function(key, val) {
25
- var data = $el.data('fineuploader');
26
-
27
- if (val) {
28
- if (data === undefined) {
29
- data = {};
30
- }
31
- data[key] = val;
32
- $el.data('fineuploader', data);
33
- }
34
- else {
35
- if (data === undefined) {
36
- return null;
37
- }
38
- return data[key];
39
- }
40
- };
41
-
42
- //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element
43
- // tied to this instance of the plug-in
44
- uploader = function(instanceToStore) {
45
- return dataStore('uploader', instanceToStore);
46
- };
47
-
48
- pluginOption = function(option, optionVal) {
49
- return dataStore(option, optionVal);
50
- };
51
-
52
- //implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and
53
- // return the result of executing the bound handler back to Fine Uploader
54
- addCallbacks = function(transformedOpts) {
55
- var callbacks = transformedOpts.callbacks = {};
56
-
57
- $.each(new qq.FineUploaderBasic()._options.callbacks, function(prop, func) {
58
- var name, $callbackEl;
59
-
60
- name = /^on(\w+)/.exec(prop)[1];
61
- name = name.substring(0, 1).toLowerCase() + name.substring(1);
62
- $callbackEl = $el;
63
-
64
- callbacks[prop] = function() {
65
- var args = Array.prototype.slice.call(arguments);
66
- return $callbackEl.triggerHandler(name, args);
67
- };
68
- });
69
- };
70
-
71
- //transform jQuery objects into HTMLElements, and pass along all other option properties
72
- transformOptions = function(source, dest) {
73
- var xformed, arrayVals;
74
-
75
- if (dest === undefined) {
76
- if (source.uploaderType !== 'basic') {
77
- xformed = { element : $el[0] };
78
- }
79
- else {
80
- xformed = {};
81
- }
82
- }
83
- else {
84
- xformed = dest;
85
- }
86
-
87
- $.each(source, function(prop, val) {
88
- if ($.inArray(prop, pluginOptions) >= 0) {
89
- pluginOption(prop, val);
90
- }
91
- else if (val instanceof $) {
92
- xformed[prop] = val[0];
93
- }
94
- else if ($.isPlainObject(val)) {
95
- xformed[prop] = {};
96
- transformOptions(val, xformed[prop]);
97
- }
98
- else if ($.isArray(val)) {
99
- arrayVals = [];
100
- $.each(val, function(idx, arrayVal) {
101
- if (arrayVal instanceof $) {
102
- $.merge(arrayVals, arrayVal);
103
- }
104
- else {
105
- arrayVals.push(arrayVal);
106
- }
107
- });
108
- xformed[prop] = arrayVals;
109
- }
110
- else {
111
- xformed[prop] = val;
112
- }
113
- });
114
-
115
- if (dest === undefined) {
116
- return xformed;
117
- }
118
- };
119
-
120
- isValidCommand = function(command) {
121
- return $.type(command) === "string" &&
122
- !command.match(/^_/) && //enforce private methods convention
123
- uploader()[command] !== undefined;
124
- };
125
-
126
- //assuming we have already verified that this is a valid command, call the associated function in the underlying
127
- // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller
128
- delegateCommand = function(command) {
129
- return uploader()[command].apply(uploader(), Array.prototype.slice.call(arguments, 1));
130
- };
131
-
132
- $.fn.fineUploader = function(optionsOrCommand) {
133
- $el = this;
134
-
135
- if (uploader() && isValidCommand(optionsOrCommand)) {
136
- return delegateCommand.apply(this, arguments);
137
- }
138
- else if (typeof optionsOrCommand === 'object' || !optionsOrCommand) {
139
- return init.apply(this, arguments);
140
- }
141
- else {
142
- $.error('Method ' + optionsOrCommand + ' does not exist on jQuery.fineUploader');
143
- }
144
-
145
- return this;
146
- };
147
-
148
- }(jQuery));
@@ -1,483 +0,0 @@
1
- qq.FineUploaderBasic = function(o){
2
- var that = this;
3
- this._options = {
4
- debug: false,
5
- button: null,
6
- multiple: true,
7
- maxConnections: 3,
8
- disableCancelForFormUploads: false,
9
- autoUpload: true,
10
- request: {
11
- endpoint: '/server/upload',
12
- params: {},
13
- customHeaders: {},
14
- forceMultipart: false,
15
- inputName: 'qqfile'
16
- },
17
- validation: {
18
- allowedExtensions: [],
19
- sizeLimit: 0,
20
- minSizeLimit: 0,
21
- stopOnFirstInvalidFile: true
22
- },
23
- callbacks: {
24
- onSubmit: function(id, fileName){}, // return false to cancel submit
25
- onComplete: function(id, fileName, responseJSON){},
26
- onCancel: function(id, fileName){},
27
- onUpload: function(id, fileName, xhr){},
28
- onProgress: function(id, fileName, loaded, total){},
29
- onError: function(id, fileName, reason) {},
30
- onAutoRetry: function(id, fileName, attemptNumber) {},
31
- onManualRetry: function(id, fileName) {},
32
- onValidate: function(fileData) {} // return false to prevent upload
33
- },
34
- messages: {
35
- typeError: "{file} has an invalid extension. Valid extension(s): {extensions}.",
36
- sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
37
- minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
38
- emptyError: "{file} is empty, please select files again without it.",
39
- noFilesError: "No files to upload.",
40
- onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."
41
- },
42
- retry: {
43
- enableAuto: false,
44
- maxAutoAttempts: 3,
45
- autoAttemptDelay: 5,
46
- preventRetryResponseProperty: 'preventRetry'
47
- }
48
- };
49
-
50
- qq.extend(this._options, o, true);
51
- this._wrapCallbacks();
52
- qq.extend(this, qq.DisposeSupport);
53
-
54
- // number of files being uploaded
55
- this._filesInProgress = 0;
56
-
57
- this._storedFileIds = [];
58
-
59
- this._autoRetries = [];
60
- this._retryTimeouts = [];
61
- this._preventRetries = [];
62
-
63
- this._handler = this._createUploadHandler();
64
-
65
- if (this._options.button){
66
- this._button = this._createUploadButton(this._options.button);
67
- }
68
-
69
- this._preventLeaveInProgress();
70
- };
71
-
72
- qq.FineUploaderBasic.prototype = {
73
- log: function(str, level) {
74
- if (this._options.debug && (!level || level === 'info')) {
75
- qq.log('[FineUploader] ' + str);
76
- }
77
- else if (level && level !== 'info') {
78
- qq.log('[FineUploader] ' + str, level);
79
-
80
- }
81
- },
82
- setParams: function(params){
83
- this._options.request.params = params;
84
- },
85
- getInProgress: function(){
86
- return this._filesInProgress;
87
- },
88
- uploadStoredFiles: function(){
89
- "use strict";
90
- while(this._storedFileIds.length) {
91
- this._filesInProgress++;
92
- this._handler.upload(this._storedFileIds.shift(), this._options.request.params);
93
- }
94
- },
95
- clearStoredFiles: function(){
96
- this._storedFileIds = [];
97
- },
98
- retry: function(id) {
99
- if (this._onBeforeManualRetry(id)) {
100
- this._handler.retry(id);
101
- return true;
102
- }
103
- else {
104
- return false;
105
- }
106
- },
107
- cancel: function(fileId) {
108
- this._handler.cancel(fileId);
109
- },
110
- reset: function() {
111
- this.log("Resetting uploader...");
112
- this._handler.reset();
113
- this._filesInProgress = 0;
114
- this._storedFileIds = [];
115
- this._autoRetries = [];
116
- this._retryTimeouts = [];
117
- this._preventRetries = [];
118
- this._button.reset();
119
- },
120
- _createUploadButton: function(element){
121
- var self = this;
122
-
123
- var button = new qq.UploadButton({
124
- element: element,
125
- multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
126
- acceptFiles: this._options.validation.acceptFiles,
127
- onChange: function(input){
128
- self._onInputChange(input);
129
- }
130
- });
131
-
132
- this.addDisposer(function() { button.dispose(); });
133
- return button;
134
- },
135
- _createUploadHandler: function(){
136
- var self = this,
137
- handlerClass;
138
-
139
- if(qq.UploadHandlerXhr.isSupported()){
140
- handlerClass = 'UploadHandlerXhr';
141
- } else {
142
- handlerClass = 'UploadHandlerForm';
143
- }
144
-
145
- var handler = new qq[handlerClass]({
146
- debug: this._options.debug,
147
- endpoint: this._options.request.endpoint,
148
- forceMultipart: this._options.request.forceMultipart,
149
- maxConnections: this._options.maxConnections,
150
- customHeaders: this._options.request.customHeaders,
151
- inputName: this._options.request.inputName,
152
- demoMode: this._options.demoMode,
153
- log: this.log,
154
- onProgress: function(id, fileName, loaded, total){
155
- self._onProgress(id, fileName, loaded, total);
156
- self._options.callbacks.onProgress(id, fileName, loaded, total);
157
- },
158
- onComplete: function(id, fileName, result, xhr){
159
- self._onComplete(id, fileName, result, xhr);
160
- self._options.callbacks.onComplete(id, fileName, result);
161
- },
162
- onCancel: function(id, fileName){
163
- self._onCancel(id, fileName);
164
- self._options.callbacks.onCancel(id, fileName);
165
- },
166
- onUpload: function(id, fileName, xhr){
167
- self._onUpload(id, fileName, xhr);
168
- self._options.callbacks.onUpload(id, fileName, xhr);
169
- },
170
- onAutoRetry: function(id, fileName, responseJSON, xhr) {
171
- self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty];
172
-
173
- if (self._shouldAutoRetry(id, fileName, responseJSON)) {
174
- self._maybeParseAndSendUploadError(id, fileName, responseJSON, xhr);
175
- self._options.callbacks.onAutoRetry(id, fileName, self._autoRetries[id] + 1);
176
- self._onBeforeAutoRetry(id, fileName);
177
-
178
- self._retryTimeouts[id] = setTimeout(function() {
179
- self._onAutoRetry(id, fileName, responseJSON)
180
- }, self._options.retry.autoAttemptDelay * 1000);
181
-
182
- return true;
183
- }
184
- else {
185
- return false;
186
- }
187
- }
188
- });
189
-
190
- return handler;
191
- },
192
- _preventLeaveInProgress: function(){
193
- var self = this;
194
-
195
- this._attach(window, 'beforeunload', function(e){
196
- if (!self._filesInProgress){return;}
197
-
198
- var e = e || window.event;
199
- // for ie, ff
200
- e.returnValue = self._options.messages.onLeave;
201
- // for webkit
202
- return self._options.messages.onLeave;
203
- });
204
- },
205
- _onSubmit: function(id, fileName){
206
- if (this._options.autoUpload) {
207
- this._filesInProgress++;
208
- }
209
- },
210
- _onProgress: function(id, fileName, loaded, total){
211
- },
212
- _onComplete: function(id, fileName, result, xhr){
213
- this._filesInProgress--;
214
- this._maybeParseAndSendUploadError(id, fileName, result, xhr);
215
- },
216
- _onCancel: function(id, fileName){
217
- clearTimeout(this._retryTimeouts[id]);
218
-
219
- var storedFileIndex = qq.indexOf(this._storedFileIds, id);
220
- if (this._options.autoUpload || storedFileIndex < 0) {
221
- this._filesInProgress--;
222
- }
223
- else if (!this._options.autoUpload) {
224
- this._storedFileIds.splice(storedFileIndex, 1);
225
- }
226
- },
227
- _onUpload: function(id, fileName, xhr){
228
- },
229
- _onInputChange: function(input){
230
- if (this._handler instanceof qq.UploadHandlerXhr){
231
- this._uploadFileList(input.files);
232
- } else {
233
- if (this._validateFile(input)){
234
- this._uploadFile(input);
235
- }
236
- }
237
- this._button.reset();
238
- },
239
- _onBeforeAutoRetry: function(id, fileName) {
240
- this.log("Waiting " + this._options.retry.autoAttemptDelay + " seconds before retrying " + fileName + "...");
241
- },
242
- _onAutoRetry: function(id, fileName, responseJSON) {
243
- this.log("Retrying " + fileName + "...");
244
- this._autoRetries[id]++;
245
- this._handler.retry(id);
246
- },
247
- _shouldAutoRetry: function(id, fileName, responseJSON) {
248
- if (!this._preventRetries[id] && this._options.retry.enableAuto) {
249
- if (this._autoRetries[id] === undefined) {
250
- this._autoRetries[id] = 0;
251
- }
252
-
253
- return this._autoRetries[id] < this._options.retry.maxAutoAttempts
254
- }
255
-
256
- return false;
257
- },
258
- //return false if we should not attempt the requested retry
259
- _onBeforeManualRetry: function(id) {
260
- if (this._preventRetries[id]) {
261
- this.log("Retries are forbidden for id " + id, 'warn');
262
- return false;
263
- }
264
- else if (this._handler.isValid(id)) {
265
- var fileName = this._handler.getName(id);
266
-
267
- if (this._options.callbacks.onManualRetry(id, fileName) === false) {
268
- return false;
269
- }
270
-
271
- this.log("Retrying upload for '" + fileName + "' (id: " + id + ")...");
272
- this._filesInProgress++;
273
- return true;
274
- }
275
- else {
276
- this.log("'" + id + "' is not a valid file ID", 'error');
277
- return false;
278
- }
279
- },
280
- _maybeParseAndSendUploadError: function(id, fileName, response, xhr) {
281
- //assuming no one will actually set the response code to something other than 200 and still set 'success' to true
282
- if (!response.success){
283
- if (xhr && xhr.status !== 200 && !response.error) {
284
- this._options.callbacks.onError(id, fileName, "XHR returned response code " + xhr.status);
285
- }
286
- else {
287
- var errorReason = response.error ? response.error : "Upload failure reason unknown";
288
- this._options.callbacks.onError(id, fileName, errorReason);
289
- }
290
- }
291
- },
292
- _uploadFileList: function(files){
293
- var validationDescriptors, index, batchInvalid;
294
-
295
- validationDescriptors = this._getValidationDescriptors(files);
296
- if (validationDescriptors.length > 1) {
297
- batchInvalid = this._options.callbacks.onValidate(validationDescriptors) === false;
298
- }
299
-
300
- if (!batchInvalid) {
301
- if (files.length > 0) {
302
- for (index = 0; index < files.length; index++){
303
- if (this._validateFile(files[index])){
304
- this._uploadFile(files[index]);
305
- } else {
306
- if (this._options.validation.stopOnFirstInvalidFile){
307
- return;
308
- }
309
- }
310
- }
311
- }
312
- else {
313
- this._error('noFilesError', "");
314
- }
315
- }
316
- },
317
- _uploadFile: function(fileContainer){
318
- var id = this._handler.add(fileContainer);
319
- var fileName = this._handler.getName(id);
320
-
321
- if (this._options.callbacks.onSubmit(id, fileName) !== false){
322
- this._onSubmit(id, fileName);
323
- if (this._options.autoUpload) {
324
- this._handler.upload(id, this._options.request.params);
325
- }
326
- else {
327
- this._storeFileForLater(id);
328
- }
329
- }
330
- },
331
- _storeFileForLater: function(id) {
332
- this._storedFileIds.push(id);
333
- },
334
- _validateFile: function(file){
335
- var validationDescriptor, name, size;
336
-
337
- validationDescriptor = this._getValidationDescriptor(file);
338
- name = validationDescriptor.name;
339
- size = validationDescriptor.size;
340
-
341
- if (this._options.callbacks.onValidate([validationDescriptor]) === false) {
342
- return false;
343
- }
344
-
345
- if (!this._isAllowedExtension(name)){
346
- this._error('typeError', name);
347
- return false;
348
-
349
- }
350
- else if (size === 0){
351
- this._error('emptyError', name);
352
- return false;
353
-
354
- }
355
- else if (size && this._options.validation.sizeLimit && size > this._options.validation.sizeLimit){
356
- this._error('sizeError', name);
357
- return false;
358
-
359
- }
360
- else if (size && size < this._options.validation.minSizeLimit){
361
- this._error('minSizeError', name);
362
- return false;
363
- }
364
-
365
- return true;
366
- },
367
- _error: function(code, fileName){
368
- var message = this._options.messages[code];
369
- function r(name, replacement){ message = message.replace(name, replacement); }
370
-
371
- var extensions = this._options.validation.allowedExtensions.join(', ');
372
-
373
- r('{file}', this._formatFileName(fileName));
374
- r('{extensions}', extensions);
375
- r('{sizeLimit}', this._formatSize(this._options.validation.sizeLimit));
376
- r('{minSizeLimit}', this._formatSize(this._options.validation.minSizeLimit));
377
-
378
- this._options.callbacks.onError(null, fileName, message);
379
-
380
- return message;
381
- },
382
- _formatFileName: function(name){
383
- if (name.length > 33){
384
- name = name.slice(0, 19) + '...' + name.slice(-13);
385
- }
386
- return name;
387
- },
388
- _isAllowedExtension: function(fileName){
389
- var ext = (-1 !== fileName.indexOf('.'))
390
- ? fileName.replace(/.*[.]/, '').toLowerCase()
391
- : '';
392
- var allowed = this._options.validation.allowedExtensions;
393
-
394
- if (!allowed.length){return true;}
395
-
396
- for (var i=0; i<allowed.length; i++){
397
- if (allowed[i].toLowerCase() == ext){ return true;}
398
- }
399
-
400
- return false;
401
- },
402
- _formatSize: function(bytes){
403
- var i = -1;
404
- do {
405
- bytes = bytes / 1024;
406
- i++;
407
- } while (bytes > 99);
408
-
409
- return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
410
- },
411
- _wrapCallbacks: function() {
412
- var self, safeCallback;
413
-
414
- self = this;
415
-
416
- safeCallback = function(name, callback, args) {
417
- try {
418
- return callback.apply(self, args);
419
- }
420
- catch (exception) {
421
- self.log("Caught exception in '" + name + "' callback - " + exception, 'error');
422
- }
423
- }
424
-
425
- for (var prop in this._options.callbacks) {
426
- (function() {
427
- var oldCallback = self._options.callbacks[prop];
428
- self._options.callbacks[prop] = function() {
429
- return safeCallback(prop, oldCallback, arguments);
430
- }
431
- }());
432
- }
433
- },
434
- _parseFileName: function(file) {
435
- var name;
436
-
437
- if (file.value){
438
- // it is a file input
439
- // get input value and remove path to normalize
440
- name = file.value.replace(/.*(\/|\\)/, "");
441
- } else {
442
- // fix missing properties in Safari 4 and firefox 11.0a2
443
- name = (file.fileName !== null && file.fileName !== undefined) ? file.fileName : file.name;
444
- }
445
-
446
- return name;
447
- },
448
- _parseFileSize: function(file) {
449
- var size;
450
-
451
- if (!file.value){
452
- // fix missing properties in Safari 4 and firefox 11.0a2
453
- size = (file.fileSize !== null && file.fileSize !== undefined) ? file.fileSize : file.size;
454
- }
455
-
456
- return size;
457
- },
458
- _getValidationDescriptor: function(file) {
459
- var name, size, fileDescriptor;
460
-
461
- fileDescriptor = {};
462
- name = this._parseFileName(file);
463
- size = this._parseFileSize(file);
464
-
465
- fileDescriptor.name = name;
466
- if (size) {
467
- fileDescriptor.size = size;
468
- }
469
-
470
- return fileDescriptor;
471
- },
472
- _getValidationDescriptors: function(files) {
473
- var index, fileDescriptors;
474
-
475
- fileDescriptors = [];
476
-
477
- for (index = 0; index < files.length; index++) {
478
- fileDescriptors.push(files[index]);
479
- }
480
-
481
- return fileDescriptors;
482
- }
483
- };