jquery.fileupload-rails 0.0.1 → 0.1.0
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.
- data/Readme.md +14 -0
- data/lib/jquery.fileupload-rails/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.fileupload-ip.js +160 -0
- data/vendor/assets/javascripts/jquery.fileupload-ui.js +342 -371
- data/vendor/assets/javascripts/jquery.fileupload.js +87 -46
- data/vendor/assets/javascripts/jquery.iframe-transport.js +14 -5
- data/vendor/assets/javascripts/jquery.postmessage-transport.js +14 -5
- data/vendor/assets/javascripts/jquery.xdr-transport.js +18 -9
- data/vendor/assets/stylesheets/jquery.fileupload-ui.css +52 -68
- metadata +4 -2
data/Readme.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# jQuery File Upload for Rails
|
2
|
+
|
3
|
+
jQuery File Upload is a very well designed cross-browser solution for modern file uploading with pure JavaScript.
|
4
|
+
The plugin is developed by Sebastian Tschan (@blueimp) and well maintained.
|
5
|
+
|
6
|
+
This is a simple gem package for this plugin.
|
7
|
+
|
8
|
+
[See the original project page](https://github.com/blueimp/jQuery-File-Upload) for reference & documentation.
|
9
|
+
|
10
|
+
## Changelog
|
11
|
+
|
12
|
+
0.1.0. jquery.fileupload 5.9.0 and jquery.fileupload-ui 6.6.2, added readme.
|
13
|
+
|
14
|
+
0.0.1. jquery.fileupload 5.5.2 and jquery.fileupload-ui 5.1.1.
|
@@ -0,0 +1,160 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery File Upload Image Processing Plugin 1.0.6
|
3
|
+
* https://github.com/blueimp/jQuery-File-Upload
|
4
|
+
*
|
5
|
+
* Copyright 2012, Sebastian Tschan
|
6
|
+
* https://blueimp.net
|
7
|
+
*
|
8
|
+
* Licensed under the MIT license:
|
9
|
+
* http://www.opensource.org/licenses/MIT
|
10
|
+
*/
|
11
|
+
|
12
|
+
/*jslint nomen: true, unparam: true, regexp: true */
|
13
|
+
/*global define, window, document */
|
14
|
+
|
15
|
+
(function (factory) {
|
16
|
+
'use strict';
|
17
|
+
if (typeof define === 'function' && define.amd) {
|
18
|
+
// Register as an anonymous AMD module:
|
19
|
+
define([
|
20
|
+
'jquery',
|
21
|
+
'load-image',
|
22
|
+
'canvas-to-blob',
|
23
|
+
'./jquery.fileupload'
|
24
|
+
], factory);
|
25
|
+
} else {
|
26
|
+
// Browser globals:
|
27
|
+
factory(
|
28
|
+
window.jQuery,
|
29
|
+
window.loadImage,
|
30
|
+
window.canvasToBlob
|
31
|
+
);
|
32
|
+
}
|
33
|
+
}(function ($, loadImage, canvasToBlob) {
|
34
|
+
'use strict';
|
35
|
+
|
36
|
+
// The File Upload IP version extends the basic fileupload widget
|
37
|
+
// with image processing functionality:
|
38
|
+
$.widget('blueimpIP.fileupload', $.blueimp.fileupload, {
|
39
|
+
|
40
|
+
options: {
|
41
|
+
// The regular expression to define which image files are to be
|
42
|
+
// resized, given that the browser supports the operation:
|
43
|
+
resizeSourceFileTypes: /^image\/(gif|jpeg|png)$/,
|
44
|
+
// The maximum file size of images that are to be resized:
|
45
|
+
resizeSourceMaxFileSize: 20000000, // 20MB
|
46
|
+
// The maximum width of the resized images:
|
47
|
+
resizeMaxWidth: undefined,
|
48
|
+
// The maximum height of the resized images:
|
49
|
+
resizeMaxHeight: undefined,
|
50
|
+
// The minimum width of the resized images:
|
51
|
+
resizeMinWidth: undefined,
|
52
|
+
// The minimum height of the resized images:
|
53
|
+
resizeMinHeight: undefined,
|
54
|
+
|
55
|
+
// The add callback is invoked as soon as files are added to the fileupload
|
56
|
+
// widget (via file input selection, drag & drop or add API call).
|
57
|
+
// See the basic file upload widget for more information:
|
58
|
+
add: function (e, data) {
|
59
|
+
$(this).fileupload('resize', data).done(function () {
|
60
|
+
data.submit();
|
61
|
+
});
|
62
|
+
}
|
63
|
+
},
|
64
|
+
|
65
|
+
// Resizes the image file at the given index and stores the created blob
|
66
|
+
// at the original position of the files list, returns a Promise object:
|
67
|
+
_resizeImage: function (files, index, options) {
|
68
|
+
var that = this,
|
69
|
+
file = files[index],
|
70
|
+
deferred = $.Deferred(),
|
71
|
+
canvas,
|
72
|
+
blob;
|
73
|
+
options = options || this.options;
|
74
|
+
loadImage(
|
75
|
+
file,
|
76
|
+
function (img) {
|
77
|
+
var width = img.width,
|
78
|
+
height = img.height;
|
79
|
+
canvas = loadImage.scale(img, {
|
80
|
+
maxWidth: options.resizeMaxWidth,
|
81
|
+
maxHeight: options.resizeMaxHeight,
|
82
|
+
minWidth: options.resizeMinWidth,
|
83
|
+
minHeight: options.resizeMinHeight,
|
84
|
+
canvas: true
|
85
|
+
});
|
86
|
+
if (width !== canvas.width || height !== canvas.height) {
|
87
|
+
canvasToBlob(canvas, function (blob) {
|
88
|
+
if (!blob.name) {
|
89
|
+
if (file.type === blob.type) {
|
90
|
+
blob.name = file.name;
|
91
|
+
} else if (file.name) {
|
92
|
+
blob.name = file.name.replace(
|
93
|
+
/\..+$/,
|
94
|
+
'.' + blob.type.substr(6)
|
95
|
+
);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
files[index] = blob;
|
99
|
+
deferred.resolveWith(that);
|
100
|
+
}, file);
|
101
|
+
} else {
|
102
|
+
deferred.resolveWith(that);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
);
|
106
|
+
return deferred.promise();
|
107
|
+
},
|
108
|
+
|
109
|
+
// Resizes the images given as files property of the data parameter,
|
110
|
+
// returns a Promise object that allows to bind a done handler, which
|
111
|
+
// will be invoked after processing all images is done:
|
112
|
+
resize: function (data) {
|
113
|
+
var that = this,
|
114
|
+
options = $.extend({}, this.options, data),
|
115
|
+
resizeAll = $.type(options.resizeSourceMaxFileSize) !== 'number',
|
116
|
+
isXHRUpload = this._isXHRUpload(options);
|
117
|
+
$.each(data.files, function (index, file) {
|
118
|
+
if (isXHRUpload && that._resizeSupport &&
|
119
|
+
(options.resizeMaxWidth || options.resizeMaxHeight ||
|
120
|
+
options.resizeMinWidth || options.resizeMinHeight) &&
|
121
|
+
(resizeAll || file.size < options.resizeSourceMaxFileSize) &&
|
122
|
+
options.resizeSourceFileTypes.test(file.type)) {
|
123
|
+
that._processing += 1;
|
124
|
+
if (that._processing === 1) {
|
125
|
+
that.element.addClass('fileupload-processing');
|
126
|
+
}
|
127
|
+
that._processingQueue = that._processingQueue.pipe(function () {
|
128
|
+
var deferred = $.Deferred();
|
129
|
+
that._resizeImage(
|
130
|
+
data.files,
|
131
|
+
index,
|
132
|
+
options
|
133
|
+
).done(function () {
|
134
|
+
that._processing -= 1;
|
135
|
+
if (that._processing === 0) {
|
136
|
+
that.element
|
137
|
+
.removeClass('fileupload-processing');
|
138
|
+
}
|
139
|
+
deferred.resolveWith(that);
|
140
|
+
});
|
141
|
+
return deferred.promise();
|
142
|
+
});
|
143
|
+
}
|
144
|
+
});
|
145
|
+
return this._processingQueue;
|
146
|
+
},
|
147
|
+
|
148
|
+
_create: function () {
|
149
|
+
$.blueimp.fileupload.prototype._create.call(this);
|
150
|
+
this._processing = 0;
|
151
|
+
this._processingQueue = $.Deferred().resolveWith(this).promise();
|
152
|
+
this._resizeSupport = canvasToBlob && canvasToBlob(
|
153
|
+
document.createElement('canvas'),
|
154
|
+
$.noop
|
155
|
+
);
|
156
|
+
}
|
157
|
+
|
158
|
+
});
|
159
|
+
|
160
|
+
}));
|
@@ -1,24 +1,42 @@
|
|
1
1
|
/*
|
2
|
-
* jQuery File Upload User Interface Plugin
|
2
|
+
* jQuery File Upload User Interface Plugin 6.6.2
|
3
3
|
* https://github.com/blueimp/jQuery-File-Upload
|
4
4
|
*
|
5
5
|
* Copyright 2010, Sebastian Tschan
|
6
6
|
* https://blueimp.net
|
7
7
|
*
|
8
8
|
* Licensed under the MIT license:
|
9
|
-
* http://
|
9
|
+
* http://www.opensource.org/licenses/MIT
|
10
10
|
*/
|
11
11
|
|
12
12
|
/*jslint nomen: true, unparam: true, regexp: true */
|
13
|
-
/*global window, document, URL, webkitURL, FileReader
|
13
|
+
/*global define, window, document, URL, webkitURL, FileReader */
|
14
14
|
|
15
|
-
(function (
|
15
|
+
(function (factory) {
|
16
|
+
'use strict';
|
17
|
+
if (typeof define === 'function' && define.amd) {
|
18
|
+
// Register as an anonymous AMD module:
|
19
|
+
define([
|
20
|
+
'jquery',
|
21
|
+
'tmpl',
|
22
|
+
'load-image',
|
23
|
+
'./jquery.fileupload-ip'
|
24
|
+
], factory);
|
25
|
+
} else {
|
26
|
+
// Browser globals:
|
27
|
+
factory(
|
28
|
+
window.jQuery,
|
29
|
+
window.tmpl,
|
30
|
+
window.loadImage
|
31
|
+
);
|
32
|
+
}
|
33
|
+
}(function ($, tmpl, loadImage) {
|
16
34
|
'use strict';
|
17
35
|
|
18
|
-
// The UI version extends the
|
19
|
-
//
|
20
|
-
|
21
|
-
$.widget('blueimpUI.fileupload',
|
36
|
+
// The UI version extends the IP (image processing) version or the basic
|
37
|
+
// file upload widget and adds complete user interface interaction:
|
38
|
+
var parentWidget = ($.blueimpIP || $.blueimp).fileupload;
|
39
|
+
$.widget('blueimpUI.fileupload', parentWidget, {
|
22
40
|
|
23
41
|
options: {
|
24
42
|
// By default, files added to the widget are uploaded as soon
|
@@ -31,13 +49,15 @@
|
|
31
49
|
// The maximum allowed file size:
|
32
50
|
maxFileSize: undefined,
|
33
51
|
// The minimum allowed file size:
|
34
|
-
minFileSize:
|
52
|
+
minFileSize: undefined,
|
35
53
|
// The regular expression for allowed file types, matches
|
36
54
|
// against either file type or file name:
|
37
55
|
acceptFileTypes: /.+$/i,
|
38
56
|
// The regular expression to define for which files a preview
|
39
57
|
// image is shown, matched against the file type:
|
40
|
-
|
58
|
+
previewSourceFileTypes: /^image\/(gif|jpeg|png)$/,
|
59
|
+
// The maximum file size of images that are to be displayed as preview:
|
60
|
+
previewSourceMaxFileSize: 5000000, // 5MB
|
41
61
|
// The maximum width of the preview images:
|
42
62
|
previewMaxWidth: 80,
|
43
63
|
// The maximum height of the preview images:
|
@@ -46,12 +66,10 @@
|
|
46
66
|
// if supported by the browser. Set the following option to false
|
47
67
|
// to always display preview images as img elements:
|
48
68
|
previewAsCanvas: true,
|
49
|
-
// The
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
// jQuery.tmpl method to render the file downloads:
|
54
|
-
downloadTemplate: $('#template-download'),
|
69
|
+
// The ID of the upload template:
|
70
|
+
uploadTemplateId: 'template-upload',
|
71
|
+
// The ID of the download template:
|
72
|
+
downloadTemplateId: 'template-download',
|
55
73
|
// The expected data type of the upload response, sets the dataType
|
56
74
|
// option of the $.ajax upload requests:
|
57
75
|
dataType: 'json',
|
@@ -60,24 +78,33 @@
|
|
60
78
|
// widget (via file input selection, drag & drop or add API call).
|
61
79
|
// See the basic file upload widget for more information:
|
62
80
|
add: function (e, data) {
|
63
|
-
var that = $(this).data('fileupload')
|
64
|
-
|
81
|
+
var that = $(this).data('fileupload'),
|
82
|
+
options = that.options,
|
83
|
+
files = data.files;
|
84
|
+
that._adjustMaxNumberOfFiles(-files.length);
|
65
85
|
data.isAdjusted = true;
|
66
|
-
data.
|
67
|
-
|
68
|
-
.
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
86
|
+
$(this).fileupload('resize', data).done(data, function () {
|
87
|
+
data.files.valid = data.isValidated = that._validate(files);
|
88
|
+
data.context = that._renderUpload(files)
|
89
|
+
.appendTo(options.filesContainer)
|
90
|
+
.data('data', data);
|
91
|
+
that._renderPreviews(files, data.context);
|
92
|
+
that._forceReflow(data.context);
|
93
|
+
that._transition(data.context).done(
|
94
|
+
function () {
|
95
|
+
if ((that._trigger('added', e, data) !== false) &&
|
96
|
+
(options.autoUpload || data.autoUpload) &&
|
97
|
+
data.autoUpload !== false && data.isValidated) {
|
98
|
+
data.submit();
|
99
|
+
}
|
100
|
+
}
|
101
|
+
);
|
102
|
+
});
|
76
103
|
},
|
77
104
|
// Callback for the start of each file upload request:
|
78
105
|
send: function (e, data) {
|
106
|
+
var that = $(this).data('fileupload');
|
79
107
|
if (!data.isValidated) {
|
80
|
-
var that = $(this).data('fileupload');
|
81
108
|
if (!data.isAdjusted) {
|
82
109
|
that._adjustMaxNumberOfFiles(-data.files.length);
|
83
110
|
}
|
@@ -90,15 +117,22 @@
|
|
90
117
|
// Iframe Transport does not support progress events.
|
91
118
|
// In lack of an indeterminate progress bar, we set
|
92
119
|
// the progress to 100%, showing the full animated bar:
|
93
|
-
data.context
|
94
|
-
'
|
95
|
-
|
96
|
-
|
120
|
+
data.context
|
121
|
+
.find('.progress').addClass(
|
122
|
+
!$.support.transition && 'progress-animated'
|
123
|
+
)
|
124
|
+
.find('.bar').css(
|
125
|
+
'width',
|
126
|
+
parseInt(100, 10) + '%'
|
127
|
+
);
|
97
128
|
}
|
129
|
+
return that._trigger('sent', e, data);
|
98
130
|
},
|
99
131
|
// Callback for successful uploads:
|
100
132
|
done: function (e, data) {
|
101
|
-
var that = $(this).data('fileupload')
|
133
|
+
var that = $(this).data('fileupload'),
|
134
|
+
template,
|
135
|
+
preview;
|
102
136
|
if (data.context) {
|
103
137
|
data.context.each(function (index) {
|
104
138
|
var file = ($.isArray(data.result) &&
|
@@ -106,190 +140,133 @@
|
|
106
140
|
if (file.error) {
|
107
141
|
that._adjustMaxNumberOfFiles(1);
|
108
142
|
}
|
109
|
-
$(this).
|
110
|
-
|
111
|
-
|
112
|
-
.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
143
|
+
that._transition($(this)).done(
|
144
|
+
function () {
|
145
|
+
var node = $(this);
|
146
|
+
template = that._renderDownload([file])
|
147
|
+
.css('height', node.height())
|
148
|
+
.replaceAll(node);
|
149
|
+
that._forceReflow(template);
|
150
|
+
that._transition(template).done(
|
151
|
+
function () {
|
152
|
+
data.context = $(this);
|
153
|
+
that._trigger('completed', e, data);
|
154
|
+
}
|
155
|
+
);
|
156
|
+
}
|
157
|
+
);
|
118
158
|
});
|
119
159
|
} else {
|
120
|
-
that._renderDownload(data.result)
|
121
|
-
.
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
$(this)
|
126
|
-
|
160
|
+
template = that._renderDownload(data.result)
|
161
|
+
.appendTo(that.options.filesContainer);
|
162
|
+
that._forceReflow(template);
|
163
|
+
that._transition(template).done(
|
164
|
+
function () {
|
165
|
+
data.context = $(this);
|
166
|
+
that._trigger('completed', e, data);
|
167
|
+
}
|
168
|
+
);
|
127
169
|
}
|
128
170
|
},
|
129
171
|
// Callback for failed (abort or error) uploads:
|
130
172
|
fail: function (e, data) {
|
131
|
-
var that = $(this).data('fileupload')
|
173
|
+
var that = $(this).data('fileupload'),
|
174
|
+
template;
|
132
175
|
that._adjustMaxNumberOfFiles(data.files.length);
|
133
176
|
if (data.context) {
|
134
177
|
data.context.each(function (index) {
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
.
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
178
|
+
if (data.errorThrown !== 'abort') {
|
179
|
+
var file = data.files[index];
|
180
|
+
file.error = file.error || data.errorThrown ||
|
181
|
+
true;
|
182
|
+
that._transition($(this)).done(
|
183
|
+
function () {
|
184
|
+
var node = $(this);
|
185
|
+
template = that._renderDownload([file])
|
186
|
+
.replaceAll(node);
|
187
|
+
that._forceReflow(template);
|
188
|
+
that._transition(template).done(
|
189
|
+
function () {
|
190
|
+
data.context = $(this);
|
191
|
+
that._trigger('failed', e, data);
|
192
|
+
}
|
193
|
+
);
|
194
|
+
}
|
195
|
+
);
|
196
|
+
} else {
|
197
|
+
that._transition($(this)).done(
|
198
|
+
function () {
|
199
|
+
$(this).remove();
|
200
|
+
that._trigger('failed', e, data);
|
201
|
+
}
|
202
|
+
);
|
203
|
+
}
|
151
204
|
});
|
152
205
|
} else if (data.errorThrown !== 'abort') {
|
153
206
|
that._adjustMaxNumberOfFiles(-data.files.length);
|
154
207
|
data.context = that._renderUpload(data.files)
|
155
|
-
.
|
156
|
-
.
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
208
|
+
.appendTo(that.options.filesContainer)
|
209
|
+
.data('data', data);
|
210
|
+
that._forceReflow(data.context);
|
211
|
+
that._transition(data.context).done(
|
212
|
+
function () {
|
213
|
+
data.context = $(this);
|
214
|
+
that._trigger('failed', e, data);
|
215
|
+
}
|
216
|
+
);
|
217
|
+
} else {
|
218
|
+
that._trigger('failed', e, data);
|
161
219
|
}
|
162
220
|
},
|
163
221
|
// Callback for upload progress events:
|
164
222
|
progress: function (e, data) {
|
165
223
|
if (data.context) {
|
166
|
-
data.context.find('.
|
167
|
-
'
|
168
|
-
parseInt(data.loaded / data.total * 100, 10)
|
224
|
+
data.context.find('.progress .bar').css(
|
225
|
+
'width',
|
226
|
+
parseInt(data.loaded / data.total * 100, 10) + '%'
|
169
227
|
);
|
170
228
|
}
|
171
229
|
},
|
172
230
|
// Callback for global upload progress events:
|
173
231
|
progressall: function (e, data) {
|
174
|
-
$(this).find('.fileupload-
|
175
|
-
'
|
176
|
-
parseInt(data.loaded / data.total * 100, 10)
|
232
|
+
$(this).find('.fileupload-buttonbar .progress .bar').css(
|
233
|
+
'width',
|
234
|
+
parseInt(data.loaded / data.total * 100, 10) + '%'
|
177
235
|
);
|
178
236
|
},
|
179
237
|
// Callback for uploads start, equivalent to the global ajaxStart event:
|
180
|
-
start: function () {
|
181
|
-
$(this).
|
182
|
-
|
238
|
+
start: function (e) {
|
239
|
+
var that = $(this).data('fileupload');
|
240
|
+
that._transition($(this).find('.fileupload-buttonbar .progress')).done(
|
241
|
+
function () {
|
242
|
+
that._trigger('started', e);
|
243
|
+
}
|
244
|
+
);
|
183
245
|
},
|
184
246
|
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
185
|
-
stop: function () {
|
186
|
-
$(this).
|
247
|
+
stop: function (e) {
|
248
|
+
var that = $(this).data('fileupload');
|
249
|
+
that._transition($(this).find('.fileupload-buttonbar .progress')).done(
|
250
|
+
function () {
|
251
|
+
$(this).find('.bar').css('width', '0%');
|
252
|
+
that._trigger('stopped', e);
|
253
|
+
}
|
254
|
+
);
|
187
255
|
},
|
188
256
|
// Callback for file deletion:
|
189
257
|
destroy: function (e, data) {
|
190
258
|
var that = $(this).data('fileupload');
|
191
259
|
if (data.url) {
|
192
|
-
$.ajax(data)
|
193
|
-
.success(function () {
|
194
|
-
that._adjustMaxNumberOfFiles(1);
|
195
|
-
$(this).fadeOut(function () {
|
196
|
-
$(this).remove();
|
197
|
-
});
|
198
|
-
});
|
199
|
-
} else {
|
200
|
-
that._adjustMaxNumberOfFiles(1);
|
201
|
-
data.context.fadeOut(function () {
|
202
|
-
$(this).remove();
|
203
|
-
});
|
260
|
+
$.ajax(data);
|
204
261
|
}
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
// and the browser supports canvas, else the scaled image:
|
212
|
-
_scaleImage: function (img, options) {
|
213
|
-
options = options || {};
|
214
|
-
var canvas = document.createElement('canvas'),
|
215
|
-
scale = Math.min(
|
216
|
-
(options.maxWidth || img.width) / img.width,
|
217
|
-
(options.maxHeight || img.height) / img.height
|
218
|
-
);
|
219
|
-
if (scale >= 1) {
|
220
|
-
scale = Math.max(
|
221
|
-
(options.minWidth || img.width) / img.width,
|
222
|
-
(options.minHeight || img.height) / img.height
|
262
|
+
that._adjustMaxNumberOfFiles(1);
|
263
|
+
that._transition(data.context).done(
|
264
|
+
function () {
|
265
|
+
$(this).remove();
|
266
|
+
that._trigger('destroyed', e, data);
|
267
|
+
}
|
223
268
|
);
|
224
269
|
}
|
225
|
-
img.width = parseInt(img.width * scale, 10);
|
226
|
-
img.height = parseInt(img.height * scale, 10);
|
227
|
-
if (!options.canvas || !canvas.getContext) {
|
228
|
-
return img;
|
229
|
-
}
|
230
|
-
canvas.width = img.width;
|
231
|
-
canvas.height = img.height;
|
232
|
-
canvas.getContext('2d')
|
233
|
-
.drawImage(img, 0, 0, img.width, img.height);
|
234
|
-
return canvas;
|
235
|
-
},
|
236
|
-
|
237
|
-
_createObjectURL: function (file) {
|
238
|
-
var undef = 'undefined',
|
239
|
-
urlAPI = (typeof window.createObjectURL !== undef && window) ||
|
240
|
-
(typeof URL !== undef && URL) ||
|
241
|
-
(typeof webkitURL !== undef && webkitURL);
|
242
|
-
return urlAPI ? urlAPI.createObjectURL(file) : false;
|
243
|
-
},
|
244
|
-
|
245
|
-
_revokeObjectURL: function (url) {
|
246
|
-
var undef = 'undefined',
|
247
|
-
urlAPI = (typeof window.revokeObjectURL !== undef && window) ||
|
248
|
-
(typeof URL !== undef && URL) ||
|
249
|
-
(typeof webkitURL !== undef && webkitURL);
|
250
|
-
return urlAPI ? urlAPI.revokeObjectURL(url) : false;
|
251
|
-
},
|
252
|
-
|
253
|
-
// Loads a given File object via FileReader interface,
|
254
|
-
// invokes the callback with a data url:
|
255
|
-
_loadFile: function (file, callback) {
|
256
|
-
if (typeof FileReader !== 'undefined' &&
|
257
|
-
FileReader.prototype.readAsDataURL) {
|
258
|
-
var fileReader = new FileReader();
|
259
|
-
fileReader.onload = function (e) {
|
260
|
-
callback(e.target.result);
|
261
|
-
};
|
262
|
-
fileReader.readAsDataURL(file);
|
263
|
-
return true;
|
264
|
-
}
|
265
|
-
return false;
|
266
|
-
},
|
267
|
-
|
268
|
-
// Loads an image for a given File object.
|
269
|
-
// Invokes the callback with an img or optional canvas
|
270
|
-
// element (if supported by the browser) as parameter:
|
271
|
-
_loadImage: function (file, callback, options) {
|
272
|
-
var that = this,
|
273
|
-
url,
|
274
|
-
img;
|
275
|
-
if (!options || !options.fileTypes ||
|
276
|
-
options.fileTypes.test(file.type)) {
|
277
|
-
url = this._createObjectURL(file);
|
278
|
-
img = $('<img>').bind('load', function () {
|
279
|
-
$(this).unbind('load');
|
280
|
-
that._revokeObjectURL(url);
|
281
|
-
callback(that._scaleImage(img[0], options));
|
282
|
-
});
|
283
|
-
if (url) {
|
284
|
-
img.prop('src', url);
|
285
|
-
return true;
|
286
|
-
} else {
|
287
|
-
return this._loadFile(file, function (url) {
|
288
|
-
img.prop('src', url);
|
289
|
-
});
|
290
|
-
}
|
291
|
-
}
|
292
|
-
return false;
|
293
270
|
},
|
294
271
|
|
295
272
|
// Link handler, that allows to download files
|
@@ -297,8 +274,7 @@
|
|
297
274
|
_enableDragToDesktop: function () {
|
298
275
|
var link = $(this),
|
299
276
|
url = link.prop('href'),
|
300
|
-
name =
|
301
|
-
.replace(/:/g, '-'),
|
277
|
+
name = link.prop('download'),
|
302
278
|
type = 'application/octet-stream';
|
303
279
|
link.bind('dragstart', function (e) {
|
304
280
|
try {
|
@@ -321,17 +297,17 @@
|
|
321
297
|
}
|
322
298
|
},
|
323
299
|
|
324
|
-
_formatFileSize: function (
|
325
|
-
if (typeof
|
300
|
+
_formatFileSize: function (bytes) {
|
301
|
+
if (typeof bytes !== 'number') {
|
326
302
|
return '';
|
327
303
|
}
|
328
|
-
if (
|
329
|
-
return (
|
304
|
+
if (bytes >= 1000000000) {
|
305
|
+
return (bytes / 1000000000).toFixed(2) + ' GB';
|
330
306
|
}
|
331
|
-
if (
|
332
|
-
return (
|
307
|
+
if (bytes >= 1000000) {
|
308
|
+
return (bytes / 1000000).toFixed(2) + ' MB';
|
333
309
|
}
|
334
|
-
return (
|
310
|
+
return (bytes / 1000).toFixed(2) + ' KB';
|
335
311
|
},
|
336
312
|
|
337
313
|
_hasError: function (file) {
|
@@ -374,107 +350,92 @@
|
|
374
350
|
return valid;
|
375
351
|
},
|
376
352
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
);
|
353
|
+
_renderTemplate: function (func, files) {
|
354
|
+
if (!func) {
|
355
|
+
return $();
|
356
|
+
}
|
357
|
+
var result = func({
|
358
|
+
files: files,
|
359
|
+
formatFileSize: this._formatFileSize,
|
360
|
+
options: this.options
|
361
|
+
});
|
362
|
+
if (result instanceof $) {
|
363
|
+
return result;
|
364
|
+
}
|
365
|
+
return $(this.options.templatesContainer).html(result).children();
|
390
366
|
},
|
391
367
|
|
392
|
-
|
368
|
+
_renderPreview: function (file, node) {
|
393
369
|
var that = this,
|
394
370
|
options = this.options,
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
text: false,
|
412
|
-
icons: {primary: 'ui-icon-circle-arrow-e'}
|
413
|
-
});
|
414
|
-
tmpl.find('.cancel button').slice(1).remove().end().first()
|
415
|
-
.button({
|
416
|
-
text: false,
|
417
|
-
icons: {primary: 'ui-icon-cancel'}
|
418
|
-
});
|
419
|
-
tmpl.find('.preview').each(function (index, node) {
|
420
|
-
that._loadImage(
|
421
|
-
files[index],
|
422
|
-
function (img) {
|
423
|
-
$(img).hide().appendTo(node).fadeIn();
|
424
|
-
},
|
425
|
-
{
|
426
|
-
maxWidth: options.previewMaxWidth,
|
427
|
-
maxHeight: options.previewMaxHeight,
|
428
|
-
fileTypes: options.previewFileTypes,
|
429
|
-
canvas: options.previewAsCanvas
|
430
|
-
}
|
431
|
-
);
|
432
|
-
});
|
433
|
-
return tmpl;
|
371
|
+
deferred = $.Deferred();
|
372
|
+
return ((loadImage && loadImage(
|
373
|
+
file,
|
374
|
+
function (img) {
|
375
|
+
node.append(img);
|
376
|
+
that._forceReflow(node);
|
377
|
+
that._transition(node).done(function () {
|
378
|
+
deferred.resolveWith(node);
|
379
|
+
});
|
380
|
+
},
|
381
|
+
{
|
382
|
+
maxWidth: options.previewMaxWidth,
|
383
|
+
maxHeight: options.previewMaxHeight,
|
384
|
+
canvas: options.previewAsCanvas
|
385
|
+
}
|
386
|
+
)) || deferred.resolveWith(node)) && deferred;
|
434
387
|
},
|
435
388
|
|
436
|
-
|
437
|
-
|
438
|
-
|
389
|
+
_renderPreviews: function (files, nodes) {
|
390
|
+
var that = this,
|
391
|
+
options = this.options;
|
392
|
+
nodes.find('.preview span').each(function (index, element) {
|
393
|
+
var file = files[index];
|
394
|
+
if (options.previewSourceFileTypes.test(file.type) &&
|
395
|
+
($.type(options.previewSourceMaxFileSize) !== 'number' ||
|
396
|
+
file.size < options.previewSourceMaxFileSize)) {
|
397
|
+
that._processingQueue = that._processingQueue.pipe(function () {
|
398
|
+
var deferred = $.Deferred();
|
399
|
+
that._renderPreview(file, $(element)).done(
|
400
|
+
function () {
|
401
|
+
deferred.resolveWith(that);
|
402
|
+
}
|
403
|
+
);
|
404
|
+
return deferred.promise();
|
405
|
+
});
|
406
|
+
}
|
407
|
+
});
|
408
|
+
return this._processingQueue;
|
439
409
|
},
|
440
410
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
$.map(files, function (file) {
|
446
|
-
return that._downloadTemplateHelper(file);
|
447
|
-
})
|
411
|
+
_renderUpload: function (files) {
|
412
|
+
return this._renderTemplate(
|
413
|
+
this.options.uploadTemplate,
|
414
|
+
files
|
448
415
|
);
|
449
416
|
},
|
450
417
|
|
451
418
|
_renderDownload: function (files) {
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
tmpl.css('display', 'none');
|
457
|
-
tmpl.find('.delete button').button({
|
458
|
-
text: false,
|
459
|
-
icons: {primary: 'ui-icon-trash'}
|
460
|
-
});
|
461
|
-
tmpl.find('a').each(this._enableDragToDesktop);
|
462
|
-
return tmpl;
|
419
|
+
return this._renderTemplate(
|
420
|
+
this.options.downloadTemplate,
|
421
|
+
files
|
422
|
+
).find('a[download]').each(this._enableDragToDesktop).end();
|
463
423
|
},
|
464
424
|
|
465
425
|
_startHandler: function (e) {
|
466
426
|
e.preventDefault();
|
467
|
-
var
|
468
|
-
|
427
|
+
var button = $(this),
|
428
|
+
template = button.closest('.template-upload'),
|
429
|
+
data = template.data('data');
|
469
430
|
if (data && data.submit && !data.jqXHR && data.submit()) {
|
470
|
-
|
431
|
+
button.prop('disabled', true);
|
471
432
|
}
|
472
433
|
},
|
473
434
|
|
474
435
|
_cancelHandler: function (e) {
|
475
436
|
e.preventDefault();
|
476
|
-
var
|
477
|
-
data =
|
437
|
+
var template = $(this).closest('.template-upload'),
|
438
|
+
data = template.data('data') || {};
|
478
439
|
if (!data.jqXHR) {
|
479
440
|
data.errorThrown = 'abort';
|
480
441
|
e.data.fileupload._trigger('fail', e, data);
|
@@ -489,72 +450,59 @@
|
|
489
450
|
e.data.fileupload._trigger('destroy', e, {
|
490
451
|
context: button.closest('.template-download'),
|
491
452
|
url: button.attr('data-url'),
|
492
|
-
type: button.attr('data-type'),
|
453
|
+
type: button.attr('data-type') || 'DELETE',
|
493
454
|
dataType: e.data.fileupload.options.dataType
|
494
455
|
});
|
495
456
|
},
|
496
457
|
|
497
|
-
|
498
|
-
$.
|
499
|
-
|
500
|
-
this.element.find('.files')
|
501
|
-
.delegate(
|
502
|
-
'.start button',
|
503
|
-
'click.' + this.options.namespace,
|
504
|
-
eventData,
|
505
|
-
this._startHandler
|
506
|
-
)
|
507
|
-
.delegate(
|
508
|
-
'.cancel button',
|
509
|
-
'click.' + this.options.namespace,
|
510
|
-
eventData,
|
511
|
-
this._cancelHandler
|
512
|
-
)
|
513
|
-
.delegate(
|
514
|
-
'.delete button',
|
515
|
-
'click.' + this.options.namespace,
|
516
|
-
eventData,
|
517
|
-
this._deleteHandler
|
518
|
-
);
|
458
|
+
_forceReflow: function (node) {
|
459
|
+
this._reflow = $.support.transition &&
|
460
|
+
node.length && node[0].offsetWidth;
|
519
461
|
},
|
520
462
|
|
521
|
-
|
522
|
-
this
|
523
|
-
|
524
|
-
|
525
|
-
.
|
526
|
-
|
463
|
+
_transition: function (node) {
|
464
|
+
var that = this,
|
465
|
+
deferred = $.Deferred();
|
466
|
+
if ($.support.transition && node.hasClass('fade')) {
|
467
|
+
node.bind(
|
468
|
+
$.support.transition.end,
|
469
|
+
function (e) {
|
470
|
+
// Make sure we don't respond to other transitions events
|
471
|
+
// in the container element, e.g. from button elements:
|
472
|
+
if (e.target === node[0]) {
|
473
|
+
node.unbind($.support.transition.end);
|
474
|
+
deferred.resolveWith(node);
|
475
|
+
}
|
476
|
+
}
|
477
|
+
).toggleClass('in');
|
478
|
+
} else {
|
479
|
+
node.toggleClass('in');
|
480
|
+
deferred.resolveWith(node);
|
481
|
+
}
|
482
|
+
return deferred;
|
527
483
|
},
|
528
484
|
|
529
|
-
|
485
|
+
_initButtonBarEventHandlers: function () {
|
530
486
|
var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
|
531
|
-
filesList = this.
|
487
|
+
filesList = this.options.filesContainer,
|
532
488
|
ns = this.options.namespace;
|
533
|
-
fileUploadButtonBar
|
534
|
-
.addClass('ui-widget-header ui-corner-top');
|
535
|
-
this.element.find('.fileinput-button').each(function () {
|
536
|
-
var fileInput = $(this).find('input:file').detach();
|
537
|
-
$(this).button({icons: {primary: 'ui-icon-plusthick'}})
|
538
|
-
.append(fileInput);
|
539
|
-
});
|
540
489
|
fileUploadButtonBar.find('.start')
|
541
|
-
.button({icons: {primary: 'ui-icon-circle-arrow-e'}})
|
542
490
|
.bind('click.' + ns, function (e) {
|
543
491
|
e.preventDefault();
|
544
492
|
filesList.find('.start button').click();
|
545
493
|
});
|
546
494
|
fileUploadButtonBar.find('.cancel')
|
547
|
-
.button({icons: {primary: 'ui-icon-cancel'}})
|
548
495
|
.bind('click.' + ns, function (e) {
|
549
496
|
e.preventDefault();
|
550
497
|
filesList.find('.cancel button').click();
|
551
498
|
});
|
552
499
|
fileUploadButtonBar.find('.delete')
|
553
|
-
.button({icons: {primary: 'ui-icon-trash'}})
|
554
500
|
.bind('click.' + ns, function (e) {
|
555
501
|
e.preventDefault();
|
556
502
|
filesList.find('.delete input:checked')
|
557
503
|
.siblings('button').click();
|
504
|
+
fileUploadButtonBar.find('.toggle')
|
505
|
+
.prop('checked', false);
|
558
506
|
});
|
559
507
|
fileUploadButtonBar.find('.toggle')
|
560
508
|
.bind('change.' + ns, function (e) {
|
@@ -565,94 +513,117 @@
|
|
565
513
|
});
|
566
514
|
},
|
567
515
|
|
568
|
-
|
569
|
-
this.element.find('.fileupload-buttonbar')
|
570
|
-
.removeClass('ui-widget-header ui-corner-top');
|
571
|
-
this.element.find('.fileinput-button').each(function () {
|
572
|
-
var fileInput = $(this).find('input:file').detach();
|
573
|
-
$(this).button('destroy')
|
574
|
-
.append(fileInput);
|
575
|
-
});
|
516
|
+
_destroyButtonBarEventHandlers: function () {
|
576
517
|
this.element.find('.fileupload-buttonbar button')
|
577
|
-
.unbind('click.' + this.options.namespace)
|
578
|
-
.button('destroy');
|
518
|
+
.unbind('click.' + this.options.namespace);
|
579
519
|
this.element.find('.fileupload-buttonbar .toggle')
|
580
520
|
.unbind('change.' + this.options.namespace);
|
581
521
|
},
|
582
522
|
|
523
|
+
_initEventHandlers: function () {
|
524
|
+
parentWidget.prototype._initEventHandlers.call(this);
|
525
|
+
var eventData = {fileupload: this};
|
526
|
+
this.options.filesContainer
|
527
|
+
.delegate(
|
528
|
+
'.start button',
|
529
|
+
'click.' + this.options.namespace,
|
530
|
+
eventData,
|
531
|
+
this._startHandler
|
532
|
+
)
|
533
|
+
.delegate(
|
534
|
+
'.cancel button',
|
535
|
+
'click.' + this.options.namespace,
|
536
|
+
eventData,
|
537
|
+
this._cancelHandler
|
538
|
+
)
|
539
|
+
.delegate(
|
540
|
+
'.delete button',
|
541
|
+
'click.' + this.options.namespace,
|
542
|
+
eventData,
|
543
|
+
this._deleteHandler
|
544
|
+
);
|
545
|
+
this._initButtonBarEventHandlers();
|
546
|
+
},
|
547
|
+
|
548
|
+
_destroyEventHandlers: function () {
|
549
|
+
var options = this.options;
|
550
|
+
this._destroyButtonBarEventHandlers();
|
551
|
+
options.filesContainer
|
552
|
+
.undelegate('.start button', 'click.' + options.namespace)
|
553
|
+
.undelegate('.cancel button', 'click.' + options.namespace)
|
554
|
+
.undelegate('.delete button', 'click.' + options.namespace);
|
555
|
+
parentWidget.prototype._destroyEventHandlers.call(this);
|
556
|
+
},
|
557
|
+
|
583
558
|
_enableFileInputButton: function () {
|
584
|
-
this.element.find('.fileinput-button input
|
585
|
-
.
|
586
|
-
|
587
|
-
button = fileInput.parent();
|
588
|
-
fileInput.detach().prop('disabled', false);
|
589
|
-
button.button('enable').append(fileInput);
|
590
|
-
});
|
559
|
+
this.element.find('.fileinput-button input')
|
560
|
+
.prop('disabled', false)
|
561
|
+
.parent().removeClass('disabled');
|
591
562
|
},
|
592
563
|
|
593
564
|
_disableFileInputButton: function () {
|
594
|
-
this.element.find('.fileinput-button input
|
595
|
-
.
|
596
|
-
|
597
|
-
button = fileInput.parent();
|
598
|
-
fileInput.detach().prop('disabled', true);
|
599
|
-
button.button('disable').append(fileInput);
|
600
|
-
});
|
565
|
+
this.element.find('.fileinput-button input')
|
566
|
+
.prop('disabled', true)
|
567
|
+
.parent().addClass('disabled');
|
601
568
|
},
|
602
569
|
|
603
570
|
_initTemplates: function () {
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
571
|
+
var options = this.options;
|
572
|
+
options.templatesContainer = document.createElement(
|
573
|
+
options.filesContainer.prop('nodeName')
|
574
|
+
);
|
575
|
+
if (tmpl) {
|
576
|
+
if (options.uploadTemplateId) {
|
577
|
+
options.uploadTemplate = tmpl(options.uploadTemplateId);
|
578
|
+
}
|
579
|
+
if (options.downloadTemplateId) {
|
580
|
+
options.downloadTemplate = tmpl(options.downloadTemplateId);
|
581
|
+
}
|
611
582
|
}
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
583
|
+
},
|
584
|
+
|
585
|
+
_initFilesContainer: function () {
|
586
|
+
var options = this.options;
|
587
|
+
if (options.filesContainer === undefined) {
|
588
|
+
options.filesContainer = this.element.find('.files');
|
589
|
+
} else if (!(options.filesContainer instanceof $)) {
|
590
|
+
options.filesContainer = $(options.filesContainer);
|
617
591
|
}
|
618
592
|
},
|
619
593
|
|
620
|
-
|
621
|
-
|
594
|
+
_initSpecialOptions: function () {
|
595
|
+
parentWidget.prototype._initSpecialOptions.call(this);
|
596
|
+
this._initFilesContainer();
|
622
597
|
this._initTemplates();
|
623
|
-
this.element
|
624
|
-
.addClass('ui-widget');
|
625
|
-
this._initFileUploadButtonBar();
|
626
|
-
this.element.find('.fileupload-content')
|
627
|
-
.addClass('ui-widget-content ui-corner-bottom');
|
628
|
-
this.element.find('.fileupload-progressbar')
|
629
|
-
.hide().progressbar();
|
630
598
|
},
|
631
599
|
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
600
|
+
_create: function () {
|
601
|
+
parentWidget.prototype._create.call(this);
|
602
|
+
this._refreshOptionsList.push(
|
603
|
+
'filesContainer',
|
604
|
+
'uploadTemplateId',
|
605
|
+
'downloadTemplateId'
|
606
|
+
);
|
607
|
+
if (!$.blueimpIP) {
|
608
|
+
this._processingQueue = $.Deferred().resolveWith(this).promise();
|
609
|
+
this.resize = function () {
|
610
|
+
return this._processingQueue;
|
611
|
+
};
|
612
|
+
}
|
640
613
|
},
|
641
614
|
|
642
615
|
enable: function () {
|
643
|
-
|
644
|
-
this.element.find('
|
645
|
-
.button('enable');
|
616
|
+
parentWidget.prototype.enable.call(this);
|
617
|
+
this.element.find('input, button').prop('disabled', false);
|
646
618
|
this._enableFileInputButton();
|
647
619
|
},
|
648
620
|
|
649
621
|
disable: function () {
|
650
|
-
this.element.find('
|
651
|
-
.button('disable');
|
622
|
+
this.element.find('input, button').prop('disabled', true);
|
652
623
|
this._disableFileInputButton();
|
653
|
-
|
624
|
+
parentWidget.prototype.disable.call(this);
|
654
625
|
}
|
655
626
|
|
656
627
|
});
|
657
628
|
|
658
|
-
}
|
629
|
+
}));
|