Skip to content

Commit a39eec5

Browse files
committed
First version
1 parent fb1159b commit a39eec5

File tree

12 files changed

+437
-0
lines changed

12 files changed

+437
-0
lines changed

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
bower_components
3+
.idea
4+

.jshintrc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"node": true,
3+
"es5": true,
4+
"esnext": true,
5+
"bitwise": true,
6+
"camelcase": true,
7+
"curly": true,
8+
"eqeqeq": true,
9+
"immed": true,
10+
"indent": 4,
11+
"latedef": true,
12+
"newcap": true,
13+
"noarg": true,
14+
"quotmark": "single",
15+
"regexp": true,
16+
"undef": true,
17+
"unused": true,
18+
"strict": true,
19+
"trailing": true,
20+
"smarttabs": true,
21+
"white": true
22+
}

Gruntfile.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
module.exports = function (grunt) {
2+
// * Read command-line switches
3+
// - Read in --browsers CLI option; split it on commas into an array if it's a string, otherwise ignore it
4+
var browsers = typeof grunt.option('browsers') == 'string' ? grunt.option('browsers').split(',') : undefined;
5+
6+
grunt.initConfig({
7+
pkg: grunt.file.readJSON('package.json'),
8+
library: grunt.file.readJSON('bower.json'),
9+
concat: {
10+
options: {
11+
separator: ''
12+
},
13+
library: {
14+
src: [
15+
'src/<%= library.name %>/<%= library.name %>.prefix',
16+
'src/<%= library.name %>/<%= library.name %>.js',
17+
'src/<%= library.name %>/directives/**/*.js',
18+
'src/<%= library.name %>/filters/**/*.js',
19+
'src/<%= library.name %>/services/**/*.js',
20+
'src/<%= library.name %>/<%= library.name %>.suffix'
21+
],
22+
dest: 'build/<%= library.name %>.js'
23+
}
24+
},
25+
uglify: {
26+
options: {
27+
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
28+
},
29+
jid: {
30+
files: {
31+
'build/<%= library.name %>.min.js': ['<%= concat.library.dest %>']
32+
}
33+
}
34+
},
35+
jshint: {
36+
beforeConcat: {
37+
src: ['gruntfile.js', '<%= library.name %>/**/*.js']
38+
},
39+
afterConcat: {
40+
src: [
41+
'<%= concat.library.dest %>'
42+
]
43+
},
44+
options: {
45+
// options here to override JSHint defaults
46+
globals: {
47+
jQuery: true,
48+
console: true,
49+
module: true,
50+
document: true,
51+
angular: true
52+
},
53+
globalstrict: false
54+
}
55+
},
56+
testFiles: {
57+
karmaUnit: 'karma.conf.js'
58+
},
59+
karma: {
60+
unit: {
61+
options: {
62+
configFile: '<%= testFiles.karmaUnit %>',
63+
autoWatch: false,
64+
singleRun: true,
65+
browsers: browsers || ['Chrome']
66+
}
67+
}
68+
},
69+
watch: {
70+
options: {
71+
livereload: true
72+
},
73+
files: [
74+
'Gruntfile.js',
75+
'src/**/*'
76+
],
77+
tasks: ['default']
78+
}
79+
});
80+
81+
// Load grunt-karma task plugin
82+
grunt.loadNpmTasks('grunt-karma');
83+
84+
grunt.loadNpmTasks('grunt-contrib-uglify');
85+
grunt.loadNpmTasks('grunt-contrib-jshint');
86+
grunt.loadNpmTasks('grunt-contrib-concat');
87+
grunt.loadNpmTasks('grunt-contrib-watch');
88+
89+
grunt.registerTask('test', ['jshint', 'karma:unit']);
90+
grunt.registerTask('default', ['jshint:beforeConcat', 'concat', 'jshint:afterConcat', 'uglify']);
91+
grunt.registerTask('livereload', ['default', 'watch']);
92+
93+
};

