Skip to content

Commit 0cda909

Browse files
committed
Minified version
1 parent a39eec5 commit 0cda909

File tree

5 files changed

+247
-21
lines changed

5 files changed

+247
-21
lines changed

Gruntfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ module.exports = function (grunt) {
1414
src: [
1515
'src/<%= library.name %>/<%= library.name %>.prefix',
1616
'src/<%= library.name %>/<%= library.name %>.js',
17+
'src/<%= library.name %>/services/**/*.js',
1718
'src/<%= library.name %>/directives/**/*.js',
1819
'src/<%= library.name %>/filters/**/*.js',
19-
'src/<%= library.name %>/services/**/*.js',
2020
'src/<%= library.name %>/<%= library.name %>.suffix'
2121
],
2222
dest: 'build/<%= library.name %>.js'

build/ng-s3upload.js

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
(function(window, document) {
2+
3+
// Create all modules and define dependencies to make sure they exist
4+
// and are loaded in the correct order to satisfy dependency injection
5+
// before all nested files are concatenated by Grunt
6+
7+
// Config
8+
angular.module('ngS3upload.config', []).
9+
value('ngS3upload.config', {
10+
debug: true
11+
}).
12+
config(['$compileProvider', function($compileProvider){
13+
if (angular.isDefined($compileProvider.urlSanitizationWhitelist)) {
14+
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|data):/);
15+
} else {
16+
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|data):/);
17+
}
18+
}]);
19+
20+
// Modules
21+
angular.module('ngS3upload.directives', []);
22+
angular.module('ngS3upload',
23+
[
24+
'ngS3upload.config',
25+
'ngS3upload.directives',
26+
'ngS3upload.services',
27+
'ngSanitize'
28+
]);
29+
angular.module('ngS3upload.services', []).
30+
service('S3Uploader', ['$http', '$q', '$window', function ($http, $q, $window) {
31+
this.uploads = 0;
32+
var self = this;
33+
34+
this.getUploadOptions = function (uri) {
35+
var deferred = $q.defer();
36+
$http.get(uri).
37+
success(function (response, status) {
38+
deferred.resolve(response);
39+
}).error(function (error, status) {
40+
deferred.reject(error);
41+
});
42+
43+
return deferred.promise;
44+
};
45+
46+
this.randomString = function (length) {
47+
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
48+
var result = '';
49+
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
50+
51+
return result;
52+
};
53+
54+
55+
this.upload = function (scope, uri, key, acl, type, accessKey, policy, signature, file) {
56+
var deferred = $q.defer();
57+
scope.attempt = true;
58+
59+
var fd = new FormData();
60+
fd.append('key', key);
61+
fd.append('acl', acl);
62+
fd.append('Content-Type', file.type);
63+
fd.append('AWSAccessKeyId', accessKey);
64+
fd.append('policy', policy);
65+
fd.append('signature', signature);
66+
fd.append("file", file);
67+
68+
var xhr = new XMLHttpRequest();
69+
xhr.upload.addEventListener("progress", uploadProgress, false);
70+
xhr.addEventListener("load", uploadComplete, false);
71+
xhr.addEventListener("error", uploadFailed, false);
72+
xhr.addEventListener("abort", uploadCanceled, false);
73+
74+
// Define event handlers
75+
function uploadProgress(e) {
76+
scope.$apply(function () {
77+
if (e.lengthComputable) {
78+
scope.progress = Math.round(e.loaded * 100 / e.total);
79+
} else {
80+
scope.progress = 'unable to compute';
81+
}
82+
});
83+
}
84+
function uploadComplete(e) {
85+
scope.$apply(function () {
86+
self.uploads--;
87+
scope.uploading = false;
88+
scope.success = true;
89+
deferred.resolve();
90+
});
91+
}
92+
function uploadFailed(e) {
93+
scope.$apply(function () {
94+
self.uploads--;
95+
scope.uploading = false;
96+
scope.success = false;
97+
deferred.reject();
98+
});
99+
}
100+
function uploadCanceled(e) {
101+
scope.$apply(function () {
102+
self.uploads--;
103+
scope.uploading = false;
104+
scope.success = false;
105+
deferred.reject();
106+
});
107+
}
108+
109+
// Send the file
110+
scope.uploading = true;
111+
this.uploads++;
112+
xhr.open('POST', uri, true);
113+
xhr.send(fd);
114+
115+
return deferred.promise;
116+
};
117+
118+
this.isUploading = function () {
119+
return this.uploads > 0;
120+
};
121+
}]);
122+
angular.module('ngS3upload.directives', []).
123+
directive('s3Upload', ['$parse', 'S3Uploader', function ($parse, S3Uploader) {
124+
return {
125+
restrict: 'AC',
126+
require: '?ngModel',
127+
replace: true,
128+
transclude: false,
129+
scope: true,
130+
controller: ['$scope', '$element', '$attrs', '$transclude', function ($scope, $element, $attrs, $transclude) {
131+
$scope.attempt = false;
132+
$scope.success = false;
133+
$scope.uploading = false;
134+
135+
$scope.barClass = function () {
136+
return {
137+
"bar-success": $scope.attempt && !$scope.uploading && $scope.success
138+
};
139+
};
140+
}],
141+
compile: function (element, attr, linker) {
142+
return {
143+
pre: function ($scope, $element, $attr) {
144+
if (angular.isUndefined($attr.bucket)) {
145+
throw Error('bucket is a mandatory attribute');
146+
}
147+
},
148+
post: function (scope, element, attrs, ngModel) {
149+
// Build the opts array
150+
var opts = angular.extend({}, scope.$eval(attrs.s3UploadOptions || attrs.options));
151+
opts = angular.extend({
152+
submitOnChange: true,
153+
getOptionsUri: '/getS3Options',
154+
acl: 'public-read',
155+
uploadingKey: 'uploading',
156+
folder: ''
157+
}, opts);
158+
var bucket = scope.$eval(attrs.bucket);
159+
160+
// Bind the button click event
161+
var button = angular.element(element.children()[0]),
162+
file = angular.element(element.find("input")[0]);
163+
button.bind('click', function (e) {
164+
file[0].click();
165+
});
166+
167+
// Update the scope with the view value
168+
ngModel.$render = function () {
169+
scope.filename = ngModel.$viewValue;
170+
};
171+
172+
var uploadFile = function () {
173+
var selectedFile = file[0].files[0];
174+
var filename = selectedFile.name;
175+
var ext = filename.split('.').pop();
176+
177+
scope.$apply(function () {
178+
S3Uploader.getUploadOptions(opts.getOptionsUri).then(function (s3Options) {
179+
ngModel.$setValidity('uploading', false);
180+
var s3Uri = 'https://' + bucket + '.s3.amazonaws.com/' + opts.folder;
181+
var key = (new Date()).getTime() + '-' + S3Uploader.randomString(16) + "." + ext;
182+
S3Uploader.upload(scope,
183+
s3Uri,
184+
key,
185+
opts.acl,
186+
selectedFile.type,
187+
s3Options.key,
188+
s3Options.policy,
189+
s3Options.signature,
190+
selectedFile
191+
).then(function () {
192+
ngModel.$setViewValue(s3Uri + key);
193+
scope.filename = ngModel.$viewValue;
194+
ngModel.$setValidity('uploading', true);
195+
ngModel.$setValidity('succeeded', true);
196+
}, function () {
197+
scope.filename = ngModel.$viewValue;
198+
ngModel.$setValidity('uploading', true);
199+
ngModel.$setValidity('succeeded', false);
200+
});
201+
202+
}, function (error) {
203+
throw Error("Can't receive the needed options for S3 " + error);
204+
});
205+
});
206+
};
207+
208+
element.bind('change', function (nVal) {
209+
if (opts.submitOnChange) {
210+
uploadFile();
211+
}
212+
});
213+
}
214+
};
215+
},
216+
template: '<div class="upload-wrap">' +
217+
'<button class="btn btn-primary" type="button"><span ng-if="!filename">Choose file</span><span ng-if="filename">Replace file</span></button>' +
218+
'<a ng-href="{{ filename }}" target="_blank" class="" ng-if="filename" > Stored file </a>' +
219+
'<div class="progress progress-striped" ng-class="{active: uploading}" ng-show="attempt" style="margin-top: 10px">' +
220+
'<div class="bar" style="width: {{ progress }}%;" ng-class="barClass()"></div>' +
221+
'</div>' +
222+
'<input type="file" style="display: none"/>' +
223+
'</div>'
224+
};
225+
}]);
226+
})(window, document);

