1341 lines
49 KiB
JavaScript
1341 lines
49 KiB
JavaScript
|
/*
|
||
|
angular-file-upload v1.1.6
|
||
|
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);
|
||
|
}
|
||
|
}(typeof angular === 'undefined' ? null : angular, function(angular) {
|
||
|
|
||
|
var module = angular.module('angularFileUpload', []);
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
/**
|
||
|
* Classes
|
||
|
*
|
||
|
* FileUploader
|
||
|
* FileUploader.FileLikeObject
|
||
|
* FileUploader.FileItem
|
||
|
* FileUploader.FileDirective
|
||
|
* FileUploader.FileSelect
|
||
|
* FileUploader.FileDrop
|
||
|
* FileUploader.FileOver
|
||
|
*/
|
||
|
|
||
|
module
|
||
|
|
||
|
|
||
|
.value('fileUploaderOptions', {
|
||
|
url: '/',
|
||
|
alias: 'file',
|
||
|
headers: {},
|
||
|
queue: [],
|
||
|
progress: 0,
|
||
|
autoUpload: false,
|
||
|
removeAfterUpload: false,
|
||
|
method: 'POST',
|
||
|
filters: [],
|
||
|
formData: [],
|
||
|
queueLimit: Number.MAX_VALUE,
|
||
|
withCredentials: false
|
||
|
})
|
||
|
|
||
|
|
||
|
.factory('FileUploader', ['fileUploaderOptions', '$rootScope', '$http', '$window', '$compile',
|
||
|
function(fileUploaderOptions, $rootScope, $http, $window, $compile) {
|
||
|
/**
|
||
|
* Creates an instance of FileUploader
|
||
|
* @param {Object} [options]
|
||
|
* @constructor
|
||
|
*/
|
||
|
function FileUploader(options) {
|
||
|
var settings = angular.copy(fileUploaderOptions);
|
||
|
angular.extend(this, settings, options, {
|
||
|
isUploading: false,
|
||
|
_nextIndex: 0,
|
||
|
_failFilterIndex: -1,
|
||
|
_directives: {select: [], drop: [], over: []}
|
||
|
});
|
||
|
|
||
|
// add default filters
|
||
|
this.filters.unshift({name: 'queueLimit', fn: this._queueLimitFilter});
|
||
|
this.filters.unshift({name: 'folder', fn: this._folderFilter});
|
||
|
}
|
||
|
/**********************
|
||
|
* PUBLIC
|
||
|
**********************/
|
||
|
/**
|
||
|
* Checks a support the html5 uploader
|
||
|
* @returns {Boolean}
|
||
|
* @readonly
|
||
|
*/
|
||
|
FileUploader.prototype.isHTML5 = !!($window.File && $window.FormData);
|
||
|
/**
|
||
|
* Adds items to the queue
|
||
|
* @param {File|HTMLInputElement|Object|FileList|Array<Object>} files
|
||
|
* @param {Object} [options]
|
||
|
* @param {Array<Function>|String} filters
|
||
|
*/
|
||
|
FileUploader.prototype.addToQueue = function(files, options, filters) {
|
||
|
var list = this.isArrayLikeObject(files) ? files: [files];
|
||
|
var arrayOfFilters = this._getFilters(filters);
|
||
|
var count = this.queue.length;
|
||
|
var addedFileItems = [];
|
||
|
|
||
|
angular.forEach(list, function(some /*{File|HTMLInputElement|Object}*/) {
|
||
|
var temp = new FileUploader.FileLikeObject(some);
|
||
|
|
||
|
if (this._isValidFile(temp, arrayOfFilters, options)) {
|
||
|
var fileItem = new FileUploader.FileItem(this, some, options);
|
||
|
addedFileItems.push(fileItem);
|
||
|
this.queue.push(fileItem);
|
||
|
this._onAfterAddingFile(fileItem);
|
||
|
} else {
|
||
|
var filter = arrayOfFilters[this._failFilterIndex];
|
||
|
this._onWhenAddingFileFailed(temp, filter, options);
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
if(this.queue.length !== count) {
|
||
|
this._onAfterAddingAll(addedFileItems);
|
||
|
this.progress = this._getTotalProgress();
|
||
|
}
|
||
|
|
||
|
this._render();
|
||
|
if (this.autoUpload) this.uploadAll();
|
||
|
};
|
||
|
/**
|
||
|
* Remove items from the queue. Remove last: index = -1
|
||
|
* @param {FileItem|Number} value
|
||
|
*/
|
||
|
FileUploader.prototype.removeFromQueue = function(value) {
|
||
|
var index = this.getIndexOfItem(value);
|
||
|
var item = this.queue[index];
|
||
|
if (item.isUploading) item.cancel();
|
||
|
this.queue.splice(index, 1);
|
||
|
item._destroy();
|
||
|
this.progress = this._getTotalProgress();
|
||
|
};
|
||
|
/**
|
||
|
* Clears the queue
|
||
|
*/
|
||
|
FileUploader.prototype.clearQueue = function() {
|
||
|
while(this.queue.length) {
|
||
|
this.queue[0].remove();
|
||
|
}
|
||
|
this.progress = 0;
|
||
|
};
|
||
|
/**
|
||
|
* Uploads a item from the queue
|
||
|
* @param {FileItem|Number} value
|
||
|
*/
|
||
|
FileUploader.prototype.uploadItem = function(value) {
|
||
|
var index = this.getIndexOfItem(value);
|
||
|
var item = this.queue[index];
|
||
|
var transport = this.isHTML5 ? '_xhrTransport' : '_iframeTransport';
|
||
|
|
||
|
item._prepareToUploading();
|
||
|
if(this.isUploading) return;
|
||
|
|
||
|
this.isUploading = true;
|
||
|
this[transport](item);
|
||
|
};
|
||
|
/**
|
||
|
* Cancels uploading of item from the queue
|
||
|
* @param {FileItem|Number} value
|
||
|
*/
|
||
|
FileUploader.prototype.cancelItem = function(value) {
|
||
|
var index = this.getIndexOfItem(value);
|
||
|
var item = this.queue[index];
|
||
|
var prop = this.isHTML5 ? '_xhr' : '_form';
|
||
|
if (item && item.isUploading) item[prop].abort();
|
||
|
};
|
||
|
/**
|
||
|
* Uploads all not uploaded items of queue
|
||
|
*/
|
||
|
FileUploader.prototype.uploadAll = function() {
|
||
|
var items = this.getNotUploadedItems().filter(function(item) {
|
||
|
return !item.isUploading;
|
||
|
});
|
||
|
if (!items.length) return;
|
||
|
|
||
|
angular.forEach(items, function(item) {
|
||
|
item._prepareToUploading();
|
||
|
});
|
||
|
items[0].upload();
|
||
|
};
|
||
|
/**
|
||
|
* Cancels all uploads
|
||
|
*/
|
||
|
FileUploader.prototype.cancelAll = function() {
|
||
|
var items = this.getNotUploadedItems();
|
||
|
angular.forEach(items, function(item) {
|
||
|
item.cancel();
|
||
|
});
|
||
|
};
|
||
|
/**
|
||
|
* Returns "true" if value an instance of File
|
||
|
* @param {*} value
|
||
|
* @returns {Boolean}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype.isFile = function(value) {
|
||
|
var fn = $window.File;
|
||
|
return (fn && value instanceof fn);
|
||
|
};
|
||
|
/**
|
||
|
* Returns "true" if value an instance of FileLikeObject
|
||
|
* @param {*} value
|
||
|
* @returns {Boolean}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype.isFileLikeObject = function(value) {
|
||
|
return value instanceof FileUploader.FileLikeObject;
|
||
|
};
|
||
|
/**
|
||
|
* Returns "true" if value is array like object
|
||
|
* @param {*} value
|
||
|
* @returns {Boolean}
|
||
|
*/
|
||
|
FileUploader.prototype.isArrayLikeObject = function(value) {
|
||
|
return (angular.isObject(value) && 'length' in value);
|
||
|
};
|
||
|
/**
|
||
|
* Returns a index of item from the queue
|
||
|
* @param {Item|Number} value
|
||
|
* @returns {Number}
|
||
|
*/
|
||
|
FileUploader.prototype.getIndexOfItem = function(value) {
|
||
|
return angular.isNumber(value) ? value : this.queue.indexOf(value);
|
||
|
};
|
||
|
/**
|
||
|
* Returns not uploaded items
|
||
|
* @returns {Array}
|
||
|
*/
|
||
|
FileUploader.prototype.getNotUploadedItems = function() {
|
||
|
return this.queue.filter(function(item) {
|
||
|
return !item.isUploaded;
|
||
|
});
|
||
|
};
|
||
|
/**
|
||
|
* Returns items ready for upload
|
||
|
* @returns {Array}
|
||
|
*/
|
||
|
FileUploader.prototype.getReadyItems = function() {
|
||
|
return this.queue
|
||
|
.filter(function(item) {
|
||
|
return (item.isReady && !item.isUploading);
|
||
|
})
|
||
|
.sort(function(item1, item2) {
|
||
|
return item1.index - item2.index;
|
||
|
});
|
||
|
};
|
||
|
/**
|
||
|
* Destroys instance of FileUploader
|
||
|
*/
|
||
|
FileUploader.prototype.destroy = function() {
|
||
|
angular.forEach(this._directives, function(key) {
|
||
|
angular.forEach(this._directives[key], function(object) {
|
||
|
object.destroy();
|
||
|
}, this);
|
||
|
}, this);
|
||
|
};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {Array} fileItems
|
||
|
*/
|
||
|
FileUploader.prototype.onAfterAddingAll = function(fileItems) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {FileItem} fileItem
|
||
|
*/
|
||
|
FileUploader.prototype.onAfterAddingFile = function(fileItem) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {File|Object} item
|
||
|
* @param {Object} filter
|
||
|
* @param {Object} options
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype.onWhenAddingFileFailed = function(item, filter, options) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {FileItem} fileItem
|
||
|
*/
|
||
|
FileUploader.prototype.onBeforeUploadItem = function(fileItem) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {FileItem} fileItem
|
||
|
* @param {Number} progress
|
||
|
*/
|
||
|
FileUploader.prototype.onProgressItem = function(fileItem, progress) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {Number} progress
|
||
|
*/
|
||
|
FileUploader.prototype.onProgressAll = function(progress) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileUploader.prototype.onSuccessItem = function(item, response, status, headers) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileUploader.prototype.onErrorItem = function(item, response, status, headers) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileUploader.prototype.onCancelItem = function(item, response, status, headers) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileUploader.prototype.onCompleteItem = function(item, response, status, headers) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
*/
|
||
|
FileUploader.prototype.onCompleteAll = function() {};
|
||
|
/**********************
|
||
|
* PRIVATE
|
||
|
**********************/
|
||
|
/**
|
||
|
* Returns the total progress
|
||
|
* @param {Number} [value]
|
||
|
* @returns {Number}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._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);
|
||
|
};
|
||
|
/**
|
||
|
* Returns array of filters
|
||
|
* @param {Array<Function>|String} filters
|
||
|
* @returns {Array<Function>}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._getFilters = function(filters) {
|
||
|
if (angular.isUndefined(filters)) return this.filters;
|
||
|
if (angular.isArray(filters)) return filters;
|
||
|
var names = filters.match(/[^\s,]+/g);
|
||
|
return this.filters.filter(function(filter) {
|
||
|
return names.indexOf(filter.name) !== -1;
|
||
|
}, this);
|
||
|
};
|
||
|
/**
|
||
|
* Updates html
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._render = function() {
|
||
|
if (!$rootScope.$$phase) $rootScope.$apply();
|
||
|
};
|
||
|
/**
|
||
|
* Returns "true" if item is a file (not folder)
|
||
|
* @param {File|FileLikeObject} item
|
||
|
* @returns {Boolean}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._folderFilter = function(item) {
|
||
|
return !!(item.size || item.type);
|
||
|
};
|
||
|
/**
|
||
|
* Returns "true" if the limit has not been reached
|
||
|
* @returns {Boolean}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._queueLimitFilter = function() {
|
||
|
return this.queue.length < this.queueLimit;
|
||
|
};
|
||
|
/**
|
||
|
* Returns "true" if file pass all filters
|
||
|
* @param {File|Object} file
|
||
|
* @param {Array<Function>} filters
|
||
|
* @param {Object} options
|
||
|
* @returns {Boolean}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._isValidFile = function(file, filters, options) {
|
||
|
this._failFilterIndex = -1;
|
||
|
return !filters.length ? true : filters.every(function(filter) {
|
||
|
this._failFilterIndex++;
|
||
|
return filter.fn.call(this, file, options);
|
||
|
}, this);
|
||
|
};
|
||
|
/**
|
||
|
* Checks whether upload successful
|
||
|
* @param {Number} status
|
||
|
* @returns {Boolean}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._isSuccessCode = function(status) {
|
||
|
return (status >= 200 && status < 300) || status === 304;
|
||
|
};
|
||
|
/**
|
||
|
* Transforms the server response
|
||
|
* @param {*} response
|
||
|
* @param {Object} headers
|
||
|
* @returns {*}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._transformResponse = function(response, headers) {
|
||
|
var headersGetter = this._headersGetter(headers);
|
||
|
angular.forEach($http.defaults.transformResponse, function(transformFn) {
|
||
|
response = transformFn(response, headersGetter);
|
||
|
});
|
||
|
return response;
|
||
|
};
|
||
|
/**
|
||
|
* Parsed response headers
|
||
|
* @param headers
|
||
|
* @returns {Object}
|
||
|
* @see https://github.com/angular/angular.js/blob/master/src/ng/http.js
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._parseHeaders = function(headers) {
|
||
|
var parsed = {}, key, val, i;
|
||
|
|
||
|
if (!headers) return parsed;
|
||
|
|
||
|
angular.forEach(headers.split('\n'), function(line) {
|
||
|
i = line.indexOf(':');
|
||
|
key = line.slice(0, i).trim().toLowerCase();
|
||
|
val = line.slice(i + 1).trim();
|
||
|
|
||
|
if (key) {
|
||
|
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return parsed;
|
||
|
};
|
||
|
/**
|
||
|
* Returns function that returns headers
|
||
|
* @param {Object} parsedHeaders
|
||
|
* @returns {Function}
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._headersGetter = function(parsedHeaders) {
|
||
|
return function(name) {
|
||
|
if (name) {
|
||
|
return parsedHeaders[name.toLowerCase()] || null;
|
||
|
}
|
||
|
return parsedHeaders;
|
||
|
};
|
||
|
};
|
||
|
/**
|
||
|
* The XMLHttpRequest transport
|
||
|
* @param {FileItem} item
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._xhrTransport = function(item) {
|
||
|
var xhr = item._xhr = new XMLHttpRequest();
|
||
|
var form = new FormData();
|
||
|
var that = this;
|
||
|
|
||
|
that._onBeforeUploadItem(item);
|
||
|
|
||
|
angular.forEach(item.formData, function(obj) {
|
||
|
angular.forEach(obj, function(value, key) {
|
||
|
form.append(key, value);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
if ( typeof(item._file.size) != 'number' ) {
|
||
|
throw new TypeError('The file specified is no longer valid');
|
||
|
}
|
||
|
|
||
|
form.append(item.alias, item._file, item.file.name);
|
||
|
|
||
|
xhr.upload.onprogress = function(event) {
|
||
|
var progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
|
||
|
that._onProgressItem(item, progress);
|
||
|
};
|
||
|
|
||
|
xhr.onload = function() {
|
||
|
var headers = that._parseHeaders(xhr.getAllResponseHeaders());
|
||
|
var response = that._transformResponse(xhr.response, headers);
|
||
|
var gist = that._isSuccessCode(xhr.status) ? 'Success' : 'Error';
|
||
|
var method = '_on' + gist + 'Item';
|
||
|
that[method](item, response, xhr.status, headers);
|
||
|
that._onCompleteItem(item, response, xhr.status, headers);
|
||
|
};
|
||
|
|
||
|
xhr.onerror = function() {
|
||
|
var headers = that._parseHeaders(xhr.getAllResponseHeaders());
|
||
|
var response = that._transformResponse(xhr.response, headers);
|
||
|
that._onErrorItem(item, response, xhr.status, headers);
|
||
|
that._onCompleteItem(item, response, xhr.status, headers);
|
||
|
};
|
||
|
|
||
|
xhr.onabort = function() {
|
||
|
var headers = that._parseHeaders(xhr.getAllResponseHeaders());
|
||
|
var response = that._transformResponse(xhr.response, headers);
|
||
|
that._onCancelItem(item, response, xhr.status, headers);
|
||
|
that._onCompleteItem(item, response, xhr.status, headers);
|
||
|
};
|
||
|
|
||
|
xhr.open(item.method, item.url, true);
|
||
|
|
||
|
xhr.withCredentials = item.withCredentials;
|
||
|
|
||
|
angular.forEach(item.headers, function(value, name) {
|
||
|
xhr.setRequestHeader(name, value);
|
||
|
});
|
||
|
|
||
|
xhr.send(form);
|
||
|
this._render();
|
||
|
};
|
||
|
/**
|
||
|
* The IFrame transport
|
||
|
* @param {FileItem} item
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._iframeTransport = function(item) {
|
||
|
var form = angular.element('<form style="display: none;" />');
|
||
|
var iframe = angular.element('<iframe name="iframeTransport' + Date.now() + '">');
|
||
|
var input = item._input;
|
||
|
var that = this;
|
||
|
|
||
|
if (item._form) item._form.replaceWith(input); // remove old form
|
||
|
item._form = form; // save link to new form
|
||
|
|
||
|
that._onBeforeUploadItem(item);
|
||
|
|
||
|
input.prop('name', item.alias);
|
||
|
|
||
|
angular.forEach(item.formData, function(obj) {
|
||
|
angular.forEach(obj, function(value, key) {
|
||
|
var element = angular.element('<input type="hidden" name="' + key + '" />');
|
||
|
element.val(value);
|
||
|
form.append(element);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
form.prop({
|
||
|
action: item.url,
|
||
|
method: 'POST',
|
||
|
target: iframe.prop('name'),
|
||
|
enctype: 'multipart/form-data',
|
||
|
encoding: 'multipart/form-data' // old IE
|
||
|
});
|
||
|
|
||
|
iframe.bind('load', function() {
|
||
|
try {
|
||
|
// Fix for legacy IE browsers that loads internal error page
|
||
|
// when failed WS response received. In consequence iframe
|
||
|
// content access denied error is thrown becouse trying to
|
||
|
// access cross domain page. When such thing occurs notifying
|
||
|
// with empty response object. See more info at:
|
||
|
// http://stackoverflow.com/questions/151362/access-is-denied-error-on-accessing-iframe-document-object
|
||
|
// Note that if non standard 4xx or 5xx error code returned
|
||
|
// from WS then response content can be accessed without error
|
||
|
// but 'XHR' status becomes 200. In order to avoid confusion
|
||
|
// returning response via same 'success' event handler.
|
||
|
|
||
|
// fixed angular.contents() for iframes
|
||
|
var html = iframe[0].contentDocument.body.innerHTML;
|
||
|
} catch (e) {}
|
||
|
|
||
|
var xhr = {response: html, status: 200, dummy: true};
|
||
|
var headers = {};
|
||
|
var response = that._transformResponse(xhr.response, headers);
|
||
|
|
||
|
that._onSuccessItem(item, response, xhr.status, headers);
|
||
|
that._onCompleteItem(item, response, xhr.status, headers);
|
||
|
});
|
||
|
|
||
|
form.abort = function() {
|
||
|
var xhr = {status: 0, dummy: true};
|
||
|
var headers = {};
|
||
|
var response;
|
||
|
|
||
|
iframe.unbind('load').prop('src', 'javascript:false;');
|
||
|
form.replaceWith(input);
|
||
|
|
||
|
that._onCancelItem(item, response, xhr.status, headers);
|
||
|
that._onCompleteItem(item, response, xhr.status, headers);
|
||
|
};
|
||
|
|
||
|
input.after(form);
|
||
|
form.append(input).append(iframe);
|
||
|
|
||
|
form[0].submit();
|
||
|
this._render();
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {File|Object} item
|
||
|
* @param {Object} filter
|
||
|
* @param {Object} options
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._onWhenAddingFileFailed = function(item, filter, options) {
|
||
|
this.onWhenAddingFileFailed(item, filter, options);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {FileItem} item
|
||
|
*/
|
||
|
FileUploader.prototype._onAfterAddingFile = function(item) {
|
||
|
this.onAfterAddingFile(item);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {Array<FileItem>} items
|
||
|
*/
|
||
|
FileUploader.prototype._onAfterAddingAll = function(items) {
|
||
|
this.onAfterAddingAll(items);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {FileItem} item
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._onBeforeUploadItem = function(item) {
|
||
|
item._onBeforeUpload();
|
||
|
this.onBeforeUploadItem(item);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {Number} progress
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._onProgressItem = function(item, progress) {
|
||
|
var total = this._getTotalProgress(progress);
|
||
|
this.progress = total;
|
||
|
item._onProgress(progress);
|
||
|
this.onProgressItem(item, progress);
|
||
|
this.onProgressAll(total);
|
||
|
this._render();
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._onSuccessItem = function(item, response, status, headers) {
|
||
|
item._onSuccess(response, status, headers);
|
||
|
this.onSuccessItem(item, response, status, headers);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._onErrorItem = function(item, response, status, headers) {
|
||
|
item._onError(response, status, headers);
|
||
|
this.onErrorItem(item, response, status, headers);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._onCancelItem = function(item, response, status, headers) {
|
||
|
item._onCancel(response, status, headers);
|
||
|
this.onCancelItem(item, response, status, headers);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {FileItem} item
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileUploader.prototype._onCompleteItem = function(item, response, status, headers) {
|
||
|
item._onComplete(response, status, headers);
|
||
|
this.onCompleteItem(item, response, status, headers);
|
||
|
|
||
|
var nextItem = this.getReadyItems()[0];
|
||
|
this.isUploading = false;
|
||
|
|
||
|
if(angular.isDefined(nextItem)) {
|
||
|
nextItem.upload();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this.onCompleteAll();
|
||
|
this.progress = this._getTotalProgress();
|
||
|
this._render();
|
||
|
};
|
||
|
/**********************
|
||
|
* STATIC
|
||
|
**********************/
|
||
|
/**
|
||
|
* @borrows FileUploader.prototype.isFile
|
||
|
*/
|
||
|
FileUploader.isFile = FileUploader.prototype.isFile;
|
||
|
/**
|
||
|
* @borrows FileUploader.prototype.isFileLikeObject
|
||
|
*/
|
||
|
FileUploader.isFileLikeObject = FileUploader.prototype.isFileLikeObject;
|
||
|
/**
|
||
|
* @borrows FileUploader.prototype.isArrayLikeObject
|
||
|
*/
|
||
|
FileUploader.isArrayLikeObject = FileUploader.prototype.isArrayLikeObject;
|
||
|
/**
|
||
|
* @borrows FileUploader.prototype.isHTML5
|
||
|
*/
|
||
|
FileUploader.isHTML5 = FileUploader.prototype.isHTML5;
|
||
|
/**
|
||
|
* Inherits a target (Class_1) by a source (Class_2)
|
||
|
* @param {Function} target
|
||
|
* @param {Function} source
|
||
|
*/
|
||
|
FileUploader.inherit = function(target, source) {
|
||
|
target.prototype = Object.create(source.prototype);
|
||
|
target.prototype.constructor = target;
|
||
|
target.super_ = source;
|
||
|
};
|
||
|
FileUploader.FileLikeObject = FileLikeObject;
|
||
|
FileUploader.FileItem = FileItem;
|
||
|
FileUploader.FileDirective = FileDirective;
|
||
|
FileUploader.FileSelect = FileSelect;
|
||
|
FileUploader.FileDrop = FileDrop;
|
||
|
FileUploader.FileOver = FileOver;
|
||
|
|
||
|
// ---------------------------
|
||
|
|
||
|
/**
|
||
|
* Creates an instance of FileLikeObject
|
||
|
* @param {File|HTMLInputElement|Object} fileOrInput
|
||
|
* @constructor
|
||
|
*/
|
||
|
function FileLikeObject(fileOrInput) {
|
||
|
var isInput = angular.isElement(fileOrInput);
|
||
|
var fakePathOrObject = isInput ? fileOrInput.value : fileOrInput;
|
||
|
var postfix = angular.isString(fakePathOrObject) ? 'FakePath' : 'Object';
|
||
|
var method = '_createFrom' + postfix;
|
||
|
this[method](fakePathOrObject);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates file like object from fake path string
|
||
|
* @param {String} path
|
||
|
* @private
|
||
|
*/
|
||
|
FileLikeObject.prototype._createFromFakePath = function(path) {
|
||
|
this.lastModifiedDate = null;
|
||
|
this.size = null;
|
||
|
this.type = 'like/' + path.slice(path.lastIndexOf('.') + 1).toLowerCase();
|
||
|
this.name = path.slice(path.lastIndexOf('/') + path.lastIndexOf('\\') + 2);
|
||
|
};
|
||
|
/**
|
||
|
* Creates file like object from object
|
||
|
* @param {File|FileLikeObject} object
|
||
|
* @private
|
||
|
*/
|
||
|
FileLikeObject.prototype._createFromObject = function(object) {
|
||
|
this.lastModifiedDate = angular.copy(object.lastModifiedDate);
|
||
|
this.size = object.size;
|
||
|
this.type = object.type;
|
||
|
this.name = object.name;
|
||
|
};
|
||
|
|
||
|
// ---------------------------
|
||
|
|
||
|
/**
|
||
|
* Creates an instance of FileItem
|
||
|
* @param {FileUploader} uploader
|
||
|
* @param {File|HTMLInputElement|Object} some
|
||
|
* @param {Object} options
|
||
|
* @constructor
|
||
|
*/
|
||
|
function FileItem(uploader, some, options) {
|
||
|
var isInput = angular.isElement(some);
|
||
|
var input = isInput ? angular.element(some) : null;
|
||
|
var file = !isInput ? some : null;
|
||
|
|
||
|
angular.extend(this, {
|
||
|
url: uploader.url,
|
||
|
alias: uploader.alias,
|
||
|
headers: angular.copy(uploader.headers),
|
||
|
formData: angular.copy(uploader.formData),
|
||
|
removeAfterUpload: uploader.removeAfterUpload,
|
||
|
withCredentials: uploader.withCredentials,
|
||
|
method: uploader.method
|
||
|
}, options, {
|
||
|
uploader: uploader,
|
||
|
file: new FileUploader.FileLikeObject(some),
|
||
|
isReady: false,
|
||
|
isUploading: false,
|
||
|
isUploaded: false,
|
||
|
isSuccess: false,
|
||
|
isCancel: false,
|
||
|
isError: false,
|
||
|
progress: 0,
|
||
|
index: null,
|
||
|
_file: file,
|
||
|
_input: input
|
||
|
});
|
||
|
|
||
|
if (input) this._replaceNode(input);
|
||
|
}
|
||
|
/**********************
|
||
|
* PUBLIC
|
||
|
**********************/
|
||
|
/**
|
||
|
* Uploads a FileItem
|
||
|
*/
|
||
|
FileItem.prototype.upload = function() {
|
||
|
try {
|
||
|
this.uploader.uploadItem(this);
|
||
|
} catch (e) {
|
||
|
this.uploader._onCompleteItem( this, '', 0, [] );
|
||
|
this.uploader._onErrorItem( this, '', 0, [] );
|
||
|
}
|
||
|
};
|
||
|
/**
|
||
|
* Cancels uploading of FileItem
|
||
|
*/
|
||
|
FileItem.prototype.cancel = function() {
|
||
|
this.uploader.cancelItem(this);
|
||
|
};
|
||
|
/**
|
||
|
* Removes a FileItem
|
||
|
*/
|
||
|
FileItem.prototype.remove = function() {
|
||
|
this.uploader.removeFromQueue(this);
|
||
|
};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype.onBeforeUpload = function() {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {Number} progress
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype.onProgress = function(progress) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileItem.prototype.onSuccess = function(response, status, headers) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileItem.prototype.onError = function(response, status, headers) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileItem.prototype.onCancel = function(response, status, headers) {};
|
||
|
/**
|
||
|
* Callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
*/
|
||
|
FileItem.prototype.onComplete = function(response, status, headers) {};
|
||
|
/**********************
|
||
|
* PRIVATE
|
||
|
**********************/
|
||
|
/**
|
||
|
* Inner callback
|
||
|
*/
|
||
|
FileItem.prototype._onBeforeUpload = function() {
|
||
|
this.isReady = true;
|
||
|
this.isUploading = true;
|
||
|
this.isUploaded = false;
|
||
|
this.isSuccess = false;
|
||
|
this.isCancel = false;
|
||
|
this.isError = false;
|
||
|
this.progress = 0;
|
||
|
this.onBeforeUpload();
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {Number} progress
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype._onProgress = function(progress) {
|
||
|
this.progress = progress;
|
||
|
this.onProgress(progress);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype._onSuccess = function(response, status, headers) {
|
||
|
this.isReady = false;
|
||
|
this.isUploading = false;
|
||
|
this.isUploaded = true;
|
||
|
this.isSuccess = true;
|
||
|
this.isCancel = false;
|
||
|
this.isError = false;
|
||
|
this.progress = 100;
|
||
|
this.index = null;
|
||
|
this.onSuccess(response, status, headers);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype._onError = function(response, status, headers) {
|
||
|
this.isReady = false;
|
||
|
this.isUploading = false;
|
||
|
this.isUploaded = true;
|
||
|
this.isSuccess = false;
|
||
|
this.isCancel = false;
|
||
|
this.isError = true;
|
||
|
this.progress = 0;
|
||
|
this.index = null;
|
||
|
this.onError(response, status, headers);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype._onCancel = function(response, status, headers) {
|
||
|
this.isReady = false;
|
||
|
this.isUploading = false;
|
||
|
this.isUploaded = false;
|
||
|
this.isSuccess = false;
|
||
|
this.isCancel = true;
|
||
|
this.isError = false;
|
||
|
this.progress = 0;
|
||
|
this.index = null;
|
||
|
this.onCancel(response, status, headers);
|
||
|
};
|
||
|
/**
|
||
|
* Inner callback
|
||
|
* @param {*} response
|
||
|
* @param {Number} status
|
||
|
* @param {Object} headers
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype._onComplete = function(response, status, headers) {
|
||
|
this.onComplete(response, status, headers);
|
||
|
if (this.removeAfterUpload) this.remove();
|
||
|
};
|
||
|
/**
|
||
|
* Destroys a FileItem
|
||
|
*/
|
||
|
FileItem.prototype._destroy = function() {
|
||
|
if (this._input) this._input.remove();
|
||
|
if (this._form) this._form.remove();
|
||
|
delete this._form;
|
||
|
delete this._input;
|
||
|
};
|
||
|
/**
|
||
|
* Prepares to uploading
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype._prepareToUploading = function() {
|
||
|
this.index = this.index || ++this.uploader._nextIndex;
|
||
|
this.isReady = true;
|
||
|
};
|
||
|
/**
|
||
|
* Replaces input element on his clone
|
||
|
* @param {JQLite|jQuery} input
|
||
|
* @private
|
||
|
*/
|
||
|
FileItem.prototype._replaceNode = function(input) {
|
||
|
var clone = $compile(input.clone())(input.scope());
|
||
|
clone.prop('value', null); // FF fix
|
||
|
input.css('display', 'none');
|
||
|
input.after(clone); // remove jquery dependency
|
||
|
};
|
||
|
|
||
|
// ---------------------------
|
||
|
|
||
|
/**
|
||
|
* Creates instance of {FileDirective} object
|
||
|
* @param {Object} options
|
||
|
* @param {Object} options.uploader
|
||
|
* @param {HTMLElement} options.element
|
||
|
* @param {Object} options.events
|
||
|
* @param {String} options.prop
|
||
|
* @constructor
|
||
|
*/
|
||
|
function FileDirective(options) {
|
||
|
angular.extend(this, options);
|
||
|
this.uploader._directives[this.prop].push(this);
|
||
|
this._saveLinks();
|
||
|
this.bind();
|
||
|
}
|
||
|
/**
|
||
|
* Map of events
|
||
|
* @type {Object}
|
||
|
*/
|
||
|
FileDirective.prototype.events = {};
|
||
|
/**
|
||
|
* Binds events handles
|
||
|
*/
|
||
|
FileDirective.prototype.bind = function() {
|
||
|
for(var key in this.events) {
|
||
|
var prop = this.events[key];
|
||
|
this.element.bind(key, this[prop]);
|
||
|
}
|
||
|
};
|
||
|
/**
|
||
|
* Unbinds events handles
|
||
|
*/
|
||
|
FileDirective.prototype.unbind = function() {
|
||
|
for(var key in this.events) {
|
||
|
this.element.unbind(key, this.events[key]);
|
||
|
}
|
||
|
};
|
||
|
/**
|
||
|
* Destroys directive
|
||
|
*/
|
||
|
FileDirective.prototype.destroy = function() {
|
||
|
var index = this.uploader._directives[this.prop].indexOf(this);
|
||
|
this.uploader._directives[this.prop].splice(index, 1);
|
||
|
this.unbind();
|
||
|
// this.element = null;
|
||
|
};
|
||
|
/**
|
||
|
* Saves links to functions
|
||
|
* @private
|
||
|
*/
|
||
|
FileDirective.prototype._saveLinks = function() {
|
||
|
for(var key in this.events) {
|
||
|
var prop = this.events[key];
|
||
|
this[prop] = this[prop].bind(this);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// ---------------------------
|
||
|
|
||
|
FileUploader.inherit(FileSelect, FileDirective);
|
||
|
|
||
|
/**
|
||
|
* Creates instance of {FileSelect} object
|
||
|
* @param {Object} options
|
||
|
* @constructor
|
||
|
*/
|
||
|
function FileSelect(options) {
|
||
|
FileSelect.super_.apply(this, arguments);
|
||
|
|
||
|
if(!this.uploader.isHTML5) {
|
||
|
this.element.removeAttr('multiple');
|
||
|
}
|
||
|
this.element.prop('value', null); // FF fix
|
||
|
}
|
||
|
/**
|
||
|
* Map of events
|
||
|
* @type {Object}
|
||
|
*/
|
||
|
FileSelect.prototype.events = {
|
||
|
$destroy: 'destroy',
|
||
|
change: 'onChange'
|
||
|
};
|
||
|
/**
|
||
|
* Name of property inside uploader._directive object
|
||
|
* @type {String}
|
||
|
*/
|
||
|
FileSelect.prototype.prop = 'select';
|
||
|
/**
|
||
|
* Returns options
|
||
|
* @return {Object|undefined}
|
||
|
*/
|
||
|
FileSelect.prototype.getOptions = function() {};
|
||
|
/**
|
||
|
* Returns filters
|
||
|
* @return {Array<Function>|String|undefined}
|
||
|
*/
|
||
|
FileSelect.prototype.getFilters = function() {};
|
||
|
/**
|
||
|
* If returns "true" then HTMLInputElement will be cleared
|
||
|
* @returns {Boolean}
|
||
|
*/
|
||
|
FileSelect.prototype.isEmptyAfterSelection = function() {
|
||
|
return !!this.element.attr('multiple');
|
||
|
};
|
||
|
/**
|
||
|
* Event handler
|
||
|
*/
|
||
|
FileSelect.prototype.onChange = function() {
|
||
|
var files = this.uploader.isHTML5 ? this.element[0].files : this.element[0];
|
||
|
var options = this.getOptions();
|
||
|
var filters = this.getFilters();
|
||
|
|
||
|
if (!this.uploader.isHTML5) this.destroy();
|
||
|
this.uploader.addToQueue(files, options, filters);
|
||
|
if (this.isEmptyAfterSelection()) this.element.prop('value', null);
|
||
|
};
|
||
|
|
||
|
// ---------------------------
|
||
|
|
||
|
FileUploader.inherit(FileDrop, FileDirective);
|
||
|
|
||
|
/**
|
||
|
* Creates instance of {FileDrop} object
|
||
|
* @param {Object} options
|
||
|
* @constructor
|
||
|
*/
|
||
|
function FileDrop(options) {
|
||
|
FileDrop.super_.apply(this, arguments);
|
||
|
}
|
||
|
/**
|
||
|
* Map of events
|
||
|
* @type {Object}
|
||
|
*/
|
||
|
FileDrop.prototype.events = {
|
||
|
$destroy: 'destroy',
|
||
|
drop: 'onDrop',
|
||
|
dragover: 'onDragOver',
|
||
|
dragleave: 'onDragLeave'
|
||
|
};
|
||
|
/**
|
||
|
* Name of property inside uploader._directive object
|
||
|
* @type {String}
|
||
|
*/
|
||
|
FileDrop.prototype.prop = 'drop';
|
||
|
/**
|
||
|
* Returns options
|
||
|
* @return {Object|undefined}
|
||
|
*/
|
||
|
FileDrop.prototype.getOptions = function() {};
|
||
|
/**
|
||
|
* Returns filters
|
||
|
* @return {Array<Function>|String|undefined}
|
||
|
*/
|
||
|
FileDrop.prototype.getFilters = function() {};
|
||
|
/**
|
||
|
* Event handler
|
||
|
*/
|
||
|
FileDrop.prototype.onDrop = function(event) {
|
||
|
var transfer = this._getTransfer(event);
|
||
|
if (!transfer) return;
|
||
|
var options = this.getOptions();
|
||
|
var filters = this.getFilters();
|
||
|
this._preventAndStop(event);
|
||
|
angular.forEach(this.uploader._directives.over, this._removeOverClass, this);
|
||
|
this.uploader.addToQueue(transfer.files, options, filters);
|
||
|
};
|
||
|
/**
|
||
|
* Event handler
|
||
|
*/
|
||
|
FileDrop.prototype.onDragOver = function(event) {
|
||
|
var transfer = this._getTransfer(event);
|
||
|
if(!this._haveFiles(transfer.types)) return;
|
||
|
transfer.dropEffect = 'copy';
|
||
|
this._preventAndStop(event);
|
||
|
angular.forEach(this.uploader._directives.over, this._addOverClass, this);
|
||
|
};
|
||
|
/**
|
||
|
* Event handler
|
||
|
*/
|
||
|
FileDrop.prototype.onDragLeave = function(event) {
|
||
|
if (event.currentTarget !== this.element[0]) return;
|
||
|
this._preventAndStop(event);
|
||
|
angular.forEach(this.uploader._directives.over, this._removeOverClass, this);
|
||
|
};
|
||
|
/**
|
||
|
* Helper
|
||
|
*/
|
||
|
FileDrop.prototype._getTransfer = function(event) {
|
||
|
return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; // jQuery fix;
|
||
|
};
|
||
|
/**
|
||
|
* Helper
|
||
|
*/
|
||
|
FileDrop.prototype._preventAndStop = function(event) {
|
||
|
event.preventDefault();
|
||
|
event.stopPropagation();
|
||
|
};
|
||
|
/**
|
||
|
* Returns "true" if types contains files
|
||
|
* @param {Object} types
|
||
|
*/
|
||
|
FileDrop.prototype._haveFiles = function(types) {
|
||
|
if (!types) return false;
|
||
|
if (types.indexOf) {
|
||
|
return types.indexOf('Files') !== -1;
|
||
|
} else if(types.contains) {
|
||
|
return types.contains('Files');
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
};
|
||
|
/**
|
||
|
* Callback
|
||
|
*/
|
||
|
FileDrop.prototype._addOverClass = function(item) {
|
||
|
item.addOverClass();
|
||
|
};
|
||
|
/**
|
||
|
* Callback
|
||
|
*/
|
||
|
FileDrop.prototype._removeOverClass = function(item) {
|
||
|
item.removeOverClass();
|
||
|
};
|
||
|
|
||
|
// ---------------------------
|
||
|
|
||
|
FileUploader.inherit(FileOver, FileDirective);
|
||
|
|
||
|
/**
|
||
|
* Creates instance of {FileDrop} object
|
||
|
* @param {Object} options
|
||
|
* @constructor
|
||
|
*/
|
||
|
function FileOver(options) {
|
||
|
FileOver.super_.apply(this, arguments);
|
||
|
}
|
||
|
/**
|
||
|
* Map of events
|
||
|
* @type {Object}
|
||
|
*/
|
||
|
FileOver.prototype.events = {
|
||
|
$destroy: 'destroy'
|
||
|
};
|
||
|
/**
|
||
|
* Name of property inside uploader._directive object
|
||
|
* @type {String}
|
||
|
*/
|
||
|
FileOver.prototype.prop = 'over';
|
||
|
/**
|
||
|
* Over class
|
||
|
* @type {string}
|
||
|
*/
|
||
|
FileOver.prototype.overClass = 'nv-file-over';
|
||
|
/**
|
||
|
* Adds over class
|
||
|
*/
|
||
|
FileOver.prototype.addOverClass = function() {
|
||
|
this.element.addClass(this.getOverClass());
|
||
|
};
|
||
|
/**
|
||
|
* Removes over class
|
||
|
*/
|
||
|
FileOver.prototype.removeOverClass = function() {
|
||
|
this.element.removeClass(this.getOverClass());
|
||
|
};
|
||
|
/**
|
||
|
* Returns over class
|
||
|
* @returns {String}
|
||
|
*/
|
||
|
FileOver.prototype.getOverClass = function() {
|
||
|
return this.overClass;
|
||
|
};
|
||
|
|
||
|
return FileUploader;
|
||
|
}])
|
||
|
|
||
|
|
||
|
.directive('nvFileSelect', ['$parse', 'FileUploader', function($parse, FileUploader) {
|
||
|
return {
|
||
|
link: function(scope, element, attributes) {
|
||
|
var uploader = scope.$eval(attributes.uploader);
|
||
|
|
||
|
if (!(uploader instanceof FileUploader)) {
|
||
|
throw new TypeError('"Uploader" must be an instance of FileUploader');
|
||
|
}
|
||
|
|
||
|
var object = new FileUploader.FileSelect({
|
||
|
uploader: uploader,
|
||
|
element: element
|
||
|
});
|
||
|
|
||
|
object.getOptions = $parse(attributes.options).bind(object, scope);
|
||
|
object.getFilters = function() {return attributes.filters;};
|
||
|
}
|
||
|
};
|
||
|
}])
|
||
|
|
||
|
|
||
|
.directive('nvFileDrop', ['$parse', 'FileUploader', function($parse, FileUploader) {
|
||
|
return {
|
||
|
link: function(scope, element, attributes) {
|
||
|
var uploader = scope.$eval(attributes.uploader);
|
||
|
|
||
|
if (!(uploader instanceof FileUploader)) {
|
||
|
throw new TypeError('"Uploader" must be an instance of FileUploader');
|
||
|
}
|
||
|
|
||
|
if (!uploader.isHTML5) return;
|
||
|
|
||
|
var object = new FileUploader.FileDrop({
|
||
|
uploader: uploader,
|
||
|
element: element
|
||
|
});
|
||
|
|
||
|
object.getOptions = $parse(attributes.options).bind(object, scope);
|
||
|
object.getFilters = function() {return attributes.filters;};
|
||
|
}
|
||
|
};
|
||
|
}])
|
||
|
|
||
|
|
||
|
.directive('nvFileOver', ['FileUploader', function(FileUploader) {
|
||
|
return {
|
||
|
link: function(scope, element, attributes) {
|
||
|
var uploader = scope.$eval(attributes.uploader);
|
||
|
|
||
|
if (!(uploader instanceof FileUploader)) {
|
||
|
throw new TypeError('"Uploader" must be an instance of FileUploader');
|
||
|
}
|
||
|
|
||
|
var object = new FileUploader.FileOver({
|
||
|
uploader: uploader,
|
||
|
element: element
|
||
|
});
|
||
|
|
||
|
object.getOverClass = function() {
|
||
|
return attributes.overClass || this.overClass;
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
}])
|
||
|
|
||
|
return module;
|
||
|
}));
|