bower.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "ng-s3upload",
3+
"version": "0.0.1",
4+
"dependencies": {
5+
"angular": "~1.0.7",
6+
"angular-sanitize": "~1.0.7"
7+
},
8+
"devDependencies": {
9+
"angular-mocks": "~1.0.7",
10+
"angular-scenario": "~1.0.7"
11+
}
12+
}
13+

karma.conf.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
basePath = '';
2+
3+
files = [
4+
JASMINE,
5+
JASMINE_ADAPTER,
6+
7+
// Libraries
8+
'bower_components/angular/angular.js',
9+
'bower_components/angular-sanitize/angular-sanitize.js',
10+
'bower_components/angular-mocks/angular-mocks.js',
11+
12+
// App
13+
'src/ng-s3upload/*.js',
14+
'src/ng-s3upload/directives/*.js',
15+
'src/ng-s3upload/services/*.js',
16+
17+
// Test specs
18+
'test/unit/**/*.js',
19+
'test/unit/**/**/*.js'
20+
];
21+
22+
autoWatch = true;
23+
24+
browsers = ['Chrome'];
25+
26+
// reporters = ['progress'];
27+
28+
junitReporter = {
29+
outputFile: 'test_out/unit.xml',
30+
suite: 'unit'
31+
};

package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "ngs3upload",
3+
"version": "0.0.0",
4+
"dependencies": {},
5+
"devDependencies": {
6+
"grunt": "~0.4.1",
7+
"grunt-contrib-copy": "~0.4.1",
8+
"grunt-contrib-concat": "~0.3.0",
9+
"grunt-contrib-coffee": "~0.7.0",
10+
"grunt-contrib-uglify": "~0.2.0",
11+
"grunt-contrib-compass": "~0.3.0",
12+
"grunt-contrib-jshint": "~0.6.0",
13+
"grunt-contrib-cssmin": "~0.6.0",
14+
"grunt-contrib-connect": "~0.3.0",
15+
"grunt-contrib-clean": "~0.4.1",
16+
"grunt-contrib-htmlmin": "~0.1.3",
17+
"grunt-contrib-imagemin": "~0.1.4",
18+
"grunt-contrib-watch": "~0.4.0",
19+
"grunt-usemin": "~0.1.11",
20+
"grunt-svgmin": "~0.2.0",
21+
"grunt-rev": "~0.1.0",
22+
"grunt-karma": "~0.4.3",
23+
"grunt-open": "~0.2.0",
24+
"grunt-concurrent": "~0.3.0",
25+
"matchdep": "~0.1.2",
26+
"connect-livereload": "~0.2.0",
27+
"grunt-google-cdn": "~0.2.0",
28+
"grunt-ngmin": "~0.0.2",
29+
"karma": "~0.9",
30+
"karma-jasmine": "~0.0.3",
31+
"karma-chrome-launcher": "~0.0.2"
32+
},
33+
"engines": {
34+
"node": ">=0.8.0"
35+
}
36+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
angular.module('ngS3upload.directives', []).
2+
directive('s3Upload', ['$parse', 'S3Uploader', function ($parse, S3Uploader) {
3+
return {
4+
restrict: 'AC',
5+
require: '?ngModel',
6+
replace: true,
7+
transclude: false,
8+
scope: true,
9+
controller: ['$scope', '$element', '$attrs', '$transclude', function ($scope, $element, $attrs, $transclude) {
10+
$scope.attempt = false;
11+
$scope.success = false;
12+
$scope.uploading = false;
13+
14+
$scope.barClass = function () {
15+
return {
16+
"bar-success": $scope.attempt && !$scope.uploading && $scope.success
17+
};
18+
};
19+
}],
20+
compile: function (element, attr, linker) {
21+
return {
22+
pre: function ($scope, $element, $attr) {
23+
if (angular.isUndefined($attr.bucket)) {
24+
throw Error('bucket is a mandatory attribute');
25+
}
26+
},
27+
post: function (scope, element, attrs, ngModel) {
28+
// Build the opts array
29+
var opts = angular.extend({}, scope.$eval(attrs.s3UploadOptions || attrs.options));
30+
opts = angular.extend({
31+
submitOnChange: true,
32+
getOptionsUri: '/getS3Options',
33+
acl: 'public-read',
34+
uploadingKey: 'uploading',
35+
folder: ''
36+
}, opts);
37+
var bucket = scope.$eval(attrs.bucket);
38+
39+
// Bind the button click event
40+
var button = angular.element(element.children()[0]),
41+
file = angular.element(element.find("input")[0]);
42+
button.bind('click', function (e) {
43+
file[0].click();
44+
});
45+
46+
// Update the scope with the view value
47+
ngModel.$render = function () {
48+
scope.filename = ngModel.$viewValue;
49+
};
50+
51+
var uploadFile = function () {
52+
var selectedFile = file[0].files[0];
53+
var filename = selectedFile.name;
54+
var ext = filename.split('.').pop();
55+
56+
scope.$apply(function () {
57+
S3Uploader.getUploadOptions(opts['getOptionsUri']).then(function (s3Options) {
58+
ngModel.$setValidity('uploading', false);
59+
var s3Uri = 'https://' + bucket + '.s3.amazonaws.com/' + opts['folder'];
60+
var key = (new Date).getTime() + '-' + S3Uploader.randomString(16) + "." + ext;
61+
S3Uploader.upload(scope,
62+
s3Uri,
63+
key,
64+
opts['acl'],
65+
selectedFile.type,
66+
s3Options.key,
67+
s3Options.policy,
68+
s3Options.signature,
69+
selectedFile
70+
).then(function () {
71+
ngModel.$setViewValue(s3Uri + key);
72+
scope.filename = ngModel.$viewValue;
73+
ngModel.$setValidity('uploading', true);
74+
ngModel.$setValidity('succeeded', true);
75+
}, function () {
76+
scope.filename = ngModel.$viewValue;
77+
ngModel.$setValidity('uploading', true);
78+
ngModel.$setValidity('succeeded', false);
79+
});
80+
81+
}, function (error) {
82+
throw Error("Can't receive the needed options for S3 " + error);
83+
});
84+
});
85+
};
86+
87+
element.bind('change', function (nVal) {
88+
if (opts['submitOnChange']) {
89+
uploadFile();
90+
}
91+
});
92+
93+
}
94+
}
95+
},
96+
template: '<div class="upload-wrap">' +
97+
'<button class="btn btn-primary" type="button"><span ng-if="!filename">Choose file</span><span ng-if="filename">Replace file</span></button>' +
98+
'<a ng-href="{{ filename }}" target="_blank" class="" ng-if="filename" > Stored file </a>' +
99+
'<div class="progress progress-striped" ng-class="{active: uploading}" ng-show="attempt" style="margin-top: 10px">' +
100+
'<div class="bar" style="width: {{ progress }}%;" ng-class="barClass()"></div>' +
101+
'</div>' +
102+
'<input type="file" style="display: none"/>' +
103+
'</div>'
104+
}
105+
}]);

src/ng-s3upload/ng-s3upload.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Create all modules and define dependencies to make sure they exist
2+
// and are loaded in the correct order to satisfy dependency injection
3+
// before all nested files are concatenated by Grunt
4+
5+
// Config
6+
angular.module('ngS3upload.config', []).
7+
value('ngS3upload.config', {
8+
debug: true
9+
}).
10+
config(['$compileProvider', function($compileProvider){
11+
if (angular.isDefined($compileProvider.urlSanitizationWhitelist)) {
12+
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|data):/);
13+
} else {
14+
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|data):/);
15+
}
16+
}]);
17+
18+
// Modules
19+
angular.module('ngS3upload.directives', []);
20+
angular.module('ngS3upload',
21+
[
22+
'ngS3upload.config',
23+
'ngS3upload.directives',
24+
'ngS3upload.services',
25+
'ngSanitize'
26+
]);

src/ng-s3upload/ng-s3upload.prefix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(function(window, document) {
2+

0 commit comments

Comments
 (0)