build/ng-s3upload.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ng-s3upload/directives/s3-upload.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ angular.module('ngS3upload.directives', []).
5454
var ext = filename.split('.').pop();
5555

5656
scope.$apply(function () {
57-
S3Uploader.getUploadOptions(opts['getOptionsUri']).then(function (s3Options) {
57+
S3Uploader.getUploadOptions(opts.getOptionsUri).then(function (s3Options) {
5858
ngModel.$setValidity('uploading', false);
59-
var s3Uri = 'https://' + bucket + '.s3.amazonaws.com/' + opts['folder'];
60-
var key = (new Date).getTime() + '-' + S3Uploader.randomString(16) + "." + ext;
59+
var s3Uri = 'https://' + bucket + '.s3.amazonaws.com/' + opts.folder;
60+
var key = (new Date()).getTime() + '-' + S3Uploader.randomString(16) + "." + ext;
6161
S3Uploader.upload(scope,
6262
s3Uri,
6363
key,
64-
opts['acl'],
64+
opts.acl,
6565
selectedFile.type,
6666
s3Options.key,
6767
s3Options.policy,
@@ -85,13 +85,12 @@ angular.module('ngS3upload.directives', []).
8585
};
8686

8787
element.bind('change', function (nVal) {
88-
if (opts['submitOnChange']) {
88+
if (opts.submitOnChange) {
8989
uploadFile();
9090
}
9191
});
92-
9392
}
94-
}
93+
};
9594
},
9695
template: '<div class="upload-wrap">' +
9796
'<button class="btn btn-primary" type="button"><span ng-if="!filename">Choose file</span><span ng-if="filename">Replace file</span></button>' +
@@ -101,5 +100,5 @@ angular.module('ngS3upload.directives', []).
101100
'</div>' +
102101
'<input type="file" style="display: none"/>' +
103102
'</div>'
104-
}
105-
}]);
103+
};
104+
}]);

