@glr/ngx-file-uploader
Version:
An angular file uploader library
1,827 lines (1,817 loc) • 59.9 kB
JavaScript
/**
* @license This package library v4.1.6-Beta
* Copyright (c) 2017 FUERSTVONMARTIN GmbH https://fuerstvonmartin.de/
* License: MIT
*/
import { Directive, ElementRef, EventEmitter, HostBinding, HostListener, Input, NgModule, Output, Pipe, Renderer } from '@angular/core';
import { BehaviorSubject } from 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import { DatePipe } from '@angular/common';
class Utils {
/**
* Creates a unique id for submit form.
*
* \@static
* \@memberOf utils
* @return {?}
*
*/
static uniqueID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
// tslint:disable-next-line:no-bitwise
const /** @type {?} */ r = Math.random() * 16 | 0, /** @type {?} */ v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
/**
* Validate input and returns true if input is an element
*
* \@static
*
* \@memberOf FileManager
* @param {?} _input
* @return {?}
*/
static isElement(_input) {
return !!(_input &&
(_input.nodeName ||
(_input.prop && _input.attr && _input.find))); // We have an on and find methode part of jQuery API
}
/**
* Validate input and returns true if input is a string
*
* \@static
*
* \@memberOf Utils
* @param {?} _input
* @return {?}
*/
static isString(_input) {
return !!(typeof _input === 'string');
}
/**
* @param {...?} args
* @return {?}
*/
static extendValue(...args) {
let /** @type {?} */ _value = args[0];
for (let /** @type {?} */ i = 1; i < args.length; i++) {
if (typeof args[i] !== 'undefined') {
_value = args[i];
}
}
return _value;
}
/**
* @param {?} subject
* @return {?}
*/
static asObservable(subject) {
return new Observable((fn) => subject.subscribe(fn));
}
}
Utils._uniqueNumber = 1;
Utils.nextUID = () => (Utils._uniqueNumber++).toString();
let hookType = {};
hookType.beforeAddingFile = 0;
hookType.afterAddingFile = 1;
hookType.errorAddingFile = 2;
hookType.prepareUploadFile = 3;
hookType.progressUploadFile = 4;
hookType.successUploadFile = 5;
hookType.completeUploadFile = 6;
hookType.failedUploadFile = 7;
hookType.cancelUploadFile = 8;
hookType.prepareUploadAll = 9;
hookType.progressUploadAll = 10;
hookType.completeUploadAll = 11;
hookType[hookType.beforeAddingFile] = "beforeAddingFile";
hookType[hookType.afterAddingFile] = "afterAddingFile";
hookType[hookType.errorAddingFile] = "errorAddingFile";
hookType[hookType.prepareUploadFile] = "prepareUploadFile";
hookType[hookType.progressUploadFile] = "progressUploadFile";
hookType[hookType.successUploadFile] = "successUploadFile";
hookType[hookType.completeUploadFile] = "completeUploadFile";
hookType[hookType.failedUploadFile] = "failedUploadFile";
hookType[hookType.cancelUploadFile] = "cancelUploadFile";
hookType[hookType.prepareUploadAll] = "prepareUploadAll";
hookType[hookType.progressUploadAll] = "progressUploadAll";
hookType[hookType.completeUploadAll] = "completeUploadAll";
class UploaderHook {
/**
* @param {?} _hookType
* @param {?} _callback
* @param {?=} _priority
*/
constructor(_hookType, _callback, _priority = 0) {
this._type = null;
this._callback = null;
this._priority = null;
this._type = _hookType;
this._callback = _callback;
this._priority = +_priority;
}
/**
* @return {?}
*/
get type() {
return this._type;
}
/**
* @return {?}
*/
get priority() {
return this._priority;
}
/**
* @return {?}
*/
get callback() {
return this._callback;
}
}
// tslint:disable:no-unused-expression
const TransferOptionsDefault = {
url: '',
alias: 'file',
headers: {},
filters: [],
formData: [],
autoUpload: false,
method: 'POST',
removeBySuccess: false,
queueLimit: -1,
enableCors: false,
withCredentials: false,
uniqueFiles: false
};
/**
* An abstract class for the transport functionality
*
* @export
* @abstract
* \@class Transfer
* @abstract
*/
class Transfer {
/**
* Creates an instance of Transfer.
*
*
* \@memberOf Transfer
* @param {?} type
* @param {?=} _options
*/
constructor(type, _options) {
this.type = type;
this._queue$ = new BehaviorSubject([]);
const div = document.createElement('div');
this._isHTML5 = !!(File && FormData && FileReader);
this._isDragAndDrop = (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) ? true : false;
this._id = Utils.uniqueID();
this._hooks = [];
if (!this._isHTML5) {
throw new Error(`Your browser doesn't support HTML5. Our FileUploader can't work here.`);
}
this.options = Object.assign({}, TransferOptionsDefault, _options);
}
/**
* @return {?}
*/
get id() {
return this._id;
}
/**
* @return {?}
*/
get queue$() {
return Utils.asObservable(this._queue$);
}
/**
* @return {?}
*/
get queueObs() {
return this._queue$.getValue();
}
/**
* Bind options to FileManager
*
*
* \@memberOf FileManager
* @param {?} _options
* @return {?}
*/
bindOptions(_options) {
this.options = Object.assign({}, this.options, _options);
}
/**
* It gives HTML5 check back
*
*
* \@memberOf Transfer
* @return {?}
*/
isHTML5() {
return this._isHTML5;
}
/**
* It gives DragAndDrop check back
*
*
* \@memberOf Transfer
* @return {?}
*/
isDragAndDrop() {
return this._isDragAndDrop;
}
/**
* To implement a hock
*
*
* \@memberOf Transfer
* @param {?} _hook
* @return {?}
*/
hook(_hook) {
if (this.hookExists(_hook) === -1) {
this._hooks.push(_hook);
this._hooks.sort((a, b) => {
if (!(a.type) || !(b.type)) {
return 0;
}
if (a.type !== b.type) {
if (a.type < b.type) {
return -1;
}
if (a.type > b.type) {
return 1;
}
return 0;
}
else {
if (!(a.priority) || !(b.priority)) {
return 0;
}
if (a.priority > b.priority) {
return -1;
}
if (a.priority < b.priority) {
return 1;
}
return 0;
}
});
}
}
/**
*
*
* \@memberOf Transfer
* @param {?} _hook
* @return {?} this
*
*/
removeHook(_hook) {
const /** @type {?} */ key = this.hookExists(_hook);
if (key >= 0) {
this._hooks.splice(key, 1);
return true;
}
return false;
}
/**
* @param {?} _files
* @param {?=} options
* @return {?}
*/
addFilesToQueue(_files, options) {
const /** @type {?} */ _retFiles = [];
let /** @type {?} */ _dummyFile;
let /** @type {?} */ _check = false;
if (Utils.isElement(_files)) {
// If _files was not converted
for (const /** @type {?} */ _fileElement of _files.files) {
try {
_dummyFile = new FileManager(_fileElement, options, this);
}
catch (e) {
throw Error(`Couldn't create a new FileManager object.`);
}
_check = this.addFile(_dummyFile);
(_check) && _retFiles.push(_dummyFile);
}
}
else if (_files instanceof Object) {
// If _files is an array of FileManger
if ((typeof _files[0] !== 'undefined') && (_files[0] instanceof FileManager)) {
for (const /** @type {?} */ _file of _files) {
_check = this.addFile(_file);
(_check) && _retFiles.push(_file);
}
// If _files is only a FileManger
}
else if (_files instanceof FileManager) {
_check = this.addFile(_files);
(_check) && _retFiles.push(_files);
}
else {
throw new Error(`Couldn't put file/files to the queue. [${_files}]`);
}
}
else {
throw new Error(`Couldn't initialise FileUploader file/files are not defined. [${_files}]`);
}
this._onAddFileAll();
return _retFiles;
}
/**
* @param {?} _file
* @return {?}
*/
addFile(_file) {
try {
this.validate(_file);
}
catch (e) {
console.log(e.message);
this._onAddFileError(_file);
return false;
}
const /** @type {?} */ queue = this._queue$.getValue();
if (this.options.uniqueFiles) {
if (this.notInQueue(_file) === -1) {
this._runHook(hookType.beforeAddingFile, _file);
queue.push(_file);
this._queue$.next(queue);
this._onAddFile(_file);
this._runHook(hookType.afterAddingFile, _file);
(this.options.autoUpload) && _file.upload();
return true;
}
}
else {
this._runHook(hookType.beforeAddingFile, _file);
queue.push(_file);
this._queue$.next(queue);
this._onAddFile(_file);
this._runHook(hookType.afterAddingFile, _file);
(this.options.autoUpload) && _file.upload();
return true;
}
this._onAddFileError(_file);
return false;
}
/**
* @param {?} _file
* @return {?}
*/
removeFile(_file) {
const /** @type {?} */ key = this.notInQueue(_file);
const /** @type {?} */ queue = this._queue$.getValue();
if (key >= 0) {
queue.splice(key, 1);
this._queue$.next(queue);
return true;
}
return false;
}
/**
* @param {?} _file
* @return {?}
*/
notInQueue(_file) {
const /** @type {?} */ queue = this._queue$.getValue();
for (const /** @type {?} */ key in queue) {
if (queue.hasOwnProperty(key)) {
const /** @type {?} */ obj = queue[key];
if ((obj.id === _file.id) ||
((obj.name + obj.type + obj.size) ===
(_file.name + _file.type + _file.size))) {
return +key;
}
}
}
return -1;
}
/**
* @param {?} _filter
* @return {?}
*/
addFilter(_filter) {
if (this.filterExists(_filter) !== -1) {
((this.options.filters)).push(_filter);
}
}
/**
* @param {?} _file
* @return {?}
*/
validate(_file) {
for (const /** @type {?} */ _filter of ((this.options.filters))) {
if (!_filter.validate(_file)) {
throw new Error(`File [${_file.name}] doesn't fit with filter [${_filter.name}]`);
}
}
return true;
}
/**
* @param {?} _protocol
* @return {?}
*/
_setProtocol(_protocol) {
this._protocol = _protocol;
}
/**
* @return {?}
*/
_getProtocol() {
return this._protocol;
}
/**
* Validate response status code.
*
*
* \@memberOf Protocol
* @param {?} status
* @return {?}
*/
_isSuccessCode(status) {
return (status >= 200 && status < 300) || status === 304;
}
/**
* Upload functions
* @return {?}
*/
upload() {
this._onBeforeUploadAll();
for (const /** @type {?} */ _file of this.queueObs) {
this.uploadItem(_file);
}
}
/**
* @return {?}
*/
cancel() {
for (const /** @type {?} */ _file of this.queueObs) {
this.cancelUploadItem(_file);
}
}
/**
* @return {?}
*/
remove() {
for (const /** @type {?} */ _file of this.queueObs) {
this.removeFile(_file);
}
}
/**
* @param {?} item
* @return {?}
*/
uploadItem(item) {
if (this.notInQueue(item) === -1) {
this.addFile(item);
}
this._onBeforeUpload(item);
this._getProtocol().run(item);
}
/**
* @param {?} item
* @return {?}
*/
cancelUploadItem(item) {
if (this.notInQueue(item) === -1) {
return;
}
(item.isUploading) && this._getProtocol().cancel(item);
(item.isUploading) && item._cancel();
}
/**
* Overwrite functions
* @param {?} _uploader
* @return {?}
*/
onAddFileAll(_uploader) { return; }
/**
* @param {?} _file
* @return {?}
*/
onAddFile(_file) { return; }
/**
* @param {?} _file
* @return {?}
*/
onAddFileError(_file) { return; }
/**
* @param {?} _uploader
* @return {?}
*/
onBeforeUploadAll(_uploader) { return; }
/**
* @param {?} _file
* @return {?}
*/
onBeforeUpload(_file) { return; }
/**
* @param {?} _uploader
* @param {?} _progress
* @return {?}
*/
onProgress(_uploader, _progress) { return; }
/**
* @param {?} _file
* @param {?} _progress
* @return {?}
*/
onProgressFile(_file, _progress) { return; }
/**
* @param {?} _file
* @param {?} _progress
* @return {?}
*/
onProgressFileSpeed(_file, _progress) { return; }
/**
* @param {?} _file
* @param {?} _response
* @param {?} _status
* @param {?} _headers
* @return {?}
*/
onSuccess(_file, _response, _status, _headers) { return; }
/**
* @param {?} _file
* @param {?} _response
* @param {?} _status
* @param {?} _headers
* @return {?}
*/
onError(_file, _response, _status, _headers) { return; }
/**
* @param {?} _file
* @param {?} _response
* @param {?} _status
* @param {?} _headers
* @return {?}
*/
onComplete(_file, _response, _status, _headers) { return; }
/**
* @param {?} _uploader
* @return {?}
*/
onCompleteAll(_uploader) { return; }
;
/**
*
*
*
* \@memberOf FileManager
* @return {?}
*/
_onAddFileAll() {
this.onAddFileAll(this);
}
/**
* @param {?} _file
* @return {?}
*/
_onAddFile(_file) {
this.onAddFile(_file);
}
/**
* @param {?} _file
* @return {?}
*/
_onAddFileError(_file) {
this._runHook(hookType.errorAddingFile, _file);
this.onAddFileError(_file);
}
/**
* @return {?}
*/
_onBeforeUploadAll() {
this._runHook(hookType.prepareUploadAll, this);
this.onBeforeUploadAll(this);
}
/**
* @param {?} _file
* @return {?}
*/
_onBeforeUpload(_file) {
this._runHook(hookType.prepareUploadFile, _file);
_file._onBeforeUpload();
this.onBeforeUpload(_file);
}
/**
* @param {?} _file
* @param {?} _speed
* @return {?}
*/
_onProgressFileSpeed(_file, _speed) {
this._runHook(hookType.prepareUploadFile, _file, _speed);
_file._onProgressFileSpeed(_speed);
this.onProgressFileSpeed(_file, _speed);
}
/**
* @param {?} _file
* @param {?} _progress
* @return {?}
*/
_onProgressFile(_file, _progress) {
_file._onProgress(_progress);
this.onProgressFile(_file, _progress);
this._onProgress();
}
/**
* @return {?}
*/
_onProgress() {
const /** @type {?} */ queue = this._queue$.getValue();
if (queue.length > 0) {
let /** @type {?} */ percent = 0;
for (const /** @type {?} */ file of queue) {
if (file.success || file.error) {
percent += 100;
}
else if (file.isUploading) {
percent += file.progress;
}
}
percent = Math.floor(percent / queue.length);
this._runHook(hookType.progressUploadAll, percent);
this.onProgress(this, percent);
(percent >= 100) && this._onCompleteAll();
return;
}
this.onProgress(this, 100);
this._onCompleteAll();
}
/**
* @param {?} _file
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onSuccessFile(_file, response, status, headers) {
this._runHook(hookType.successUploadFile, _file, response, status, headers);
_file._onSuccess(response, status, headers);
this.onSuccess(_file, response, status, headers);
}
/**
* @param {?} _file
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onErrorFile(_file, response, status, headers) {
this._runHook(hookType.failedUploadFile, _file, response, status, headers);
this.onError(_file, response, status, headers);
}
/**
* @param {?} _file
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onCompleteFile(_file, response, status, headers) {
this._runHook(hookType.completeUploadFile, _file, response, status, headers);
this._onProgress();
this.onComplete(_file, response, status, headers);
}
/**
* @return {?}
*/
_onCompleteAll() {
this._runHook(hookType.completeUploadAll, this);
this.onCompleteAll(this);
}
/**
* @param {?} parsedHeaders
* @return {?}
*/
_headersGetter(parsedHeaders) {
return (name) => {
if (name) {
return parsedHeaders[name.toLowerCase()] || null;
}
return parsedHeaders;
};
}
/**
* @param {?} headers
* @return {?}
*/
_parseHeaders(headers) {
const /** @type {?} */ parsed = {};
let /** @type {?} */ key, /** @type {?} */ val, /** @type {?} */ i;
if (!headers) {
return parsed;
}
const /** @type {?} */ incomeHeaders = headers.split('\n');
for (const /** @type {?} */ line of incomeHeaders) {
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;
}
/**
* @param {?} response
* @param {?} headers
* @return {?}
*/
_transformResponse(response, headers) {
headers = {};
return response;
}
/**
* @param {?} type
* @param {...?} args
* @return {?}
*/
_runHook(type, ...args) {
for (const /** @type {?} */ key in this._hooks) {
if (this._hooks.hasOwnProperty(key)) {
const /** @type {?} */ obj = this._hooks[key];
if (obj.type === type) {
switch (type) {
case hookType.beforeAddingFile:
case hookType.prepareUploadAll:
case hookType.prepareUploadFile:
case hookType.afterAddingFile:
case hookType.errorAddingFile:
case hookType.completeUploadAll:
case hookType.progressUploadAll:
{
((obj.callback))(args[0]);
}
break;
case hookType.progressUploadFile:
{
((obj.callback))(args[0], args[1]);
}
break;
case hookType.cancelUploadFile:
case hookType.successUploadFile:
case hookType.failedUploadFile:
case hookType.completeUploadFile:
{
((obj.callback))(args[0], args[1], args[2], args[3]);
}
break;
default: {
throw new Error(`hookType unknown or not defined`);
}
}
}
}
}
}
/**
*
*
*
* \@memberOf Transfer
* @param {?} hook
* @return {?}
*/
hookExists(hook) {
for (const /** @type {?} */ key in this._hooks) {
if (this._hooks.hasOwnProperty(key)) {
const /** @type {?} */ obj = this._hooks[key];
if ((obj.type === hook.type) && ('' + obj.callback === '' + hook.callback)) {
return +key;
}
}
}
return -1;
}
/**
* @param {?} _filter
* @return {?}
*/
filterExists(_filter) {
const /** @type {?} */ filters = (this.options.filters);
for (const /** @type {?} */ key in filters) {
if (filters.hasOwnProperty(key)) {
const /** @type {?} */ obj = filters[key];
if (obj.name === _filter.name) {
return +key;
}
}
}
return -1;
}
}
// tslint:disable:no-unused-expression
const FileManagerOptionsDefault = {};
const speedObject = {
total: 0,
loaded: 0,
percent: 0,
speed: 0,
speedToText: '0 bytes'
};
class FileObject {
/**
* @param {?} fileOrInput
*/
constructor(fileOrInput) {
const isInput = Utils.isElement(fileOrInput);
const fakePathOrObject = isInput ? fileOrInput.value : fileOrInput;
const isFakePath = Utils.isString(fakePathOrObject) ? true : false;
const method = (v, x) => { if (v) {
this._createFromFakePath(x);
}
else {
this._createFromObject(x);
} };
method(isFakePath, fakePathOrObject);
}
/**
* @param {?} path
* @return {?}
*/
_createFromFakePath(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);
}
/**
* @param {?} object
* @return {?}
*/
_createFromObject(object) {
this.lastModifiedDate = new Date(object.lastModifiedDate.getTime());
this.size = object.size;
this.type = object.type;
this.name = object.name;
}
}
class FileManager {
/**
* Creates an instance of FileManager.
*
*
* \@memberOf FileManager
* @param {?} _file
* @param {?=} _options
* @param {?=} _uploader
*/
constructor(_file, _options, _uploader) {
this._progress$ = new BehaviorSubject(0);
this._speed$ = new BehaviorSubject(speedObject);
this.options = Object.assign({}, FileManagerOptionsDefault, _options);
this._speedDefault = {};
this._id = Utils.uniqueID();
this._isUploading = false;
this._isUploaded = false;
this._isSuccess = false;
this._isCancel = false;
this._isError = false;
const isInput = Utils.isElement(_file);
const file = isInput ? new FileObject(_file.files[0]) : new FileObject(_file);
this._file = file;
this._fileElement = isInput ? _file.files[0] : _file;
this._fileActive = false;
if (typeof _uploader !== 'undefined') {
this.bindUploader(_uploader);
}
}
/**
* @param {?} _protocol
* @return {?}
*/
set protocol(_protocol) {
this._protocol = _protocol;
}
/**
* @return {?}
*/
get id() {
return this._id;
}
/**
* @return {?}
*/
get progressPercent$() {
return Utils.asObservable(this._progress$);
}
/**
* @return {?}
*/
get progress$() {
return Utils.asObservable(this._speed$);
}
/**
* @return {?}
*/
get progress() {
return this._progress$.getValue();
}
/**
* @return {?}
*/
get element() {
return this._fileElement;
}
/**
* @return {?}
*/
get object() {
return this._file;
}
/**
* @return {?}
*/
get name() {
return this._file.name;
}
/**
* @return {?}
*/
get type() {
return this._file.type;
}
/**
* @return {?}
*/
get date() {
return this._file.lastModifiedDate;
}
/**
* @return {?}
*/
get size() {
return this._file.size;
}
/**
* @return {?}
*/
get inQueue() {
return this._fileActive;
}
/**
* @return {?}
*/
get success() {
return this._isSuccess;
}
/**
* @return {?}
*/
get error() {
return this._isError;
}
/**
* Bind uploader to FileManager
*
*
* \@memberOf FileManager
* @param {?} _uploader
* @return {?}
*/
bindUploader(_uploader) {
if (this._uploader instanceof Transfer) {
this._uploader.removeFile(this);
}
this._uploader = _uploader;
const /** @type {?} */ check = this._uploader.addFile(this);
this._setFileActive(check);
}
/**
* Bind options to FileManager
*
*
* \@memberOf FileManager
* @param {?} _options
* @return {?}
*/
bindOptions(_options) {
this.options = Object.assign({}, this.options, _options);
}
/**
* Return uploader if exists else throw error
*
*
* \@memberOf FileManager
* @return {?}
*/
getUploader() {
if (this._uploader instanceof Transfer) {
return this._uploader;
}
throw new Error('Not uploader for this file defined.');
}
/**
* Start uploading this file
*
*
* \@memberOf FileManager
* @return {?}
*/
upload() {
let /** @type {?} */ _uploader;
try {
_uploader = this.getUploader();
}
catch (e) {
throw new Error('Couldn`t upload because uploader was not defined. ERR_MSG: ' + ((e)).message);
}
this._isUploading = true;
try {
_uploader.uploadItem(this);
}
catch (e) {
// TODO write error handling
}
}
/**
* Cancel upload process from this file
*
*
* \@memberOf FileManager
* @return {?}
*/
cancel() {
if (this._isUploading) {
const /** @type {?} */ uploader = this.getUploader();
uploader.cancelUploadItem(this);
}
}
/**
* @return {?}
*/
_cancel() {
if (this._isUploading) {
this._isCancel = true;
this._isUploaded = false;
this._isUploading = false;
}
}
/**
* Remove this FileManger from uploader queue
*
*
* \@memberOf FileManager
* @return {?}
*/
remove() {
let /** @type {?} */ _uploader;
try {
_uploader = this.getUploader();
}
catch (e) {
throw new Error('Couldn`t remove because uploader was not defined. ERR_MSG: ' + ((e)).message);
}
(this._isUploading) && this.cancel();
_uploader.removeFile(this);
this._setFileActive(false);
}
/**
* @return {?}
*/
isUploaded() {
return this._isUploaded;
}
/**
* @return {?}
*/
isUploading() {
return this._isUploading;
}
/**
* @return {?}
*/
canUpload() {
return (!this._isUploaded && !this._isUploading && !this._isSuccess && !this._isError);
}
/**
* @return {?}
*/
handleImageLoad() {
this._imageLoad = true;
}
/**
* Callback
* @return {?}
*/
onBeforeUpload() { return; }
/**
* @param {?} speed
* @return {?}
*/
onProgressSpeed(speed) { speed = speed; }
/**
* Callback
* @param {?} progress
* @return {?}
*/
onProgress(progress) { progress = progress; }
/**
* Callback
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
onSuccess(response, status, headers) { response = response; status = status; headers = headers; }
/**
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
onError(response, status, headers) { response = response; status = status; headers = headers; }
/**
* Internal functions
* @return {?}
*/
_onBeforeUpload() {
this._isUploading = true;
this._isUploaded = false;
this._isSuccess = false;
this._isCancel = false;
this._isError = false;
this._progress$.next(0);
this.onBeforeUpload();
}
/**
* @param {?} speed
* @return {?}
*/
_onProgressFileSpeed(speed) {
this._speed$.next(speed);
this.onProgressSpeed(speed);
}
/**
* @param {?} _progress
* @return {?}
*/
_onProgress(_progress) {
this._progress$.next(_progress);
this.onProgress(_progress);
}
/**
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onSuccess(response, status, headers) {
if (this._uploader.options.removeBySuccess) {
this.remove();
}
this._isUploading = false;
this._isUploaded = true;
this._isSuccess = true;
this._isError = false;
this.onSuccess(response, status, headers);
}
/**
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onError(response, status, headers) {
this._isUploading = false;
this._isUploaded = false;
this._isSuccess = false;
this._isError = true;
this.onError(response, status, headers);
}
/**
* @param {?} check
* @return {?}
*/
_setFileActive(check) {
this._fileActive = check;
}
}
// tslint:disable:max-line-length
// tslint:disable:no-unused-expression
class FileDropDirective {
/**
* @param {?} element
* @param {?} renderer
*/
constructor(element, renderer) {
this.element = element;
this.renderer = renderer;
this.fileHoverStart = new EventEmitter();
this.fileHoverEnd = new EventEmitter();
this.fileAccepted = new EventEmitter();
this.fileRejected = new EventEmitter();
this._InputFile = null;
}
/**
* @return {?}
*/
ngOnInit() {
this._files = [];
this.renderer.setElementClass(this.element.nativeElement, 'drop-area', true);
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this._files.length > 0) {
for (const /** @type {?} */ _file of this._files) {
if (_file instanceof FileManager) {
if (!_file.isUploaded()) {
_file.cancel();
this.uploader.removeFile(_file);
}
}
}
}
}
/**
* @param {?} event
* @return {?}
*/
onDragOver(event) {
// If we're already in the on-drag, don't bother with this
if (this._InputFile === null) {
// Get the object being dragged and reference it as a copy action
this._InputFile = this.getDataTransferObject(event);
if (this._InputFile === null) {
return;
}
this.renderer.setElementClass(this.element.nativeElement, 'drop-enter', true);
const /** @type {?} */ _dropValueText = 'Drop now';
this.renderer.setElementAttribute(this.element.nativeElement, 'dropValueText', _dropValueText);
// Let the client know
this.fileHoverStart.emit();
}
// Don't propagate
this.preventAndStopEventPropagation(event);
}
/**
* @param {?} event
* @return {?}
*/
onDragLeave(event) {
// Only bother if we have a file
if (this._InputFile !== null) {
this.renderer.setElementClass(this.element.nativeElement, 'drop-enter', false);
this.renderer.setElementAttribute(this.element.nativeElement, 'dropValueText', '');
// Finished with the file
this._InputFile = null;
if (event.currentTarget === ((this)).element[0]) {
return;
}
// Let the client know
this.fileHoverEnd.emit();
}
// Don't let it continue
this.preventAndStopEventPropagation(event);
}
/**
* @param {?} event
* @return {?}
*/
onDrop(event) {
// Only bother if we have a file
if (this._InputFile !== null) {
this.renderer.setElementClass(this.element.nativeElement, 'drop-enter', false);
this.renderer.setElementAttribute(this.element.nativeElement, 'dropValueText', '');
// Let the client know
this.fileHoverEnd.emit();
// Update our data
this._InputFile = this.getDataTransferObject(event);
if (this._InputFile.files.length === 0) {
this._InputFile = null;
return;
}
const /** @type {?} */ filesData = this._InputFile.files;
if (!this.hasFiles(this._InputFile.types)) {
return;
}
this.readFile(filesData);
this.fileAccepted.emit(this._files);
// Finished with the file
this._InputFile = null;
}
// Don't let it continue
this.preventAndStopEventPropagation(event);
}
/**
* @param {?} event
* @return {?}
*/
preventAndStopEventPropagation(event) {
event.preventDefault();
event.stopPropagation();
}
/**
* @param {?} _files
* @return {?}
*/
readFile(_files) {
let /** @type {?} */ fmObject;
for (let /** @type {?} */ i = 0; i < _files.length; i++) {
const /** @type {?} */ file = _files[i];
try {
fmObject = new FileManager(file, this.fileOptions, this.uploader);
}
catch (e) {
if (e.status === 100) {
this.fileRejected.emit(e);
}
else {
this.fileRejected.emit(e);
}
throw new Error('Something goes wrong e: ' + e.message);
}
(fmObject.inQueue) && this._files.push(fmObject);
}
}
/**
* @param {?} event
* @return {?}
*/
getDataTransferObject(event) {
return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer;
}
/**
* @param {?} types
* @return {?}
*/
hasFiles(types) {
if (!types) {
return false;
}
if (types.indexOf) {
return types.indexOf('Files') !== -1;
}
if (types.contains) {
return types.contains('Files');
}
return false;
}
}
FileDropDirective.decorators = [
{ type: Directive, args: [{
// Selector required in component HTML
// tslint:disable-next-line:directive-selector
selector: '[ng2File2Drop]'
},] },
];
/**
* @nocollapse
*/
FileDropDirective.ctorParameters = () => [
{ type: ElementRef, },
{ type: Renderer, },
];
FileDropDirective.propDecorators = {
'fileHoverStart': [{ type: Output },],
'fileHoverEnd': [{ type: Output },],
'fileAccepted': [{ type: Output },],
'fileRejected': [{ type: Output },],
'fileOptions': [{ type: Input },],
'uploader': [{ type: Input },],
'onDragOver': [{ type: HostListener, args: ['dragover', ['$event'],] },],
'onDragLeave': [{ type: HostListener, args: ['dragleave', ['$event'],] },],
'onDrop': [{ type: HostListener, args: ['drop', ['$event'],] },],
};
// tslint:disable:max-line-length
// tslint:disable:no-unused-expression
class FileSelectDirective {
constructor() {
this.role = 'input';
this.type = 'file';
this.fileHoverStart = new EventEmitter();
this.fileHoverEnd = new EventEmitter();
this.fileAccepted = new EventEmitter();
this.fileRejected = new EventEmitter();
this._InputFile = null;
}
/**
* @return {?}
*/
ngOnInit() {
this._files = [];
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this._files.length > 0) {
for (const /** @type {?} */ _file of this._files) {
if (_file instanceof FileManager) {
if (!_file.isUploaded()) {
_file.cancel();
this.uploader.removeFile(_file);
}
}
}
}
}
/**
* @param {?} event
* @return {?}
*/
onChange(event) {
// Update our data
this._InputFile = this.getEventTarget(event);
if (this._InputFile.files.length === 0) {
this._InputFile = null;
return;
}
const /** @type {?} */ filesData = this._InputFile.files;
console.log('onChange', filesData);
this.readFile(filesData);
this.fileAccepted.emit(this._files);
// Finished with the file
this._InputFile = null;
// Don't let it continue
this.preventAndStopEventPropagation(event);
}
/**
* @param {?} event
* @return {?}
*/
preventAndStopEventPropagation(event) {
event.preventDefault();
event.stopPropagation();
}
/**
* @param {?} _files
* @return {?}
*/
readFile(_files) {
let /** @type {?} */ fmObject;
for (let /** @type {?} */ i = 0; i < _files.length; i++) {
const /** @type {?} */ file = _files[i];
try {
fmObject = new FileManager(file, this.fileOptions, this.uploader);
}
catch (e) {
if (e.status === 100) {
this.fileRejected.emit(e);
}
else {
this.fileRejected.emit(e);
}
throw new Error('Something goes wrong e: ' + e.message);
}
(fmObject.inQueue) && this._files.push(fmObject);
}
}
/**
* @param {?} event
* @return {?}
*/
getEventTarget(event) {
return event.target;
}
}
FileSelectDirective.decorators = [
{ type: Directive, args: [{
// Selector required in component HTML
// tslint:disable-next-line:directive-selector
selector: '[ng2File2Select]'
},] },
];
/**
* @nocollapse
*/
FileSelectDirective.ctorParameters = () => [];
FileSelectDirective.propDecorators = {
'role': [{ type: HostBinding, args: ['attr.role',] },],
'type': [{ type: HostBinding, args: ['attr.type',] },],
'fileHoverStart': [{ type: Output },],
'fileHoverEnd': [{ type: Output },],
'fileAccepted': [{ type: Output },],
'fileRejected': [{ type: Output },],
'fileOptions': [{ type: Input },],
'uploader': [{ type: Input },],
'onChange': [{ type: HostListener, args: ['change', ['$event'],] },],
};
const { FileReader: FileReader$1 } = ((window));
class ImagePreviewDirective {
/**
* @param {?} el
*/
constructor(el) {
this.el = el;
}
/**
* @return {?}
*/
ngOnChanges() {
const /** @type {?} */ reader = new FileReader$1();
const /** @type {?} */ el = this.el;
// tslint:disable-next-line:max-line-length
el.nativeElement.src = 'data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D\'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg\' viewBox%3D\'0 0 200 150\'%2F%3E';
reader.onloadend = function () {
el.nativeElement.src = reader.result;
};
if (this.image) {
return reader.readAsDataURL(this.image.element);
}
}
}
ImagePreviewDirective.decorators = [
{ type: Directive, args: [{ selector: 'img[imgPreview]' },] },
];
/**
* @nocollapse
*/
ImagePreviewDirective.ctorParameters = () => [
{ type: ElementRef, },
];
ImagePreviewDirective.propDecorators = {
'image': [{ type: Input },],
};
class FileSizePipe {
constructor() {
this.units = [
'bytes',
'KB',
'MB',
'GB',
'TB',
'PB'
];
}
/**
* @param {?=} bytes
* @param {?=} precision
* @return {?}
*/
transform(bytes = 0, precision = 2) {
if (!isFinite(bytes)) {
return '?';
}
let /** @type {?} */ unit = 0;
while (bytes >= 1024) {
bytes /= 1024;
unit++;
}
return bytes.toFixed(+precision) + ' ' + this.units[unit];
}
}
FileSizePipe.decorators = [
{ type: Pipe, args: [{ name: 'fileSize' },] },
];
/**
* @nocollapse
*/
FileSizePipe.ctorParameters = () => [];
class ProgressBarDirective {
/**
* @param {?} el
* @param {?} renderer
*/
constructor(el, renderer) {
this.el = el;
this.renderer = renderer;
}
/**
* @return {?}
*/
ngOnChanges() {
const /** @type {?} */ el = this.el;
el.nativeElement.value = this.progress.percent;
if (this.progress.speed > 0) {
const /** @type {?} */ pipe = new FileSizePipe();
this.renderer.setElementAttribute(this.el.nativeElement, 'speedText', pipe.transform(this.progress.loaded));
}
else {
this.renderer.setElementAttribute(this.el.nativeElement, 'speedText', '');
}
}
}
ProgressBarDirective.decorators = [
{ type: Directive, args: [{
selector: 'progress[progressBar]'
},] },
];
/**
* @nocollapse
*/
ProgressBarDirective.ctorParameters = () => [
{ type: ElementRef, },
{ type: Renderer, },
];
ProgressBarDirective.propDecorators = {
'progress': [{ type: Input },],
};
// tslint:disable:max-line-length
const { FormData: FormData$1 } = ((window));
/**
* Absractr proctol class if someone want to write his own protocol
*
* @export
* @abstract
* \@class Protocol
* @abstract
*/
class Protocol {
/**
* @param {?} obj
* @return {?}
*/
set connection(obj) {
const { _file, _connection } = obj;
if (!this.isConnected(_file)) {
this._connections.push({
id: _file.id,
connection: _connection
});
}
}
/**
* Creates an instance of Protocol and for each protocol an own unique ID.
*
*
* \@memberOf Protocol
*/
constructor() {
this._id = Utils.uniqueID();
this._progress = new EventEmitter();
this._load = new EventEmitter();
this._error = new EventEmitter();
this._abort = new EventEmitter();
this._connections = [];
}
/**
* Call uploader method _onCompleteFile.
*
*
* \@memberOf Protocol
* @param {?} _file
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onLoad(_file, response, status, headers) {
const /** @type {?} */ uploader = _file.getUploader();
const /** @type {?} */ gist = this._isSuccessCode(status);
const /** @type {?} */ method = (g, f, r, s, h) => { if (g) {
uploader._onSuccessFile(f, r, s, h);
}
else {
uploader._onErrorFile(f, r, s, h);
} };
method(gist, _file, response, status, headers);
uploader._onCompleteFile(_file, response, status, headers);
}
/**
* Call uploader methodes _onErrorFile and _onCompleteFile.
*
*
* \@memberOf Protocol
* @param {?} _file
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onError(_file, response, status, headers) {
const /** @type {?} */ uploader = _file.getUploader();
uploader._onErrorFile(_file, response, status, headers);
uploader._onCompleteFile(_file, response, status, headers);
}
/**
* Call uploader methodes _onErrorFile and _onCompleteFile.
*
*
* \@memberOf Protocol
* @param {?} _file
* @param {?} response
* @param {?} status
* @param {?} headers
* @return {?}
*/
_onAbort(_file, response, status, headers) {
const /** @type {?} */ uploader = _file.getUploader();
uploader._onErrorFile(_file, response, status, headers);
uploader._onCompleteFile(_file, response, status, headers);
}
/**
* Validate response status code.
*
*
* \@memberOf Protocol
* @param {?} status
* @return {?}
*/
_isSuccessCode(status) {
return (status >= 200 && status < 300) || status === 304;
}
/**
* @param {?} _file
* @return {?}
*/
isConnected(_file) {
for (const /** @type {?} */ _request of this._connections) {
if (_request.id === _file.id) {
return _request;
}
}
return false;
}
/**
* @param {?} _file
* @return {?}
*/
removeConnection(_file) {
let /** @type {?} */ _request = null;
for (const /** @type {?} */ _key in this._connections) {
if (this._connections.hasOwnProperty(_key)) {
_request = this._connections[_key];
if (_file.id === _request.id) {
this._connections.splice(+_key, 1);
}
}
}
}
/**
* Must be implemented at each protocol class.
*
* @abstract
*
* \@memberOf Protocol
* @abstract
* @param {?} _file
* @return {?}
*/
run(_file) { }
/**
* @abstract
* @param {?} _file
* @return {?}
*/
cancel(_file) { }
}
/**
* Standard protocol for server communication (file uploading)
*
* @export
* \@class ProtocolXHR
*/
class ProtocolXHR extends Protocol {
constructor() {
super();
}
/**
* Implementation of the abstract.protocol method `run`
*
*
* \@memberOf ProtocolXHR
* @param {?} _file
* @return {?}
*/
run(_file) {
let /** @type {?} */ _xhr;
let /** @type {?} */ sendable;
const /** @type {?} */ uploader = _file.getUploader();
const /** @type {?} */ _formData = Utils.extendValue(uploader.options.formData, _file.options.formData);
const /** @type {?} */ _withCredentials = Utils.extendValue(uploader.options.withCredentials, _file.options.withCredentials);
const /** @type {?} */ _method = Utils.extendValue(uploader.options.method, _file.options.method);
const /** @type {?} */ _url = Utils.extendValue(uploader.options.url, _file.options.url);
const /** @type {?} */ _alias = Utils.extendValue(uploader.options.alias, _file.options.alias);
const /** @type {?} */ _headers = Utils.extendValue(uploader.options.headers, _file.options.headers);
const /** @type {?} */ time = new Date().getTime();
let /** @type {?} */ load = 0;
let /** @type {?} */ speed = 0;
let /** @type {?} */ sppedToText = null;
const /** @type {?} */ $filesize = new FileSizePipe();
_xhr = new XMLHttpRequest();
this.connection = {
_file: _file,
_connection: _xhr
};
sendable = new FormData$1();
if (typeof _formData !== 'undefined') {
// Only allow Multipart
for (const /** @type {?} */ obj of _formData) {
for (const /** @type {?} */ key in obj) {
if (obj.hasOwnProperty(key)) {
const /** @type {?} */ value = obj[key];
sendable.append(key, value);
}
}
}
}
sendable.append(_alias, _file.element, _file.name);
if (typeof (_file.size) !== 'number') {
throw new TypeError('We need the file size.');
}
_xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const /** @type {?} */ _time = new Date().getTime() - time;
load = event.loaded - load;
speed = load / _time * 10