fine_uploader 2.1.1 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -3
- data/Vendorfile +17 -5
- data/lib/fine_uploader/version.rb +1 -1
- data/vendor/assets/images/{loading.gif → fine_uploader/loading.gif} +0 -0
- data/vendor/assets/images/fine_uploader/processing.gif +0 -0
- data/vendor/assets/javascripts/fine_uploader/button.js +102 -0
- data/vendor/assets/javascripts/fine_uploader/dnd.js +355 -0
- data/vendor/assets/javascripts/fine_uploader/handler.base.js +115 -0
- data/vendor/assets/javascripts/fine_uploader/handler.form.js +202 -0
- data/vendor/assets/javascripts/fine_uploader/handler.xhr.js +168 -0
- data/vendor/assets/javascripts/fine_uploader/header.js +10 -0
- data/vendor/assets/javascripts/fine_uploader/jquery-plugin.js +168 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.basic.js +558 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.js +451 -0
- data/vendor/assets/javascripts/fine_uploader/util.js +469 -0
- data/vendor/assets/javascripts/fine_uploader.js +10 -1634
- data/vendor/assets/stylesheets/fine_uploader.css.scss +27 -5
- metadata +14 -3
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# Fine Uploader
|
2
2
|
|
3
|
-
|
3
|
+
Fine Uploader is a project attempts to achieve a user-friendly file-uploading experience over the web. It's built as a Javascript plugin for developers looking to incorporate file-uploading into their website.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,7 +18,13 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
Add `application.js`
|
22
|
+
|
23
|
+
//= require fine_uploader
|
24
|
+
|
25
|
+
and `application.css`
|
26
|
+
|
27
|
+
/*= require fine_uploader
|
22
28
|
|
23
29
|
## Contributing
|
24
30
|
|
data/Vendorfile
CHANGED
@@ -1,9 +1,21 @@
|
|
1
|
-
from 'git://github.com/valums/file-uploader.git',
|
2
|
-
file 'vendor/assets/images/loading.gif', 'client/loading.gif'
|
3
|
-
file 'vendor/assets/
|
4
|
-
file 'vendor/assets/
|
1
|
+
from 'git://github.com/valums/file-uploader.git', ref: 'be738538a57633e355529ec13c63a7b2493b7ec8' do
|
2
|
+
file 'vendor/assets/images/fine_uploader/loading.gif', 'client/loading.gif'
|
3
|
+
file 'vendor/assets/images/fine_uploader/processing.gif', 'client/processing.gif'
|
4
|
+
file 'vendor/assets/javascripts/fine_uploader/header.js', 'client/js/header.js'
|
5
|
+
file 'vendor/assets/javascripts/fine_uploader/util.js', 'client/js/util.js'
|
6
|
+
file 'vendor/assets/javascripts/fine_uploader/button.js', 'client/js/button.js'
|
7
|
+
file 'vendor/assets/javascripts/fine_uploader/handler.base.js', 'client/js/handler.base.js'
|
8
|
+
file 'vendor/assets/javascripts/fine_uploader/handler.form.js', 'client/js/handler.form.js'
|
9
|
+
file 'vendor/assets/javascripts/fine_uploader/handler.xhr.js', 'client/js/handler.xhr.js'
|
10
|
+
file 'vendor/assets/javascripts/fine_uploader/uploader.basic.js', 'client/js/uploader.basic.js'
|
11
|
+
file 'vendor/assets/javascripts/fine_uploader/dnd.js', 'client/js/dnd.js'
|
12
|
+
file 'vendor/assets/javascripts/fine_uploader/uploader.js', 'client/js/uploader.js'
|
13
|
+
file 'vendor/assets/javascripts/fine_uploader/jquery-plugin.js', 'client/js/jquery-plugin.js'
|
14
|
+
file 'vendor/assets/stylesheets/fine_uploader.css.scss', 'client/fineuploader.css' do |path|
|
5
15
|
rewrite(path) do |content|
|
6
|
-
content.gsub('url', 'image-url')
|
16
|
+
content.gsub!('url', 'image-url')
|
17
|
+
content.gsub!('loading.gif', 'fine_uploader/loading.gif')
|
18
|
+
content.gsub!('processing.gif', 'fine_uploader/processing.gif')
|
7
19
|
end
|
8
20
|
end
|
9
21
|
end
|
File without changes
|
Binary file
|
@@ -0,0 +1,102 @@
|
|
1
|
+
qq.UploadButton = function(o){
|
2
|
+
this._options = {
|
3
|
+
element: null,
|
4
|
+
// if set to true adds multiple attribute to file input
|
5
|
+
multiple: false,
|
6
|
+
acceptFiles: null,
|
7
|
+
// name attribute of file input
|
8
|
+
name: 'file',
|
9
|
+
onChange: function(input){},
|
10
|
+
hoverClass: 'qq-upload-button-hover',
|
11
|
+
focusClass: 'qq-upload-button-focus'
|
12
|
+
};
|
13
|
+
|
14
|
+
qq.extend(this._options, o);
|
15
|
+
this._disposeSupport = new qq.DisposeSupport();
|
16
|
+
|
17
|
+
this._element = this._options.element;
|
18
|
+
|
19
|
+
// make button suitable container for input
|
20
|
+
qq(this._element).css({
|
21
|
+
position: 'relative',
|
22
|
+
overflow: 'hidden',
|
23
|
+
// Make sure browse button is in the right side
|
24
|
+
// in Internet Explorer
|
25
|
+
direction: 'ltr'
|
26
|
+
});
|
27
|
+
|
28
|
+
this._input = this._createInput();
|
29
|
+
};
|
30
|
+
|
31
|
+
qq.UploadButton.prototype = {
|
32
|
+
/* returns file input element */
|
33
|
+
getInput: function(){
|
34
|
+
return this._input;
|
35
|
+
},
|
36
|
+
/* cleans/recreates the file input */
|
37
|
+
reset: function(){
|
38
|
+
if (this._input.parentNode){
|
39
|
+
qq(this._input).remove();
|
40
|
+
}
|
41
|
+
|
42
|
+
qq(this._element).removeClass(this._options.focusClass);
|
43
|
+
this._input = this._createInput();
|
44
|
+
},
|
45
|
+
_createInput: function(){
|
46
|
+
var input = document.createElement("input");
|
47
|
+
|
48
|
+
if (this._options.multiple){
|
49
|
+
input.setAttribute("multiple", "multiple");
|
50
|
+
}
|
51
|
+
|
52
|
+
if (this._options.acceptFiles) input.setAttribute("accept", this._options.acceptFiles);
|
53
|
+
|
54
|
+
input.setAttribute("type", "file");
|
55
|
+
input.setAttribute("name", this._options.name);
|
56
|
+
|
57
|
+
qq(input).css({
|
58
|
+
position: 'absolute',
|
59
|
+
// in Opera only 'browse' button
|
60
|
+
// is clickable and it is located at
|
61
|
+
// the right side of the input
|
62
|
+
right: 0,
|
63
|
+
top: 0,
|
64
|
+
fontFamily: 'Arial',
|
65
|
+
// 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
|
66
|
+
fontSize: '118px',
|
67
|
+
margin: 0,
|
68
|
+
padding: 0,
|
69
|
+
cursor: 'pointer',
|
70
|
+
opacity: 0
|
71
|
+
});
|
72
|
+
|
73
|
+
this._element.appendChild(input);
|
74
|
+
|
75
|
+
var self = this;
|
76
|
+
this._disposeSupport.attach(input, 'change', function(){
|
77
|
+
self._options.onChange(input);
|
78
|
+
});
|
79
|
+
|
80
|
+
this._disposeSupport.attach(input, 'mouseover', function(){
|
81
|
+
qq(self._element).addClass(self._options.hoverClass);
|
82
|
+
});
|
83
|
+
this._disposeSupport.attach(input, 'mouseout', function(){
|
84
|
+
qq(self._element).removeClass(self._options.hoverClass);
|
85
|
+
});
|
86
|
+
this._disposeSupport.attach(input, 'focus', function(){
|
87
|
+
qq(self._element).addClass(self._options.focusClass);
|
88
|
+
});
|
89
|
+
this._disposeSupport.attach(input, 'blur', function(){
|
90
|
+
qq(self._element).removeClass(self._options.focusClass);
|
91
|
+
});
|
92
|
+
|
93
|
+
// IE and Opera, unfortunately have 2 tab stops on file input
|
94
|
+
// which is unacceptable in our case, disable keyboard access
|
95
|
+
if (window.attachEvent){
|
96
|
+
// it is IE or Opera
|
97
|
+
input.setAttribute('tabIndex', "-1");
|
98
|
+
}
|
99
|
+
|
100
|
+
return input;
|
101
|
+
}
|
102
|
+
};
|
@@ -0,0 +1,355 @@
|
|
1
|
+
/*globals qq, document*/
|
2
|
+
qq.DragAndDrop = function(o) {
|
3
|
+
"use strict";
|
4
|
+
|
5
|
+
var options, dz, dirPending,
|
6
|
+
droppedFiles = [],
|
7
|
+
droppedEntriesCount = 0,
|
8
|
+
droppedEntriesParsedCount = 0,
|
9
|
+
disposeSupport = new qq.DisposeSupport();
|
10
|
+
|
11
|
+
options = {
|
12
|
+
dropArea: null,
|
13
|
+
extraDropzones: [],
|
14
|
+
hideDropzones: true,
|
15
|
+
multiple: true,
|
16
|
+
classes: {
|
17
|
+
dropActive: null
|
18
|
+
},
|
19
|
+
callbacks: {
|
20
|
+
dropProcessing: function(isProcessing, files) {},
|
21
|
+
error: function(code, filename) {},
|
22
|
+
log: function(message, level) {}
|
23
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
qq.extend(options, o);
|
27
|
+
|
28
|
+
function maybeUploadDroppedFiles() {
|
29
|
+
if (droppedEntriesCount === droppedEntriesParsedCount && !dirPending) {
|
30
|
+
options.callbacks.log('Grabbed ' + droppedFiles.length + " files after tree traversal.");
|
31
|
+
dz.dropDisabled(false);
|
32
|
+
options.callbacks.dropProcessing(false, droppedFiles);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
function addDroppedFile(file) {
|
36
|
+
droppedFiles.push(file);
|
37
|
+
droppedEntriesParsedCount+=1;
|
38
|
+
maybeUploadDroppedFiles();
|
39
|
+
}
|
40
|
+
|
41
|
+
function traverseFileTree(entry) {
|
42
|
+
var dirReader, i;
|
43
|
+
|
44
|
+
droppedEntriesCount+=1;
|
45
|
+
|
46
|
+
if (entry.isFile) {
|
47
|
+
entry.file(function(file) {
|
48
|
+
addDroppedFile(file);
|
49
|
+
});
|
50
|
+
}
|
51
|
+
else if (entry.isDirectory) {
|
52
|
+
dirPending = true;
|
53
|
+
dirReader = entry.createReader();
|
54
|
+
dirReader.readEntries(function(entries) {
|
55
|
+
droppedEntriesParsedCount+=1;
|
56
|
+
for (i = 0; i < entries.length; i+=1) {
|
57
|
+
traverseFileTree(entries[i]);
|
58
|
+
}
|
59
|
+
|
60
|
+
dirPending = false;
|
61
|
+
|
62
|
+
if (!entries.length) {
|
63
|
+
maybeUploadDroppedFiles();
|
64
|
+
}
|
65
|
+
});
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
function handleDataTransfer(dataTransfer) {
|
70
|
+
var i, items, entry;
|
71
|
+
|
72
|
+
options.callbacks.dropProcessing(true);
|
73
|
+
dz.dropDisabled(true);
|
74
|
+
|
75
|
+
if (dataTransfer.files.length > 1 && !options.multiple) {
|
76
|
+
options.callbacks.error('tooManyFilesError', "");
|
77
|
+
}
|
78
|
+
else {
|
79
|
+
droppedFiles = [];
|
80
|
+
droppedEntriesCount = 0;
|
81
|
+
droppedEntriesParsedCount = 0;
|
82
|
+
|
83
|
+
if (qq.isFolderDropSupported(dataTransfer)) {
|
84
|
+
items = dataTransfer.items;
|
85
|
+
|
86
|
+
for (i = 0; i < items.length; i+=1) {
|
87
|
+
entry = items[i].webkitGetAsEntry();
|
88
|
+
if (entry) {
|
89
|
+
//due to a bug in Chrome's File System API impl - #149735
|
90
|
+
if (entry.isFile) {
|
91
|
+
droppedFiles.push(items[i].getAsFile());
|
92
|
+
if (i === items.length-1) {
|
93
|
+
maybeUploadDroppedFiles();
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
else {
|
98
|
+
traverseFileTree(entry);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
else {
|
104
|
+
options.callbacks.dropProcessing(false, dataTransfer.files);
|
105
|
+
dz.dropDisabled(false);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
function setupDropzone(dropArea){
|
111
|
+
dz = new qq.UploadDropZone({
|
112
|
+
element: dropArea,
|
113
|
+
onEnter: function(e){
|
114
|
+
qq(dropArea).addClass(options.classes.dropActive);
|
115
|
+
e.stopPropagation();
|
116
|
+
},
|
117
|
+
onLeaveNotDescendants: function(e){
|
118
|
+
qq(dropArea).removeClass(options.classes.dropActive);
|
119
|
+
},
|
120
|
+
onDrop: function(e){
|
121
|
+
if (options.hideDropzones) {
|
122
|
+
qq(dropArea).hide();
|
123
|
+
}
|
124
|
+
qq(dropArea).removeClass(options.classes.dropActive);
|
125
|
+
|
126
|
+
handleDataTransfer(e.dataTransfer);
|
127
|
+
}
|
128
|
+
});
|
129
|
+
|
130
|
+
disposeSupport.addDisposer(function() {
|
131
|
+
dz.dispose();
|
132
|
+
});
|
133
|
+
|
134
|
+
if (options.hideDropzones) {
|
135
|
+
qq(dropArea).hide();
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
function isFileDrag(dragEvent) {
|
140
|
+
var fileDrag;
|
141
|
+
|
142
|
+
qq.each(dragEvent.dataTransfer.types, function(key, val) {
|
143
|
+
if (val === 'Files') {
|
144
|
+
fileDrag = true;
|
145
|
+
return false;
|
146
|
+
}
|
147
|
+
});
|
148
|
+
|
149
|
+
return fileDrag;
|
150
|
+
}
|
151
|
+
|
152
|
+
function setupDragDrop(){
|
153
|
+
if (options.dropArea) {
|
154
|
+
options.extraDropzones.push(options.dropArea);
|
155
|
+
}
|
156
|
+
|
157
|
+
var i, dropzones = options.extraDropzones;
|
158
|
+
|
159
|
+
for (i=0; i < dropzones.length; i+=1){
|
160
|
+
setupDropzone(dropzones[i]);
|
161
|
+
}
|
162
|
+
|
163
|
+
// IE <= 9 does not support the File API used for drag+drop uploads
|
164
|
+
if (options.dropArea && (!qq.ie() || qq.ie10())) {
|
165
|
+
disposeSupport.attach(document, 'dragenter', function(e) {
|
166
|
+
if (!dz.dropDisabled() && isFileDrag(e)) {
|
167
|
+
if (qq(options.dropArea).hasClass(options.classes.dropDisabled)) {
|
168
|
+
return;
|
169
|
+
}
|
170
|
+
|
171
|
+
options.dropArea.style.display = 'block';
|
172
|
+
for (i=0; i < dropzones.length; i+=1) {
|
173
|
+
dropzones[i].style.display = 'block';
|
174
|
+
}
|
175
|
+
}
|
176
|
+
});
|
177
|
+
}
|
178
|
+
disposeSupport.attach(document, 'dragleave', function(e){
|
179
|
+
if (options.hideDropzones && qq.FineUploader.prototype._leaving_document_out(e)) {
|
180
|
+
for (i=0; i < dropzones.length; i+=1) {
|
181
|
+
qq(dropzones[i]).hide();
|
182
|
+
}
|
183
|
+
}
|
184
|
+
});
|
185
|
+
disposeSupport.attach(document, 'drop', function(e){
|
186
|
+
if (options.hideDropzones) {
|
187
|
+
for (i=0; i < dropzones.length; i+=1) {
|
188
|
+
qq(dropzones[i]).hide();
|
189
|
+
}
|
190
|
+
}
|
191
|
+
e.preventDefault();
|
192
|
+
});
|
193
|
+
}
|
194
|
+
|
195
|
+
return {
|
196
|
+
setup: function() {
|
197
|
+
setupDragDrop();
|
198
|
+
},
|
199
|
+
|
200
|
+
setupExtraDropzone: function(element) {
|
201
|
+
options.extraDropzones.push(element);
|
202
|
+
setupDropzone(element);
|
203
|
+
},
|
204
|
+
|
205
|
+
removeExtraDropzone: function(element) {
|
206
|
+
var i, dzs = options.extraDropzones;
|
207
|
+
for(i in dzs) {
|
208
|
+
if (dzs[i] === element) {
|
209
|
+
return dzs.splice(i, 1);
|
210
|
+
}
|
211
|
+
}
|
212
|
+
},
|
213
|
+
|
214
|
+
dispose: function() {
|
215
|
+
disposeSupport.dispose();
|
216
|
+
dz.dispose();
|
217
|
+
}
|
218
|
+
};
|
219
|
+
};
|
220
|
+
|
221
|
+
|
222
|
+
qq.UploadDropZone = function(o){
|
223
|
+
"use strict";
|
224
|
+
|
225
|
+
var options, element, preventDrop, dropOutsideDisabled, disposeSupport = new qq.DisposeSupport();
|
226
|
+
|
227
|
+
options = {
|
228
|
+
element: null,
|
229
|
+
onEnter: function(e){},
|
230
|
+
onLeave: function(e){},
|
231
|
+
// is not fired when leaving element by hovering descendants
|
232
|
+
onLeaveNotDescendants: function(e){},
|
233
|
+
onDrop: function(e){}
|
234
|
+
};
|
235
|
+
|
236
|
+
qq.extend(options, o);
|
237
|
+
element = options.element;
|
238
|
+
|
239
|
+
function dragover_should_be_canceled(){
|
240
|
+
return qq.safari() || (qq.firefox() && qq.windows());
|
241
|
+
}
|
242
|
+
|
243
|
+
function disableDropOutside(e){
|
244
|
+
// run only once for all instances
|
245
|
+
if (!dropOutsideDisabled ){
|
246
|
+
|
247
|
+
// for these cases we need to catch onDrop to reset dropArea
|
248
|
+
if (dragover_should_be_canceled){
|
249
|
+
disposeSupport.attach(document, 'dragover', function(e){
|
250
|
+
e.preventDefault();
|
251
|
+
});
|
252
|
+
} else {
|
253
|
+
disposeSupport.attach(document, 'dragover', function(e){
|
254
|
+
if (e.dataTransfer){
|
255
|
+
e.dataTransfer.dropEffect = 'none';
|
256
|
+
e.preventDefault();
|
257
|
+
}
|
258
|
+
});
|
259
|
+
}
|
260
|
+
|
261
|
+
dropOutsideDisabled = true;
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
function isValidFileDrag(e){
|
266
|
+
// e.dataTransfer currently causing IE errors
|
267
|
+
// IE9 does NOT support file API, so drag-and-drop is not possible
|
268
|
+
if (qq.ie() && !qq.ie10()) {
|
269
|
+
return false;
|
270
|
+
}
|
271
|
+
|
272
|
+
var effectTest, dt = e.dataTransfer,
|
273
|
+
// do not check dt.types.contains in webkit, because it crashes safari 4
|
274
|
+
isSafari = qq.safari();
|
275
|
+
|
276
|
+
// dt.effectAllowed is none in Safari 5
|
277
|
+
// dt.types.contains check is for firefox
|
278
|
+
effectTest = qq.ie10() ? true : dt.effectAllowed !== 'none';
|
279
|
+
return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains('Files')));
|
280
|
+
}
|
281
|
+
|
282
|
+
function isOrSetDropDisabled(isDisabled) {
|
283
|
+
if (isDisabled !== undefined) {
|
284
|
+
preventDrop = isDisabled;
|
285
|
+
}
|
286
|
+
return preventDrop;
|
287
|
+
}
|
288
|
+
|
289
|
+
function attachEvents(){
|
290
|
+
disposeSupport.attach(element, 'dragover', function(e){
|
291
|
+
if (!isValidFileDrag(e)) {
|
292
|
+
return;
|
293
|
+
}
|
294
|
+
|
295
|
+
var effect = qq.ie() ? null : e.dataTransfer.effectAllowed;
|
296
|
+
if (effect === 'move' || effect === 'linkMove'){
|
297
|
+
e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
|
298
|
+
} else {
|
299
|
+
e.dataTransfer.dropEffect = 'copy'; // for Chrome
|
300
|
+
}
|
301
|
+
|
302
|
+
e.stopPropagation();
|
303
|
+
e.preventDefault();
|
304
|
+
});
|
305
|
+
|
306
|
+
disposeSupport.attach(element, 'dragenter', function(e){
|
307
|
+
if (!isOrSetDropDisabled()) {
|
308
|
+
if (!isValidFileDrag(e)) {
|
309
|
+
return;
|
310
|
+
}
|
311
|
+
options.onEnter(e);
|
312
|
+
}
|
313
|
+
});
|
314
|
+
|
315
|
+
disposeSupport.attach(element, 'dragleave', function(e){
|
316
|
+
if (!isValidFileDrag(e)) {
|
317
|
+
return;
|
318
|
+
}
|
319
|
+
|
320
|
+
options.onLeave(e);
|
321
|
+
|
322
|
+
var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
|
323
|
+
// do not fire when moving a mouse over a descendant
|
324
|
+
if (qq(this).contains(relatedTarget)) {
|
325
|
+
return;
|
326
|
+
}
|
327
|
+
|
328
|
+
options.onLeaveNotDescendants(e);
|
329
|
+
});
|
330
|
+
|
331
|
+
disposeSupport.attach(element, 'drop', function(e){
|
332
|
+
if (!isOrSetDropDisabled()) {
|
333
|
+
if (!isValidFileDrag(e)) {
|
334
|
+
return;
|
335
|
+
}
|
336
|
+
|
337
|
+
e.preventDefault();
|
338
|
+
options.onDrop(e);
|
339
|
+
}
|
340
|
+
});
|
341
|
+
}
|
342
|
+
|
343
|
+
disableDropOutside();
|
344
|
+
attachEvents();
|
345
|
+
|
346
|
+
return {
|
347
|
+
dropDisabled: function(isDisabled) {
|
348
|
+
return isOrSetDropDisabled(isDisabled);
|
349
|
+
},
|
350
|
+
|
351
|
+
dispose: function() {
|
352
|
+
disposeSupport.dispose();
|
353
|
+
}
|
354
|
+
};
|
355
|
+
};
|
@@ -0,0 +1,115 @@
|
|
1
|
+
/**
|
2
|
+
* Class for uploading files, uploading itself is handled by child classes
|
3
|
+
*/
|
4
|
+
qq.UploadHandlerAbstract = function(o){
|
5
|
+
// Default options, can be overridden by the user
|
6
|
+
this._options = {
|
7
|
+
debug: false,
|
8
|
+
endpoint: '/upload.php',
|
9
|
+
paramsInBody: false,
|
10
|
+
// maximum number of concurrent uploads
|
11
|
+
maxConnections: 999,
|
12
|
+
log: function(str, level) {},
|
13
|
+
onProgress: function(id, fileName, loaded, total){},
|
14
|
+
onComplete: function(id, fileName, response, xhr){},
|
15
|
+
onCancel: function(id, fileName){},
|
16
|
+
onUpload: function(id, fileName, xhr){},
|
17
|
+
onAutoRetry: function(id, fileName, response, xhr){}
|
18
|
+
|
19
|
+
};
|
20
|
+
qq.extend(this._options, o);
|
21
|
+
|
22
|
+
this._queue = [];
|
23
|
+
|
24
|
+
this.log = this._options.log;
|
25
|
+
};
|
26
|
+
qq.UploadHandlerAbstract.prototype = {
|
27
|
+
/**
|
28
|
+
* Adds file or file input to the queue
|
29
|
+
* @returns id
|
30
|
+
**/
|
31
|
+
add: function(file){},
|
32
|
+
/**
|
33
|
+
* Sends the file identified by id
|
34
|
+
*/
|
35
|
+
upload: function(id){
|
36
|
+
var len = this._queue.push(id);
|
37
|
+
|
38
|
+
// if too many active uploads, wait...
|
39
|
+
if (len <= this._options.maxConnections){
|
40
|
+
this._upload(id);
|
41
|
+
}
|
42
|
+
},
|
43
|
+
retry: function(id) {
|
44
|
+
var i = qq.indexOf(this._queue, id);
|
45
|
+
if (i >= 0) {
|
46
|
+
this._upload(id);
|
47
|
+
}
|
48
|
+
else {
|
49
|
+
this.upload(id);
|
50
|
+
}
|
51
|
+
},
|
52
|
+
/**
|
53
|
+
* Cancels file upload by id
|
54
|
+
*/
|
55
|
+
cancel: function(id){
|
56
|
+
this.log('Cancelling ' + id);
|
57
|
+
this._options.paramsStore.remove(id);
|
58
|
+
this._cancel(id);
|
59
|
+
this._dequeue(id);
|
60
|
+
},
|
61
|
+
/**
|
62
|
+
* Cancells all uploads
|
63
|
+
*/
|
64
|
+
cancelAll: function(){
|
65
|
+
for (var i=0; i<this._queue.length; i++){
|
66
|
+
this._cancel(this._queue[i]);
|
67
|
+
}
|
68
|
+
this._queue = [];
|
69
|
+
},
|
70
|
+
/**
|
71
|
+
* Returns name of the file identified by id
|
72
|
+
*/
|
73
|
+
getName: function(id){},
|
74
|
+
/**
|
75
|
+
* Returns size of the file identified by id
|
76
|
+
*/
|
77
|
+
getSize: function(id){},
|
78
|
+
/**
|
79
|
+
* Returns id of files being uploaded or
|
80
|
+
* waiting for their turn
|
81
|
+
*/
|
82
|
+
getQueue: function(){
|
83
|
+
return this._queue;
|
84
|
+
},
|
85
|
+
reset: function() {
|
86
|
+
this.log('Resetting upload handler');
|
87
|
+
this._queue = [];
|
88
|
+
},
|
89
|
+
/**
|
90
|
+
* Actual upload method
|
91
|
+
*/
|
92
|
+
_upload: function(id){},
|
93
|
+
/**
|
94
|
+
* Actual cancel method
|
95
|
+
*/
|
96
|
+
_cancel: function(id){},
|
97
|
+
/**
|
98
|
+
* Removes element from queue, starts upload of next
|
99
|
+
*/
|
100
|
+
_dequeue: function(id){
|
101
|
+
var i = qq.indexOf(this._queue, id);
|
102
|
+
this._queue.splice(i, 1);
|
103
|
+
|
104
|
+
var max = this._options.maxConnections;
|
105
|
+
|
106
|
+
if (this._queue.length >= max && i < max){
|
107
|
+
var nextId = this._queue[max-1];
|
108
|
+
this._upload(nextId);
|
109
|
+
}
|
110
|
+
},
|
111
|
+
/**
|
112
|
+
* Determine if the file exists.
|
113
|
+
*/
|
114
|
+
isValid: function(id) {}
|
115
|
+
};
|