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.
- data/LICENSE.txt +1 -3
- data/Vendorfile +16 -5
- data/lib/fine_uploader/version.rb +1 -1
- data/vendor/assets/javascripts/fine_uploader/ajax.requester.js +184 -0
- data/vendor/assets/javascripts/fine_uploader/button.js +62 -58
- data/vendor/assets/javascripts/fine_uploader/deletefile.ajax.requester.js +44 -0
- data/vendor/assets/javascripts/fine_uploader/dnd.js +2 -0
- data/vendor/assets/javascripts/fine_uploader/handler.base.js +164 -92
- data/vendor/assets/javascripts/fine_uploader/handler.form.js +220 -133
- data/vendor/assets/javascripts/fine_uploader/handler.xhr.js +594 -132
- data/vendor/assets/javascripts/fine_uploader/header.js +3 -4
- data/vendor/assets/javascripts/fine_uploader/iframe.xss.response.js +6 -0
- data/vendor/assets/javascripts/fine_uploader/jquery-plugin.js +13 -4
- data/vendor/assets/javascripts/fine_uploader/paste.js +49 -0
- data/vendor/assets/javascripts/fine_uploader/promise.js +45 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.basic.js +547 -175
- data/vendor/assets/javascripts/fine_uploader/uploader.js +197 -42
- data/vendor/assets/javascripts/fine_uploader/util.js +117 -12
- data/vendor/assets/javascripts/fine_uploader/window.receive.message.js +32 -0
- data/vendor/assets/javascripts/fine_uploader.js +17 -0
- data/vendor/assets/stylesheets/fine_uploader.css.scss +6 -7
- metadata +9 -2
data/LICENSE.txt
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
Copyright (c) 2012 Alif Rachmawadi
|
2
|
-
|
3
1
|
MIT License
|
4
2
|
|
5
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
@@ -19,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
17
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Vendorfile
CHANGED
@@ -1,16 +1,27 @@
|
|
1
|
-
from 'git://github.com/
|
1
|
+
from 'git://github.com/Widen/fine-uploader.git', tag: '3.4.1' do
|
2
|
+
# images
|
2
3
|
file 'vendor/assets/images/fine_uploader/loading.gif', 'client/loading.gif'
|
3
4
|
file 'vendor/assets/images/fine_uploader/processing.gif', 'client/processing.gif'
|
4
|
-
|
5
|
-
|
5
|
+
|
6
|
+
# javascripts
|
7
|
+
file 'vendor/assets/javascripts/fine_uploader/ajax.requester.js', 'client/js/ajax.requester.js'
|
6
8
|
file 'vendor/assets/javascripts/fine_uploader/button.js', 'client/js/button.js'
|
9
|
+
file 'vendor/assets/javascripts/fine_uploader/deletefile.ajax.requester.js', 'client/js/deletefile.ajax.requester.js'
|
10
|
+
file 'vendor/assets/javascripts/fine_uploader/dnd.js', 'client/js/dnd.js'
|
7
11
|
file 'vendor/assets/javascripts/fine_uploader/handler.base.js', 'client/js/handler.base.js'
|
8
12
|
file 'vendor/assets/javascripts/fine_uploader/handler.form.js', 'client/js/handler.form.js'
|
9
13
|
file 'vendor/assets/javascripts/fine_uploader/handler.xhr.js', 'client/js/handler.xhr.js'
|
14
|
+
file 'vendor/assets/javascripts/fine_uploader/header.js', 'client/js/header.js'
|
15
|
+
file 'vendor/assets/javascripts/fine_uploader/iframe.xss.response.js', 'client/js/iframe.xss.response.js'
|
16
|
+
file 'vendor/assets/javascripts/fine_uploader/jquery-plugin.js', 'client/js/jquery-plugin.js'
|
17
|
+
file 'vendor/assets/javascripts/fine_uploader/paste.js', 'client/js/paste.js'
|
18
|
+
file 'vendor/assets/javascripts/fine_uploader/promise.js', 'client/js/promise.js'
|
10
19
|
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
20
|
file 'vendor/assets/javascripts/fine_uploader/uploader.js', 'client/js/uploader.js'
|
13
|
-
file 'vendor/assets/javascripts/fine_uploader/
|
21
|
+
file 'vendor/assets/javascripts/fine_uploader/util.js', 'client/js/util.js'
|
22
|
+
file 'vendor/assets/javascripts/fine_uploader/window.receive.message.js', 'client/js/window.receive.message.js'
|
23
|
+
|
24
|
+
# scss
|
14
25
|
file 'vendor/assets/stylesheets/fine_uploader.css.scss', 'client/fineuploader.css' do |path|
|
15
26
|
rewrite(path) do |content|
|
16
27
|
content.gsub!('url', 'image-url')
|
@@ -0,0 +1,184 @@
|
|
1
|
+
/** Generic class for sending non-upload ajax requests and handling the associated responses **/
|
2
|
+
//TODO Use XDomainRequest if expectCors = true. Not necessary now since only DELETE requests are sent and XDR doesn't support pre-flighting.
|
3
|
+
/*globals qq, XMLHttpRequest*/
|
4
|
+
qq.AjaxRequestor = function(o) {
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
var log, shouldParamsBeInQueryString,
|
8
|
+
queue = [],
|
9
|
+
requestState = [],
|
10
|
+
options = {
|
11
|
+
method: 'POST',
|
12
|
+
maxConnections: 3,
|
13
|
+
customHeaders: {},
|
14
|
+
endpointStore: {},
|
15
|
+
paramsStore: {},
|
16
|
+
successfulResponseCodes: [200],
|
17
|
+
demoMode: false,
|
18
|
+
cors: {
|
19
|
+
expected: false,
|
20
|
+
sendCredentials: false
|
21
|
+
},
|
22
|
+
log: function(str, level) {},
|
23
|
+
onSend: function(id) {},
|
24
|
+
onComplete: function(id, xhr, isError) {},
|
25
|
+
onCancel: function(id) {}
|
26
|
+
};
|
27
|
+
|
28
|
+
qq.extend(options, o);
|
29
|
+
log = options.log;
|
30
|
+
shouldParamsBeInQueryString = getMethod() === 'GET' || getMethod() === 'DELETE';
|
31
|
+
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Removes element from queue, sends next request
|
35
|
+
*/
|
36
|
+
function dequeue(id) {
|
37
|
+
var i = qq.indexOf(queue, id),
|
38
|
+
max = options.maxConnections,
|
39
|
+
nextId;
|
40
|
+
|
41
|
+
delete requestState[id];
|
42
|
+
queue.splice(i, 1);
|
43
|
+
|
44
|
+
if (queue.length >= max && i < max){
|
45
|
+
nextId = queue[max-1];
|
46
|
+
sendRequest(nextId);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
function onComplete(id) {
|
51
|
+
var xhr = requestState[id].xhr,
|
52
|
+
method = getMethod(),
|
53
|
+
isError = false;
|
54
|
+
|
55
|
+
dequeue(id);
|
56
|
+
|
57
|
+
if (!isResponseSuccessful(xhr.status)) {
|
58
|
+
isError = true;
|
59
|
+
log(method + " request for " + id + " has failed - response code " + xhr.status, "error");
|
60
|
+
}
|
61
|
+
|
62
|
+
options.onComplete(id, xhr, isError);
|
63
|
+
}
|
64
|
+
|
65
|
+
function sendRequest(id) {
|
66
|
+
var xhr = new XMLHttpRequest(),
|
67
|
+
method = getMethod(),
|
68
|
+
params = {},
|
69
|
+
url;
|
70
|
+
|
71
|
+
options.onSend(id);
|
72
|
+
|
73
|
+
if (options.paramsStore.getParams) {
|
74
|
+
params = options.paramsStore.getParams(id);
|
75
|
+
}
|
76
|
+
|
77
|
+
url = createUrl(id, params);
|
78
|
+
|
79
|
+
requestState[id].xhr = xhr;
|
80
|
+
xhr.onreadystatechange = getReadyStateChangeHandler(id);
|
81
|
+
xhr.open(method, url, true);
|
82
|
+
|
83
|
+
if (options.cors.expected && options.cors.sendCredentials) {
|
84
|
+
xhr.withCredentials = true;
|
85
|
+
}
|
86
|
+
|
87
|
+
setHeaders(id);
|
88
|
+
|
89
|
+
log('Sending ' + method + " request for " + id);
|
90
|
+
if (!shouldParamsBeInQueryString && params) {
|
91
|
+
xhr.send(qq.obj2url(params, ""));
|
92
|
+
}
|
93
|
+
else {
|
94
|
+
xhr.send();
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
function createUrl(id, params) {
|
99
|
+
var endpoint = options.endpointStore.getEndpoint(id),
|
100
|
+
addToPath = requestState[id].addToPath;
|
101
|
+
|
102
|
+
if (addToPath !== undefined) {
|
103
|
+
endpoint += "/" + addToPath;
|
104
|
+
}
|
105
|
+
|
106
|
+
if (shouldParamsBeInQueryString && params) {
|
107
|
+
return qq.obj2url(params, endpoint);
|
108
|
+
}
|
109
|
+
else {
|
110
|
+
return endpoint;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
function getReadyStateChangeHandler(id) {
|
115
|
+
var xhr = requestState[id].xhr;
|
116
|
+
|
117
|
+
return function() {
|
118
|
+
if (xhr.readyState === 4) {
|
119
|
+
onComplete(id, xhr);
|
120
|
+
}
|
121
|
+
};
|
122
|
+
}
|
123
|
+
|
124
|
+
function setHeaders(id) {
|
125
|
+
var xhr = requestState[id].xhr,
|
126
|
+
customHeaders = options.customHeaders;
|
127
|
+
|
128
|
+
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
129
|
+
xhr.setRequestHeader("Cache-Control", "no-cache");
|
130
|
+
|
131
|
+
qq.each(customHeaders, function(name, val) {
|
132
|
+
xhr.setRequestHeader(name, val);
|
133
|
+
});
|
134
|
+
}
|
135
|
+
|
136
|
+
function cancelRequest(id) {
|
137
|
+
var xhr = requestState[id].xhr,
|
138
|
+
method = getMethod();
|
139
|
+
|
140
|
+
if (xhr) {
|
141
|
+
xhr.onreadystatechange = null;
|
142
|
+
xhr.abort();
|
143
|
+
dequeue(id);
|
144
|
+
|
145
|
+
log('Cancelled ' + method + " for " + id);
|
146
|
+
options.onCancel(id);
|
147
|
+
|
148
|
+
return true;
|
149
|
+
}
|
150
|
+
|
151
|
+
return false;
|
152
|
+
}
|
153
|
+
|
154
|
+
function isResponseSuccessful(responseCode) {
|
155
|
+
return qq.indexOf(options.successfulResponseCodes, responseCode) >= 0;
|
156
|
+
}
|
157
|
+
|
158
|
+
function getMethod() {
|
159
|
+
if (options.demoMode) {
|
160
|
+
return "GET";
|
161
|
+
}
|
162
|
+
|
163
|
+
return options.method;
|
164
|
+
}
|
165
|
+
|
166
|
+
|
167
|
+
return {
|
168
|
+
send: function(id, addToPath) {
|
169
|
+
requestState[id] = {
|
170
|
+
addToPath: addToPath
|
171
|
+
};
|
172
|
+
|
173
|
+
var len = queue.push(id);
|
174
|
+
|
175
|
+
// if too many active connections, wait...
|
176
|
+
if (len <= options.maxConnections){
|
177
|
+
sendRequest(id);
|
178
|
+
}
|
179
|
+
},
|
180
|
+
cancel: function(id) {
|
181
|
+
return cancelRequest(id);
|
182
|
+
}
|
183
|
+
};
|
184
|
+
};
|
@@ -1,58 +1,34 @@
|
|
1
|
-
qq
|
2
|
-
|
3
|
-
|
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
|
-
};
|
1
|
+
/*globals qq*/
|
2
|
+
qq.UploadButton = function(o) {
|
3
|
+
"use strict";
|
30
4
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
5
|
+
var input,
|
6
|
+
disposeSupport = new qq.DisposeSupport(),
|
7
|
+
options = {
|
8
|
+
element: null,
|
9
|
+
// if set to true adds multiple attribute to file input
|
10
|
+
multiple: false,
|
11
|
+
acceptFiles: null,
|
12
|
+
// name attribute of file input
|
13
|
+
name: 'file',
|
14
|
+
onChange: function(input) {},
|
15
|
+
hoverClass: 'qq-upload-button-hover',
|
16
|
+
focusClass: 'qq-upload-button-focus'
|
17
|
+
};
|
41
18
|
|
42
|
-
|
43
|
-
this._input = this._createInput();
|
44
|
-
},
|
45
|
-
_createInput: function(){
|
19
|
+
function createInput() {
|
46
20
|
var input = document.createElement("input");
|
47
21
|
|
48
|
-
if (
|
22
|
+
if (options.multiple){
|
49
23
|
input.setAttribute("multiple", "multiple");
|
50
24
|
}
|
51
25
|
|
52
|
-
if (
|
26
|
+
if (options.acceptFiles) {
|
27
|
+
input.setAttribute("accept", options.acceptFiles);
|
28
|
+
}
|
53
29
|
|
54
30
|
input.setAttribute("type", "file");
|
55
|
-
input.setAttribute("name",
|
31
|
+
input.setAttribute("name", options.name);
|
56
32
|
|
57
33
|
qq(input).css({
|
58
34
|
position: 'absolute',
|
@@ -70,24 +46,23 @@ qq.UploadButton.prototype = {
|
|
70
46
|
opacity: 0
|
71
47
|
});
|
72
48
|
|
73
|
-
|
49
|
+
options.element.appendChild(input);
|
74
50
|
|
75
|
-
|
76
|
-
|
77
|
-
self._options.onChange(input);
|
51
|
+
disposeSupport.attach(input, 'change', function(){
|
52
|
+
options.onChange(input);
|
78
53
|
});
|
79
54
|
|
80
|
-
|
81
|
-
qq(
|
55
|
+
disposeSupport.attach(input, 'mouseover', function(){
|
56
|
+
qq(options.element).addClass(options.hoverClass);
|
82
57
|
});
|
83
|
-
|
84
|
-
qq(
|
58
|
+
disposeSupport.attach(input, 'mouseout', function(){
|
59
|
+
qq(options.element).removeClass(options.hoverClass);
|
85
60
|
});
|
86
|
-
|
87
|
-
qq(
|
61
|
+
disposeSupport.attach(input, 'focus', function(){
|
62
|
+
qq(options.element).addClass(options.focusClass);
|
88
63
|
});
|
89
|
-
|
90
|
-
qq(
|
64
|
+
disposeSupport.attach(input, 'blur', function(){
|
65
|
+
qq(options.element).removeClass(options.focusClass);
|
91
66
|
});
|
92
67
|
|
93
68
|
// IE and Opera, unfortunately have 2 tab stops on file input
|
@@ -99,4 +74,33 @@ qq.UploadButton.prototype = {
|
|
99
74
|
|
100
75
|
return input;
|
101
76
|
}
|
77
|
+
|
78
|
+
|
79
|
+
qq.extend(options, o);
|
80
|
+
|
81
|
+
// make button suitable container for input
|
82
|
+
qq(options.element).css({
|
83
|
+
position: 'relative',
|
84
|
+
overflow: 'hidden',
|
85
|
+
// Make sure browse button is in the right side
|
86
|
+
// in Internet Explorer
|
87
|
+
direction: 'ltr'
|
88
|
+
});
|
89
|
+
|
90
|
+
input = createInput();
|
91
|
+
|
92
|
+
return {
|
93
|
+
getInput: function(){
|
94
|
+
return input;
|
95
|
+
},
|
96
|
+
|
97
|
+
reset: function(){
|
98
|
+
if (input.parentNode){
|
99
|
+
qq(input).remove();
|
100
|
+
}
|
101
|
+
|
102
|
+
qq(options.element).removeClass(options.focusClass);
|
103
|
+
input = createInput();
|
104
|
+
}
|
105
|
+
};
|
102
106
|
};
|
@@ -0,0 +1,44 @@
|
|
1
|
+
/** Generic class for sending non-upload ajax requests and handling the associated responses **/
|
2
|
+
/*globals qq, XMLHttpRequest*/
|
3
|
+
qq.DeleteFileAjaxRequestor = function(o) {
|
4
|
+
"use strict";
|
5
|
+
|
6
|
+
var requestor,
|
7
|
+
options = {
|
8
|
+
endpointStore: {},
|
9
|
+
maxConnections: 3,
|
10
|
+
customHeaders: {},
|
11
|
+
paramsStore: {},
|
12
|
+
demoMode: false,
|
13
|
+
cors: {
|
14
|
+
expected: false,
|
15
|
+
sendCredentials: false
|
16
|
+
},
|
17
|
+
log: function(str, level) {},
|
18
|
+
onDelete: function(id) {},
|
19
|
+
onDeleteComplete: function(id, xhr, isError) {}
|
20
|
+
};
|
21
|
+
|
22
|
+
qq.extend(options, o);
|
23
|
+
|
24
|
+
requestor = new qq.AjaxRequestor({
|
25
|
+
method: 'DELETE',
|
26
|
+
endpointStore: options.endpointStore,
|
27
|
+
paramsStore: options.paramsStore,
|
28
|
+
maxConnections: options.maxConnections,
|
29
|
+
customHeaders: options.customHeaders,
|
30
|
+
successfulResponseCodes: [200, 202, 204],
|
31
|
+
demoMode: options.demoMode,
|
32
|
+
log: options.log,
|
33
|
+
onSend: options.onDelete,
|
34
|
+
onComplete: options.onDeleteComplete
|
35
|
+
});
|
36
|
+
|
37
|
+
|
38
|
+
return {
|
39
|
+
sendDelete: function(id, uuid) {
|
40
|
+
requestor.send(id, uuid);
|
41
|
+
options.log("Submitted delete file request for " + id);
|
42
|
+
}
|
43
|
+
};
|
44
|
+
};
|
@@ -73,7 +73,9 @@ qq.DragAndDrop = function(o) {
|
|
73
73
|
dz.dropDisabled(true);
|
74
74
|
|
75
75
|
if (dataTransfer.files.length > 1 && !options.multiple) {
|
76
|
+
options.callbacks.dropProcessing(false);
|
76
77
|
options.callbacks.error('tooManyFilesError', "");
|
78
|
+
dz.dropDisabled(false);
|
77
79
|
}
|
78
80
|
else {
|
79
81
|
droppedFiles = [];
|