src/ng-s3upload/services/s3-uploader.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ angular.module('ngS3upload.services', []).
1313
});
1414

1515
return deferred.promise;
16-
}
16+
};
1717

1818
this.randomString = function (length) {
1919
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
2020
var result = '';
2121
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
2222

2323
return result;
24-
}
24+
};
2525

2626

2727
this.upload = function (scope, uri, key, acl, type, accessKey, policy, signature, file) {
@@ -52,31 +52,31 @@ angular.module('ngS3upload.services', []).
5252
scope.progress = 'unable to compute';
5353
}
5454
});
55-
};
55+
}
5656
function uploadComplete(e) {
5757
scope.$apply(function () {
5858
self.uploads--;
5959
scope.uploading = false;
6060
scope.success = true;
6161
deferred.resolve();
6262
});
63-
};
63+
}
6464
function uploadFailed(e) {
6565
scope.$apply(function () {
6666
self.uploads--;
6767
scope.uploading = false;
6868
scope.success = false;
6969
deferred.reject();
7070
});
71-
};
71+
}
7272
function uploadCanceled(e) {
7373
scope.$apply(function () {
7474
self.uploads--;
7575
scope.uploading = false;
7676
scope.success = false;
7777
deferred.reject();
7878
});
79-
};
79+
}
8080

8181
// Send the file
8282
scope.uploading = true;
@@ -85,10 +85,9 @@ angular.module('ngS3upload.services', []).
8585
xhr.send(fd);
8686

8787
return deferred.promise;
88-
}
88+
};
8989

9090
this.isUploading = function () {
91-
this.uploads > 0;
92-
}
93-
94-
}]);
91+
return this.uploads > 0;
92+
};
93+
}]);

0 commit comments

Comments
 (0)