This repository has been archived by the owner on Sep 8, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 74
/
uploader.js
171 lines (138 loc) · 4.98 KB
/
uploader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* Author: Remy Alain Ticona Carbajal http://realtica.org
* Description: The main objective of ng-uploader is to have a user control,
* clean, simple, customizable, and above all very easy to implement.
* Licence: MIT
*/
angular.module('ui.uploader', []).service('uiUploader', uiUploader);
uiUploader.$inject = ['$log'];
function uiUploader($log) {
/*jshint validthis: true */
var self = this;
self.files = [];
self.options = {};
self.activeUploads = 0;
self.uploadedFiles = 0;
$log.info('uiUploader loaded');
function addFiles(files) {
for (var i = 0; i < files.length; i++) {
self.files.push(files[i]);
}
}
function getFiles() {
return self.files;
}
function startUpload(options) {
self.options = options;
//headers are not shared by requests
var headers = options.headers || {};
var xhrOptions = options.options || {};
for (var i = 0; i < self.files.length; i++) {
if (self.activeUploads == self.options.concurrency) {
break;
}
if (self.files[i].active)
continue;
ajaxUpload(self.files[i], self.options.url, self.options.data, self.options.paramName, headers, xhrOptions);
}
}
function removeFile(file) {
self.files.splice(self.files.indexOf(file), 1);
}
function removeAll() {
self.files.splice(0, self.files.length);
}
return {
addFiles: addFiles,
getFiles: getFiles,
files: self.files,
startUpload: startUpload,
removeFile: removeFile,
removeAll: removeAll
};
function getHumanSize(bytes) {
var sizes = ['n/a', 'bytes', 'KiB', 'MiB', 'GiB', 'TB', 'PB', 'EiB', 'ZiB', 'YiB'];
var i = (bytes === 0) ? 0 : +Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, i)).toFixed(i ? 1 : 0) + ' ' + sizes[isNaN(bytes) ? 0 : i + 1];
}
function ajaxUpload(file, url, data, key, headers, xhrOptions) {
var xhr, formData, prop;
data = data || {};
key = key || 'file';
self.activeUploads += 1;
file.active = true;
xhr = new window.XMLHttpRequest();
// To account for sites that may require CORS
if (xhrOptions.withCredentials === true) {
xhr.withCredentials = true;
}
formData = new window.FormData();
xhr.open('POST', url);
if (headers) {
for (var headerKey in headers) {
if (headers.hasOwnProperty(headerKey)) {
xhr.setRequestHeader(headerKey, headers[headerKey]);
}
}
}
// Triggered when upload starts:
xhr.upload.onloadstart = function() {
};
// Triggered many times during upload:
xhr.upload.onprogress = function(event) {
if (!event.lengthComputable) {
return;
}
// Update file size because it might be bigger than reported by
// the fileSize:
//$log.info("progres..");
//console.info(event.loaded);
file.loaded = event.loaded;
file.humanSize = getHumanSize(event.loaded);
if (angular.isFunction(self.options.onProgress)) {
self.options.onProgress(file);
}
};
// Triggered when the upload is successful (the server may not have responded yet).
xhr.upload.onload = function() {
if (angular.isFunction(self.options.onUploadSuccess)) {
self.options.onUploadSuccess(file);
}
};
// Triggered when upload fails:
xhr.upload.onerror = function(e) {
if (angular.isFunction(self.options.onError)) {
self.options.onError(e);
}
};
// Triggered when the upload has completed AND the server has responded. Equivalent to
// listening for the readystatechange event when xhr.readyState === XMLHttpRequest.DONE.
xhr.onload = function () {
self.activeUploads -= 1;
self.uploadedFiles += 1;
startUpload(self.options);
if (angular.isFunction(self.options.onCompleted)) {
self.options.onCompleted(file, xhr.responseText, xhr.status);
}
if (self.activeUploads === 0) {
self.uploadedFiles = 0;
if (angular.isFunction(self.options.onCompletedAll)) {
self.options.onCompletedAll(self.files);
}
}
};
// Append additional data if provided:
if (data) {
for (prop in data) {
if (data.hasOwnProperty(prop)) {
formData.append(prop, data[prop]);
}
}
}
// Append file data:
formData.append(key, file, file.name);
// Initiate upload:
xhr.send(formData);
return xhr;
}
}