diff --git a/example-2.0/.editorconfig b/example-2.0/.editorconfig new file mode 100644 index 0000000..3ee22e5 --- /dev/null +++ b/example-2.0/.editorconfig @@ -0,0 +1,13 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/example-2.0/.jshintignore b/example-2.0/.jshintignore new file mode 100644 index 0000000..ee8c771 --- /dev/null +++ b/example-2.0/.jshintignore @@ -0,0 +1,2 @@ +/client/ +/node_modules/ diff --git a/example-2.0/.jshintrc b/example-2.0/.jshintrc new file mode 100644 index 0000000..feb0928 --- /dev/null +++ b/example-2.0/.jshintrc @@ -0,0 +1,21 @@ +{ + "node": true, + "esnext": true, + "bitwise": true, + "camelcase": true, + "eqeqeq": true, + "eqnull": true, + "immed": true, + "indent": 2, + "latedef": "nofunc", + "newcap": true, + "nonew": true, + "noarg": true, + "quotmark": "single", + "regexp": true, + "undef": true, + "unused": false, + "trailing": true, + "sub": true, + "maxlen": 80 +} diff --git a/example-2.0/.npmignore b/example-2.0/.npmignore new file mode 100644 index 0000000..7ec7473 --- /dev/null +++ b/example-2.0/.npmignore @@ -0,0 +1,16 @@ +.idea +.project +*.sublime-* +.DS_Store +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.swp +*.swo +node_modules +coverage +*.tgz +*.xml diff --git a/example-2.0/client/README.md b/example-2.0/client/README.md new file mode 100644 index 0000000..dd00c9e --- /dev/null +++ b/example-2.0/client/README.md @@ -0,0 +1,3 @@ +## Client + +This is the place for your application front-end files. diff --git a/example-2.0/client/angular-file-upload.js b/example-2.0/client/angular-file-upload.js new file mode 100644 index 0000000..a73fd4c --- /dev/null +++ b/example-2.0/client/angular-file-upload.js @@ -0,0 +1,685 @@ +/* + Angular File Upload v0.3.3.1 + https://github.com/nervgh/angular-file-upload +*/ +(function(angular, factory) { + if (typeof define === 'function' && define.amd) { + define('angular-file-upload', ['angular'], function(angular) { + return factory(angular); + }); + } else { + return factory(angular); + } +}(angular || null, function(angular) { +var app = angular.module('angularFileUpload', []); + +// It is attached to an element that catches the event drop file +app.directive('ngFileDrop', [ '$fileUploader', function ($fileUploader) { + 'use strict'; + + return { + // don't use drag-n-drop files in IE9, because not File API support + link: !$fileUploader.isHTML5 ? angular.noop : function (scope, element, attributes) { + element + .bind('drop', function (event) { + var dataTransfer = event.dataTransfer ? + event.dataTransfer : + event.originalEvent.dataTransfer; // jQuery fix; + if (!dataTransfer) return; + event.preventDefault(); + event.stopPropagation(); + scope.$broadcast('file:removeoverclass'); + scope.$emit('file:add', dataTransfer.files, scope.$eval(attributes.ngFileDrop)); + }) + .bind('dragover', function (event) { + var dataTransfer = event.dataTransfer ? + event.dataTransfer : + event.originalEvent.dataTransfer; // jQuery fix; + + event.preventDefault(); + event.stopPropagation(); + dataTransfer.dropEffect = 'copy'; + scope.$broadcast('file:addoverclass'); + }) + .bind('dragleave', function () { + scope.$broadcast('file:removeoverclass'); + }); + } + }; +}]) +// It is attached to an element which will be assigned to a class "ng-file-over" or ng-file-over="className" +app.directive('ngFileOver', function () { + 'use strict'; + + return { + link: function (scope, element, attributes) { + scope.$on('file:addoverclass', function () { + element.addClass(attributes.ngFileOver || 'ng-file-over'); + }); + scope.$on('file:removeoverclass', function () { + element.removeClass(attributes.ngFileOver || 'ng-file-over'); + }); + } + }; +}); +// It is attached to element like +app.directive('ngFileSelect', [ '$fileUploader', function ($fileUploader) { + 'use strict'; + + return { + link: function (scope, element, attributes) { + $fileUploader.isHTML5 || element.removeAttr('multiple'); + + element.bind('change', function () { + scope.$emit('file:add', $fileUploader.isHTML5 ? this.files : this, scope.$eval(attributes.ngFileSelect)); + ($fileUploader.isHTML5 && element.attr('multiple')) && element.prop('value', null); + }); + + element.prop('value', null); // FF fix + } + }; +}]); +app.factory('$fileUploader', [ '$compile', '$rootScope', '$http', '$window', function ($compile, $rootScope, $http, $window) { + 'use strict'; + + /** + * Creates a uploader + * @param {Object} params + * @constructor + */ + function Uploader(params) { + angular.extend(this, { + scope: $rootScope, + url: '/', + alias: 'file', + queue: [], + headers: {}, + progress: null, + autoUpload: false, + removeAfterUpload: false, + method: 'POST', + filters: [], + formData: [], + isUploading: false, + _nextIndex: 0, + _timestamp: Date.now() + }, params); + + // add the base filter + this.filters.unshift(this._filter); + + this.scope.$on('file:add', function (event, items, options) { + event.stopPropagation(); + this.addToQueue(items, options); + }.bind(this)); + + this.bind('beforeupload', Item.prototype._beforeupload); + this.bind('in:progress', Item.prototype._progress); + this.bind('in:success', Item.prototype._success); + this.bind('in:cancel', Item.prototype._cancel); + this.bind('in:error', Item.prototype._error); + this.bind('in:complete', Item.prototype._complete); + this.bind('in:progress', this._progress); + this.bind('in:complete', this._complete); + } + + Uploader.prototype = { + /** + * Link to the constructor + */ + constructor: Uploader, + + /** + * The base filter. If returns "true" an item will be added to the queue + * @param {File|Input} item + * @returns {boolean} + * @private + */ + _filter: function (item) { + return angular.isElement(item) ? true : !!item.size; + }, + + /** + * Registers a event handler + * @param {String} event + * @param {Function} handler + * @return {Function} unsubscribe function + */ + bind: function (event, handler) { + return this.scope.$on(this._timestamp + ':' + event, handler.bind(this)); + }, + + /** + * Triggers events + * @param {String} event + * @param {...*} [some] + */ + trigger: function (event, some) { + arguments[ 0 ] = this._timestamp + ':' + event; + this.scope.$broadcast.apply(this.scope, arguments); + }, + + /** + * Checks a support the html5 uploader + * @returns {Boolean} + * @readonly + */ + isHTML5: !!($window.File && $window.FormData), + + /** + * Adds items to the queue + * @param {FileList|File|HTMLInputElement} items + * @param {Object} [options] + */ + addToQueue: function (items, options) { + var length = this.queue.length; + var list = 'length' in items ? items : [items]; + + angular.forEach(list, function (file) { + // check a [File|HTMLInputElement] + var isValid = !this.filters.length ? true : this.filters.every(function (filter) { + return filter.call(this, file); + }, this); + + // create new item + var item = new Item(angular.extend({ + url: this.url, + alias: this.alias, + headers: angular.copy(this.headers), + formData: angular.copy(this.formData), + removeAfterUpload: this.removeAfterUpload, + method: this.method, + uploader: this, + file: file + }, options)); + + if (isValid) { + this.queue.push(item); + this.trigger('afteraddingfile', item); + } else { + this.trigger('whenaddingfilefailed', item); + } + }, this); + + if (this.queue.length !== length) { + this.trigger('afteraddingall', this.queue); + this.progress = this._getTotalProgress(); + } + + this._render(); + this.autoUpload && this.uploadAll(); + }, + + /** + * Remove items from the queue. Remove last: index = -1 + * @param {Item|Number} value + */ + removeFromQueue: function (value) { + var index = this.getIndexOfItem(value); + var item = this.queue[ index ]; + item.isUploading && item.cancel(); + this.queue.splice(index, 1); + item._destroy(); + this.progress = this._getTotalProgress(); + }, + + /** + * Clears the queue + */ + clearQueue: function () { + this.queue.forEach(function (item) { + item.isUploading && item.cancel(); + item._destroy(); + }, this); + this.queue.length = 0; + this.progress = 0; + }, + + /** + * Returns a index of item from the queue + * @param {Item|Number} value + * @returns {Number} + */ + getIndexOfItem: function (value) { + return angular.isObject(value) ? this.queue.indexOf(value) : value; + }, + + /** + * Returns not uploaded items + * @returns {Array} + */ + getNotUploadedItems: function () { + return this.queue.filter(function (item) { + return !item.isUploaded; + }); + }, + + /** + * Returns items ready for upload + * @returns {Array} + */ + getReadyItems: function() { + return this.queue + .filter(function(item) { + return item.isReady && !item.isUploading; + }) + .sort(function(item1, item2) { + return item1.index - item2.index; + }); + }, + + /** + * Uploads a item from the queue + * @param {Item|Number} value + */ + uploadItem: function (value) { + var index = this.getIndexOfItem(value); + var item = this.queue[ index ]; + var transport = this.isHTML5 ? '_xhrTransport' : '_iframeTransport'; + + item.index = item.index || this._nextIndex++; + item.isReady = true; + + if (this.isUploading) { + return; + } + + this.isUploading = true; + this[ transport ](item); + }, + + /** + * Cancels uploading of item from the queue + * @param {Item|Number} value + */ + cancelItem: function(value) { + var index = this.getIndexOfItem(value); + var item = this.queue[ index ]; + var prop = this.isHTML5 ? '_xhr' : '_form'; + item[prop] && item[prop].abort(); + }, + + /** + * Uploads all not uploaded items of queue + */ + uploadAll: function () { + var items = this.getNotUploadedItems().filter(function(item) { + return !item.isUploading; + }); + items.forEach(function(item) { + item.index = item.index || this._nextIndex++; + item.isReady = true; + }, this); + items.length && this.uploadItem(items[ 0 ]); + }, + + /** + * Cancels all uploads + */ + cancelAll: function() { + this.getNotUploadedItems().forEach(function(item) { + this.cancelItem(item); + }, this); + }, + + /** + * Updates angular scope + * @private + */ + _render: function() { + this.scope.$$phase || this.scope.$digest(); + }, + + /** + * Returns the total progress + * @param {Number} [value] + * @returns {Number} + * @private + */ + _getTotalProgress: function (value) { + if (this.removeAfterUpload) { + return value || 0; + } + + var notUploaded = this.getNotUploadedItems().length; + var uploaded = notUploaded ? this.queue.length - notUploaded : this.queue.length; + var ratio = 100 / this.queue.length; + var current = (value || 0) * ratio / 100; + + return Math.round(uploaded * ratio + current); + }, + + /** + * The 'in:progress' handler + * @private + */ + _progress: function (event, item, progress) { + var result = this._getTotalProgress(progress); + this.trigger('progressall', result); + this.progress = result; + this._render(); + }, + + /** + * The 'in:complete' handler + * @private + */ + _complete: function () { + var item = this.getReadyItems()[ 0 ]; + this.isUploading = false; + + if (angular.isDefined(item)) { + this.uploadItem(item); + return; + } + + this.trigger('completeall', this.queue); + this.progress = this._getTotalProgress(); + this._render(); + }, + + /** + * The XMLHttpRequest transport + * @private + */ + _xhrTransport: function (item) { + var xhr = item._xhr = new XMLHttpRequest(); + var form = new FormData(); + var that = this; + + this.trigger('beforeupload', item); + + item.formData.forEach(function(obj) { + angular.forEach(obj, function(value, key) { + form.append(key, value); + }); + }); + + form.append(item.alias, item.file); + + xhr.upload.onprogress = function (event) { + var progress = event.lengthComputable ? event.loaded * 100 / event.total : 0; + that.trigger('in:progress', item, Math.round(progress)); + }; + + xhr.onload = function () { + var response = that._transformResponse(xhr.response); + var event = that._isSuccessCode(xhr.status) ? 'success' : 'error'; + that.trigger('in:' + event, xhr, item, response); + that.trigger('in:complete', xhr, item, response); + }; + + xhr.onerror = function () { + that.trigger('in:error', xhr, item); + that.trigger('in:complete', xhr, item); + }; + + xhr.onabort = function () { + that.trigger('in:cancel', xhr, item); + that.trigger('in:complete', xhr, item); + }; + + xhr.open(item.method, item.url, true); + + angular.forEach(item.headers, function (value, name) { + xhr.setRequestHeader(name, value); + }); + + xhr.send(form); + }, + + /** + * The IFrame transport + * @private + */ + _iframeTransport: function (item) { + var form = angular.element(''); + var iframe = angular.element(''); + var input = item._input; + var that = this; + + item._form && item._form.replaceWith(input); // remove old form + item._form = form; // save link to new form + + this.trigger('beforeupload', item); + + input.prop('name', item.alias); + + item.formData.forEach(function(obj) { + angular.forEach(obj, function(value, key) { + form.append(angular.element('')); + }); + }); + + form.prop({ + action: item.url, + method: item.method, + target: iframe.prop('name'), + enctype: 'multipart/form-data', + encoding: 'multipart/form-data' // old IE + }); + + iframe.bind('load', function () { + // fixed angular.contents() for iframes + var html = iframe[0].contentDocument.body.innerHTML; + var xhr = { response: html, status: 200, dummy: true }; + var response = that._transformResponse(xhr.response); + that.trigger('in:success', xhr, item, response); + that.trigger('in:complete', xhr, item, response); + }); + + form.abort = function() { + var xhr = { status: 0, dummy: true }; + iframe.unbind('load').prop('src', 'javascript:false;'); + form.replaceWith(input); + that.trigger('in:cancel', xhr, item); + that.trigger('in:complete', xhr, item); + }; + + input.after(form); + form.append(input).append(iframe); + + form[ 0 ].submit(); + }, + + /** + * Checks whether upload successful + * @param {Number} status + * @returns {Boolean} + * @private + */ + _isSuccessCode: function(status) { + return (status >= 200 && status < 300) || status === 304; + }, + + /** + * Transforms the server response + * @param {*} response + * @returns {*} + * @private + */ + _transformResponse: function (response) { + $http.defaults.transformResponse.forEach(function (transformFn) { + response = transformFn(response); + }); + return response; + } + }; + + + /** + * Create a item + * @param {Object} params + * @constructor + */ + function Item(params) { + // fix for old browsers + if (!Uploader.prototype.isHTML5) { + var input = angular.element(params.file); + var clone = $compile(input.clone())(params.uploader.scope); + var value = input.val(); + + params.file = { + lastModifiedDate: null, + size: null, + type: 'like/' + value.slice(value.lastIndexOf('.') + 1).toLowerCase(), + name: value.slice(value.lastIndexOf('/') + value.lastIndexOf('\\') + 2) + }; + + params._input = input; + clone.prop('value', null); // FF fix + input.css('display', 'none').after(clone); // remove jquery dependency + } + + angular.extend(this, { + isReady: false, + isUploading: false, + isUploaded: false, + isSuccess: false, + isCancel: false, + isError: false, + progress: null, + index: null + }, params); + } + + + Item.prototype = { + /** + * Link to the constructor + */ + constructor: Item, + /** + * Removes a item + */ + remove: function () { + this.uploader.removeFromQueue(this); + }, + /** + * Uploads a item + */ + upload: function () { + this.uploader.uploadItem(this); + }, + /** + * Cancels uploading + */ + cancel: function() { + this.uploader.cancelItem(this); + }, + /** + * Destroys form and input + * @private + */ + _destroy: function() { + this._form && this._form.remove(); + this._input && this._input.remove(); + delete this._form; + delete this._input; + }, + /** + * The 'beforeupload' handler + * @param {Object} event + * @param {Item} item + * @private + */ + _beforeupload: function (event, item) { + item.isReady = true; + item.isUploading = true; + item.isUploaded = false; + item.isSuccess = false; + item.isCancel = false; + item.isError = false; + item.progress = 0; + }, + /** + * The 'in:progress' handler + * @param {Object} event + * @param {Item} item + * @param {Number} progress + * @private + */ + _progress: function (event, item, progress) { + item.progress = progress; + item.uploader.trigger('progress', item, progress); + }, + /** + * The 'in:success' handler + * @param {Object} event + * @param {XMLHttpRequest} xhr + * @param {Item} item + * @param {*} response + * @private + */ + _success: function (event, xhr, item, response) { + item.isReady = false; + item.isUploading = false; + item.isUploaded = true; + item.isSuccess = true; + item.isCancel = false; + item.isError = false; + item.progress = 100; + item.index = null; + item.uploader.trigger('success', xhr, item, response); + }, + /** + * The 'in:cancel' handler + * @param {Object} event + * @param {XMLHttpRequest} xhr + * @param {Item} item + * @private + */ + _cancel: function(event, xhr, item) { + item.isReady = false; + item.isUploading = false; + item.isUploaded = false; + item.isSuccess = false; + item.isCancel = true; + item.isError = false; + item.progress = 0; + item.index = null; + item.uploader.trigger('cancel', xhr, item); + }, + /** + * The 'in:error' handler + * @param {Object} event + * @param {XMLHttpRequest} xhr + * @param {Item} item + * @param {*} response + * @private + */ + _error: function (event, xhr, item, response) { + item.isReady = false; + item.isUploading = false; + item.isUploaded = true; + item.isSuccess = false; + item.isCancel = false; + item.isError = true; + item.progress = 100; + item.index = null; + item.uploader.trigger('error', xhr, item, response); + }, + /** + * The 'in:complete' handler + * @param {Object} event + * @param {XMLHttpRequest} xhr + * @param {Item} item + * @param {*} response + * @private + */ + _complete: function (event, xhr, item, response) { + item.uploader.trigger('complete', xhr, item, response); + item.removeAfterUpload && item.remove(); + } + }; + + return { + create: function (params) { + return new Uploader(params); + }, + isHTML5: Uploader.prototype.isHTML5 + }; +}]) + + return app; +})); \ No newline at end of file diff --git a/example-2.0/client/angular-file-upload.min.js b/example-2.0/client/angular-file-upload.min.js new file mode 100644 index 0000000..243ca0c --- /dev/null +++ b/example-2.0/client/angular-file-upload.min.js @@ -0,0 +1,6 @@ +/* + Angular File Upload v0.3.3.1 + https://github.com/nervgh/angular-file-upload +*/ +!function(a,b){return"function"==typeof define&&define.amd?(define("angular-file-upload",["angular"],function(a){return b(a)}),void 0):b(a)}(angular||null,function(a){var b=a.module("angularFileUpload",[]);return b.directive("ngFileDrop",["$fileUploader",function(b){"use strict";return{link:b.isHTML5?function(a,b,c){b.bind("drop",function(b){var d=b.dataTransfer?b.dataTransfer:b.originalEvent.dataTransfer;d&&(b.preventDefault(),b.stopPropagation(),a.$broadcast("file:removeoverclass"),a.$emit("file:add",d.files,a.$eval(c.ngFileDrop)))}).bind("dragover",function(b){var c=b.dataTransfer?b.dataTransfer:b.originalEvent.dataTransfer;b.preventDefault(),b.stopPropagation(),c.dropEffect="copy",a.$broadcast("file:addoverclass")}).bind("dragleave",function(){a.$broadcast("file:removeoverclass")})}:a.noop}}]),b.directive("ngFileOver",function(){"use strict";return{link:function(a,b,c){a.$on("file:addoverclass",function(){b.addClass(c.ngFileOver||"ng-file-over")}),a.$on("file:removeoverclass",function(){b.removeClass(c.ngFileOver||"ng-file-over")})}}}),b.directive("ngFileSelect",["$fileUploader",function(a){"use strict";return{link:function(b,c,d){a.isHTML5||c.removeAttr("multiple"),c.bind("change",function(){b.$emit("file:add",a.isHTML5?this.files:this,b.$eval(d.ngFileSelect)),a.isHTML5&&c.attr("multiple")&&c.prop("value",null)}),c.prop("value",null)}}}]),b.factory("$fileUploader",["$compile","$rootScope","$http","$window",function(b,c,d,e){"use strict";function f(b){a.extend(this,{scope:c,url:"/",alias:"file",queue:[],headers:{},progress:null,autoUpload:!1,removeAfterUpload:!1,method:"POST",filters:[],formData:[],isUploading:!1,_nextIndex:0,_timestamp:Date.now()},b),this.filters.unshift(this._filter),this.scope.$on("file:add",function(a,b,c){a.stopPropagation(),this.addToQueue(b,c)}.bind(this)),this.bind("beforeupload",g.prototype._beforeupload),this.bind("in:progress",g.prototype._progress),this.bind("in:success",g.prototype._success),this.bind("in:cancel",g.prototype._cancel),this.bind("in:error",g.prototype._error),this.bind("in:complete",g.prototype._complete),this.bind("in:progress",this._progress),this.bind("in:complete",this._complete)}function g(c){if(!f.prototype.isHTML5){var d=a.element(c.file),e=b(d.clone())(c.uploader.scope),g=d.val();c.file={lastModifiedDate:null,size:null,type:"like/"+g.slice(g.lastIndexOf(".")+1).toLowerCase(),name:g.slice(g.lastIndexOf("/")+g.lastIndexOf("\\")+2)},c._input=d,e.prop("value",null),d.css("display","none").after(e)}a.extend(this,{isReady:!1,isUploading:!1,isUploaded:!1,isSuccess:!1,isCancel:!1,isError:!1,progress:null,index:null},c)}return f.prototype={constructor:f,_filter:function(b){return a.isElement(b)?!0:!!b.size},bind:function(a,b){return this.scope.$on(this._timestamp+":"+a,b.bind(this))},trigger:function(a){arguments[0]=this._timestamp+":"+a,this.scope.$broadcast.apply(this.scope,arguments)},isHTML5:!(!e.File||!e.FormData),addToQueue:function(b,c){var d=this.queue.length,e="length"in b?b:[b];a.forEach(e,function(b){var d=this.filters.length?this.filters.every(function(a){return a.call(this,b)},this):!0,e=new g(a.extend({url:this.url,alias:this.alias,headers:a.copy(this.headers),formData:a.copy(this.formData),removeAfterUpload:this.removeAfterUpload,method:this.method,uploader:this,file:b},c));d?(this.queue.push(e),this.trigger("afteraddingfile",e)):this.trigger("whenaddingfilefailed",e)},this),this.queue.length!==d&&(this.trigger("afteraddingall",this.queue),this.progress=this._getTotalProgress()),this._render(),this.autoUpload&&this.uploadAll()},removeFromQueue:function(a){var b=this.getIndexOfItem(a),c=this.queue[b];c.isUploading&&c.cancel(),this.queue.splice(b,1),c._destroy(),this.progress=this._getTotalProgress()},clearQueue:function(){this.queue.forEach(function(a){a.isUploading&&a.cancel(),a._destroy()},this),this.queue.length=0,this.progress=0},getIndexOfItem:function(b){return a.isObject(b)?this.queue.indexOf(b):b},getNotUploadedItems:function(){return this.queue.filter(function(a){return!a.isUploaded})},getReadyItems:function(){return this.queue.filter(function(a){return a.isReady&&!a.isUploading}).sort(function(a,b){return a.index-b.index})},uploadItem:function(a){var b=this.getIndexOfItem(a),c=this.queue[b],d=this.isHTML5?"_xhrTransport":"_iframeTransport";c.index=c.index||this._nextIndex++,c.isReady=!0,this.isUploading||(this.isUploading=!0,this[d](c))},cancelItem:function(a){var b=this.getIndexOfItem(a),c=this.queue[b],d=this.isHTML5?"_xhr":"_form";c[d]&&c[d].abort()},uploadAll:function(){var a=this.getNotUploadedItems().filter(function(a){return!a.isUploading});a.forEach(function(a){a.index=a.index||this._nextIndex++,a.isReady=!0},this),a.length&&this.uploadItem(a[0])},cancelAll:function(){this.getNotUploadedItems().forEach(function(a){this.cancelItem(a)},this)},_render:function(){this.scope.$$phase||this.scope.$digest()},_getTotalProgress:function(a){if(this.removeAfterUpload)return a||0;var b=this.getNotUploadedItems().length,c=b?this.queue.length-b:this.queue.length,d=100/this.queue.length,e=(a||0)*d/100;return Math.round(c*d+e)},_progress:function(a,b,c){var d=this._getTotalProgress(c);this.trigger("progressall",d),this.progress=d,this._render()},_complete:function(){var b=this.getReadyItems()[0];return this.isUploading=!1,a.isDefined(b)?(this.uploadItem(b),void 0):(this.trigger("completeall",this.queue),this.progress=this._getTotalProgress(),this._render(),void 0)},_xhrTransport:function(b){var c=b._xhr=new XMLHttpRequest,d=new FormData,e=this;this.trigger("beforeupload",b),b.formData.forEach(function(b){a.forEach(b,function(a,b){d.append(b,a)})}),d.append(b.alias,b.file),c.upload.onprogress=function(a){var c=a.lengthComputable?100*a.loaded/a.total:0;e.trigger("in:progress",b,Math.round(c))},c.onload=function(){var a=e._transformResponse(c.response),d=e._isSuccessCode(c.status)?"success":"error";e.trigger("in:"+d,c,b,a),e.trigger("in:complete",c,b,a)},c.onerror=function(){e.trigger("in:error",c,b),e.trigger("in:complete",c,b)},c.onabort=function(){e.trigger("in:cancel",c,b),e.trigger("in:complete",c,b)},c.open(b.method,b.url,!0),a.forEach(b.headers,function(a,b){c.setRequestHeader(b,a)}),c.send(d)},_iframeTransport:function(b){var c=a.element(''),d=a.element(''),e=b._input,f=this;b._form&&b._form.replaceWith(e),b._form=c,this.trigger("beforeupload",b),e.prop("name",b.alias),b.formData.forEach(function(b){a.forEach(b,function(b,d){c.append(a.element(''))})}),c.prop({action:b.url,method:b.method,target:d.prop("name"),enctype:"multipart/form-data",encoding:"multipart/form-data"}),d.bind("load",function(){var a=d[0].contentDocument.body.innerHTML,c={response:a,status:200,dummy:!0},e=f._transformResponse(c.response);f.trigger("in:success",c,b,e),f.trigger("in:complete",c,b,e)}),c.abort=function(){var a={status:0,dummy:!0};d.unbind("load").prop("src","javascript:false;"),c.replaceWith(e),f.trigger("in:cancel",a,b),f.trigger("in:complete",a,b)},e.after(c),c.append(e).append(d),c[0].submit()},_isSuccessCode:function(a){return a>=200&&300>a||304===a},_transformResponse:function(a){return d.defaults.transformResponse.forEach(function(b){a=b(a)}),a}},g.prototype={constructor:g,remove:function(){this.uploader.removeFromQueue(this)},upload:function(){this.uploader.uploadItem(this)},cancel:function(){this.uploader.cancelItem(this)},_destroy:function(){this._form&&this._form.remove(),this._input&&this._input.remove(),delete this._form,delete this._input},_beforeupload:function(a,b){b.isReady=!0,b.isUploading=!0,b.isUploaded=!1,b.isSuccess=!1,b.isCancel=!1,b.isError=!1,b.progress=0},_progress:function(a,b,c){b.progress=c,b.uploader.trigger("progress",b,c)},_success:function(a,b,c,d){c.isReady=!1,c.isUploading=!1,c.isUploaded=!0,c.isSuccess=!0,c.isCancel=!1,c.isError=!1,c.progress=100,c.index=null,c.uploader.trigger("success",b,c,d)},_cancel:function(a,b,c){c.isReady=!1,c.isUploading=!1,c.isUploaded=!1,c.isSuccess=!1,c.isCancel=!0,c.isError=!1,c.progress=0,c.index=null,c.uploader.trigger("cancel",b,c)},_error:function(a,b,c,d){c.isReady=!1,c.isUploading=!1,c.isUploaded=!0,c.isSuccess=!1,c.isCancel=!1,c.isError=!0,c.progress=100,c.index=null,c.uploader.trigger("error",b,c,d)},_complete:function(a,b,c,d){c.uploader.trigger("complete",b,c,d),c.removeAfterUpload&&c.remove()}},{create:function(a){return new f(a)},isHTML5:f.prototype.isHTML5}}]),b}); +//# sourceMappingURL=angular-file-upload.min.map \ No newline at end of file diff --git a/example-2.0/client/angular-file-upload.min.map b/example-2.0/client/angular-file-upload.min.map new file mode 100644 index 0000000..142ccfd --- /dev/null +++ b/example-2.0/client/angular-file-upload.min.map @@ -0,0 +1 @@ +{"version":3,"file":"angular-file-upload.min.js","sources":["angular-file-upload.js"],"names":["angular","factory","define","amd","app","module","directive","$fileUploader","link","isHTML5","scope","element","attributes","bind","event","dataTransfer","originalEvent","preventDefault","stopPropagation","$broadcast","$emit","files","$eval","ngFileDrop","dropEffect","noop","$on","addClass","ngFileOver","removeClass","removeAttr","this","ngFileSelect","attr","prop","$compile","$rootScope","$http","$window","Uploader","params","extend","url","alias","queue","headers","progress","autoUpload","removeAfterUpload","method","filters","formData","isUploading","_nextIndex","_timestamp","Date","now","unshift","_filter","items","options","addToQueue","Item","prototype","_beforeupload","_progress","_success","_cancel","_error","_complete","input","file","clone","uploader","value","val","lastModifiedDate","size","type","slice","lastIndexOf","toLowerCase","name","_input","css","after","isReady","isUploaded","isSuccess","isCancel","isError","index","constructor","item","isElement","handler","trigger","arguments","apply","File","FormData","length","list","forEach","isValid","every","filter","call","copy","push","_getTotalProgress","_render","uploadAll","removeFromQueue","getIndexOfItem","cancel","splice","_destroy","clearQueue","isObject","indexOf","getNotUploadedItems","getReadyItems","sort","item1","item2","uploadItem","transport","cancelItem","abort","cancelAll","$$phase","$digest","notUploaded","uploaded","ratio","current","Math","round","result","isDefined","_xhrTransport","xhr","_xhr","XMLHttpRequest","form","that","obj","key","append","upload","onprogress","lengthComputable","loaded","total","onload","response","_transformResponse","_isSuccessCode","status","onerror","onabort","open","setRequestHeader","send","_iframeTransport","iframe","_form","replaceWith","action","target","enctype","encoding","html","contentDocument","body","innerHTML","dummy","unbind","submit","defaults","transformResponse","transformFn","remove","create"],"mappings":"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"} \ No newline at end of file diff --git a/example-2.0/client/controllers.js b/example-2.0/client/controllers.js new file mode 100644 index 0000000..9eb16ce --- /dev/null +++ b/example-2.0/client/controllers.js @@ -0,0 +1,97 @@ +angular.module('app', ['angularFileUpload']) + + // The example of the full functionality + .controller('TestController',function ($scope, $fileUploader) { + 'use strict'; + + // create a uploader with options + var uploader = $scope.uploader = $fileUploader.create({ + scope: $scope, // to automatically update the html. Default: $rootScope + url: '/api/containers/container1/upload', + formData: [ + { key: 'value' } + ], + filters: [ + function (item) { // first user filter + console.info('filter1'); + return true; + } + ] + }); + + // ADDING FILTERS + + uploader.filters.push(function (item) { // second user filter + console.info('filter2'); + return true; + }); + + // REGISTER HANDLERS + + uploader.bind('afteraddingfile', function (event, item) { + console.info('After adding a file', item); + }); + + uploader.bind('whenaddingfilefailed', function (event, item) { + console.info('When adding a file failed', item); + }); + + uploader.bind('afteraddingall', function (event, items) { + console.info('After adding all files', items); + }); + + uploader.bind('beforeupload', function (event, item) { + console.info('Before upload', item); + }); + + uploader.bind('progress', function (event, item, progress) { + console.info('Progress: ' + progress, item); + }); + + uploader.bind('success', function (event, xhr, item, response) { + console.info('Success', xhr, item, response); + $scope.$broadcast('uploadCompleted', item); + }); + + uploader.bind('cancel', function (event, xhr, item) { + console.info('Cancel', xhr, item); + }); + + uploader.bind('error', function (event, xhr, item, response) { + console.info('Error', xhr, item, response); + }); + + uploader.bind('complete', function (event, xhr, item, response) { + console.info('Complete', xhr, item, response); + }); + + uploader.bind('progressall', function (event, progress) { + console.info('Total progress: ' + progress); + }); + + uploader.bind('completeall', function (event, items) { + console.info('Complete all', items); + }); + + } +).controller('FilesController', function ($scope, $http) { + + $scope.load = function () { + $http.get('/api/containers/container1/files').success(function (data) { + console.log(data); + $scope.files = data; + }); + }; + + $scope.delete = function (index, id) { + $http.delete('/api/containers/container1/files/' + encodeURIComponent(id)).success(function (data, status, headers) { + $scope.files.splice(index, 1); + }); + }; + + $scope.$on('uploadCompleted', function(event) { + console.log('uploadCompleted event received'); + $scope.load(); + }); + + }); diff --git a/example-2.0/client/index.html b/example-2.0/client/index.html new file mode 100644 index 0000000..e7ef4ad --- /dev/null +++ b/example-2.0/client/index.html @@ -0,0 +1,202 @@ + + + + + LoopBack Storage Service Demo + + + + + + + + + + + + + + + + + + + + + + + + LoopBack + Storage Service + + + + + + + + Select files + + + + + Base drop zone + + + + + Another drop zone with its own settings + + + + + Multiple + + + Single + + + + + + Upload queue + + Queue length: {{ uploader.queue.length }} + + + + + Name + Size + Progress + Status + Actions + + + + + {{ item.file.name }} + {{ + item.file.size/1024/1024|number:2 }} MB + + + + + + + + + + + + + + + Upload + + + + Cancel + + + + Remove + + + + + + + + + Queue progress: + + + + + + + Upload all + + + Cancel + all + + + Remove all + + + + + + + + Files in the container + + + + + + + {{ + file.name }} + + + + + Remove + + + + + + + + + + + + + + + + diff --git a/example-2.0/package.json b/example-2.0/package.json new file mode 100644 index 0000000..fec9dc5 --- /dev/null +++ b/example-2.0/package.json @@ -0,0 +1,20 @@ +{ + "name": "loopback-example-storage", + "version": "0.0.0", + "main": "server/server.js", + "scripts": { + "pretest": "jshint ." + }, + "dependencies": { + "compression": "^1.0.3", + "errorhandler": "^1.1.1", + "loopback": "^2.0.0", + "loopback-boot": "^2.0.0", + "loopback-component-storage": "~1.0.5", + "loopback-datasource-juggler": "^2.7.0", + "serve-favicon": "^2.0.1" + }, + "optionalDependencies": { + "loopback-explorer": "^1.1.0" + } +} diff --git a/example-2.0/server/boot/authentication.js b/example-2.0/server/boot/authentication.js new file mode 100644 index 0000000..a87cd08 --- /dev/null +++ b/example-2.0/server/boot/authentication.js @@ -0,0 +1,4 @@ +module.exports = function enableAuthentication(server) { + // enable authentication + server.enableAuth(); +}; diff --git a/example-2.0/server/boot/explorer.js b/example-2.0/server/boot/explorer.js new file mode 100644 index 0000000..b74d498 --- /dev/null +++ b/example-2.0/server/boot/explorer.js @@ -0,0 +1,23 @@ +module.exports = function mountLoopBackExplorer(server) { + var explorer; + try { + explorer = require('loopback-explorer'); + } catch(err) { + console.log( + 'Run `npm install loopback-explorer` to enable the LoopBack explorer' + ); + return; + } + + var restApiRoot = server.get('restApiRoot'); + + var explorerApp = explorer(server, { basePath: restApiRoot }); + server.use('/explorer', explorerApp); + server.once('started', function() { + var baseUrl = server.get('url').replace(/\/$/, ''); + // express 4.x (loopback 2.x) uses `mountpath` + // express 3.x (loopback 1.x) uses `route` + var explorerPath = explorerApp.mountpath || explorerApp.route; + console.log('Browse your REST API at %s%s', baseUrl, explorerPath); + }); +}; diff --git a/example-2.0/server/boot/rest-api.js b/example-2.0/server/boot/rest-api.js new file mode 100644 index 0000000..256579a --- /dev/null +++ b/example-2.0/server/boot/rest-api.js @@ -0,0 +1,4 @@ +module.exports = function mountRestApi(server) { + var restApiRoot = server.get('restApiRoot'); + server.use(restApiRoot, server.loopback.rest()); +}; diff --git a/example-2.0/server/config.json b/example-2.0/server/config.json new file mode 100644 index 0000000..22152ca --- /dev/null +++ b/example-2.0/server/config.json @@ -0,0 +1,6 @@ +{ + "restApiRoot": "/api", + "host": "0.0.0.0", + "port": 3000, + "url": "http://localhost:3000/" +} diff --git a/example-2.0/server/datasources.json b/example-2.0/server/datasources.json new file mode 100644 index 0000000..16423ff --- /dev/null +++ b/example-2.0/server/datasources.json @@ -0,0 +1,12 @@ +{ + "db": { + "name": "db", + "connector": "memory" + }, + "storage": { + "name": "storage", + "connector": "loopback-component-storage", + "provider": "filesystem", + "root": "./server/storage" + } +} diff --git a/example-2.0/server/model-config.json b/example-2.0/server/model-config.json new file mode 100644 index 0000000..73467d5 --- /dev/null +++ b/example-2.0/server/model-config.json @@ -0,0 +1,31 @@ +{ + "_meta": { + "sources": [ + "../common/models", + "./models" + ] + }, + "User": { + "dataSource": "db" + }, + "AccessToken": { + "dataSource": "db", + "public": false + }, + "ACL": { + "dataSource": "db", + "public": false + }, + "RoleMapping": { + "dataSource": "db", + "public": false + }, + "Role": { + "dataSource": "db", + "public": false + }, + "container": { + "dataSource": "storage", + "public": true + } +} diff --git a/example-2.0/server/models/container.js b/example-2.0/server/models/container.js new file mode 100644 index 0000000..a0e8234 --- /dev/null +++ b/example-2.0/server/models/container.js @@ -0,0 +1,3 @@ +module.exports = function(Container) { + +}; diff --git a/example-2.0/server/models/container.json b/example-2.0/server/models/container.json new file mode 100644 index 0000000..a42952c --- /dev/null +++ b/example-2.0/server/models/container.json @@ -0,0 +1,9 @@ +{ + "name": "container", + "base": "Model", + "properties": {}, + "validations": [], + "relations": {}, + "acls": [], + "methods": [] +} diff --git a/example-2.0/server/providers-private.json b/example-2.0/server/providers-private.json new file mode 100644 index 0000000..77cc7c9 --- /dev/null +++ b/example-2.0/server/providers-private.json @@ -0,0 +1,11 @@ +{ + "rackspace": { + "username": "strongloop", + "apiKey": "a51076644fc37583bd87dd648b58777e", + "region": "DFW" + }, + "amazon": { + "keyId": "AKIAJXSYYW7EAWTJYMLA", + "key": "TkW/9i7nNsOEg/vvYS4P/zexNrzDvkjQp3NwF7J7" + } +} diff --git a/example-2.0/server/providers.json b/example-2.0/server/providers.json new file mode 100644 index 0000000..15dd4ac --- /dev/null +++ b/example-2.0/server/providers.json @@ -0,0 +1,11 @@ +{ + "rackspace": { + "username": "your-rackspace-username", + "apiKey": "your-rackspace-api-key", + "region": "DFW" + }, + "amazon": { + "key": "your-amazon-key", + "keyId": "your-amazon-key-id" + } +} diff --git a/example-2.0/server/server.js b/example-2.0/server/server.js new file mode 100644 index 0000000..7578866 --- /dev/null +++ b/example-2.0/server/server.js @@ -0,0 +1,43 @@ +var loopback = require('loopback'); +var boot = require('loopback-boot'); + +var app = module.exports = loopback(); + +// Set up the /favicon.ico +app.use(loopback.favicon()); + +// request pre-processing middleware +app.use(loopback.compress()); + +// -- Add your pre-processing middleware here -- + +// boot scripts mount components like REST API +boot(app, __dirname); + +// -- Mount static files here-- +// All static middleware should be registered at the end, as all requests +// passing the static middleware are hitting the file system +// Example: +var path = require('path'); +app.use(loopback.static(path.resolve(__dirname, '../client'))); + +// Requests that get this far won't be handled +// by any middleware. Convert them into a 404 error +// that will be handled later down the chain. +app.use(loopback.urlNotFound()); + +// The ultimate error handler. +app.use(loopback.errorHandler()); + +app.start = function() { + // start the web server + return app.listen(function() { + app.emit('started'); + console.log('Web server listening at: %s', app.get('url')); + }); +}; + +// start the server if `$ node server.js` +if (require.main === module) { + app.start(); +} diff --git a/example-2.0/server/storage/container1/f1.txt b/example-2.0/server/storage/container1/f1.txt new file mode 100644 index 0000000..1652405 --- /dev/null +++ b/example-2.0/server/storage/container1/f1.txt @@ -0,0 +1 @@ +Hello.... \ No newline at end of file diff --git a/example-2.0/server/storage/container1/f1_downloaded.txt b/example-2.0/server/storage/container1/f1_downloaded.txt new file mode 100644 index 0000000..1652405 --- /dev/null +++ b/example-2.0/server/storage/container1/f1_downloaded.txt @@ -0,0 +1 @@ +Hello.... \ No newline at end of file diff --git a/example-2.0/server/storage/container1/fybc_logo_2013.jpg b/example-2.0/server/storage/container1/fybc_logo_2013.jpg new file mode 100644 index 0000000..5eda491 Binary files /dev/null and b/example-2.0/server/storage/container1/fybc_logo_2013.jpg differ diff --git a/example-2.0/server/storage/container1/loopback-models.pptx b/example-2.0/server/storage/container1/loopback-models.pptx new file mode 100644 index 0000000..83484a5 Binary files /dev/null and b/example-2.0/server/storage/container1/loopback-models.pptx differ diff --git a/example-2.0/server/storage/container1/uploadTest.txt b/example-2.0/server/storage/container1/uploadTest.txt new file mode 100644 index 0000000..9bc8a72 --- /dev/null +++ b/example-2.0/server/storage/container1/uploadTest.txt @@ -0,0 +1 @@ +Upload test \ No newline at end of file diff --git a/example-2.0/server/storage/container2/f2.txt b/example-2.0/server/storage/container2/f2.txt new file mode 100644 index 0000000..1652405 --- /dev/null +++ b/example-2.0/server/storage/container2/f2.txt @@ -0,0 +1 @@ +Hello.... \ No newline at end of file
Queue length: {{ uploader.queue.length }}
+ Queue progress: + +