Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pure-upload

Package Overview
Dependencies
Maintainers
1
Versions
75
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pure-upload - npm Package Compare versions

Comparing version 4.2.1 to 5.0.0

94

CHANGELOG.md

@@ -1,40 +0,43 @@

CHANGELOG
===
4.2.1
--
# CHANGELOG
## 5.0.0
Updated environment.
Updated TS to 2.7.2.
Higher restrictions.
Prettier.
## 4.2.1
Improved internal type definitions and casting
4.2.0
--
## 4.2.0
Added highlighting on dnd.
4.1.0
--
## 4.1.0
Added option to allow upload of empty files
4.0.1
--
Fix
-
## 4.0.1
## Fix
Options access modifier reverted to public.
4.0.0
--
Changed localizations
-
## 4.0.0
## Changed localizations
Localizations are now accessible through new options property with specific errors.
3.0.0
--
Cleaning
-
## 3.0.0
## Cleaning
Removed compatibility parts for obsolette browser without FileAPI.
## 2.2.3
2.2.3
--
Fix
-
## Fix

@@ -44,53 +47,40 @@ Removed duplications when same file is adding many times to queue.

2.2.2
--
Fix
-
## 2.2.2
## Fix
Automatic clearing of manual upload file list after puting to queue is done on parameter.
2.2.0
--
New features
-
## 2.2.0
## New features
Added manual triggering of adding file to UploadQueue in UploadArea.
## 2.1.0
2.1.0
--
New features
-
## New features
Added offset for batches limited by max uploading file count.
## 2.0.5 - 2.0.8
2.0.5 - 2.0.8
--
Fixes
## 2.0.4
2.0.4
--
## Fixes
Fixes
-
Modified update progress condition to not throw in IE.
2.0.3
--
## 2.0.3
Fixes
-
## Fixes
Url is now loaded on file adding instead of request creating.
2.0.2
--
## 2.0.2
New features
-
## New features
Added onFileCanceled for UploadArea

@@ -10,3 +10,3 @@ "use strict";

if (elem.attachEvent) {
elem.attachEvent('on' + event, handler);
elem.attachEvent("on" + event, handler);
}

@@ -22,5 +22,5 @@ else {

var files;
if (typeof fileList === 'object') {
if (typeof fileList === "object") {
files = Object.keys(fileList)
.filter(function (key) { return key !== 'length'; })
.filter(function (key) { return key !== "length"; })
.map(function (key) { return fileList[key]; });

@@ -34,6 +34,10 @@ }

file.responseCode = file.responseCode || 0;
file.responseText = file.responseText || '';
file.responseText = file.responseText || "";
file.progress = file.progress || 0;
file.sentBytes = file.sentBytes || 0;
file.cancel = file.cancel || (function () { return; });
file.cancel =
file.cancel ||
(function () {
return;
});
});

@@ -48,4 +52,10 @@ return files;

return newFirst
? function () { newFn(); origFn(); }
: function () { origFn(); newFn(); };
? function () {
newFn();
origFn();
}
: function () {
origFn();
newFn();
};
}

@@ -56,3 +66,4 @@ exports.decorateSimpleFunction = decorateSimpleFunction;

for (var nextKey in source) {
if (Object.prototype.hasOwnProperty.call(source, nextKey) && (to[nextKey] === undefined || to[nextKey] === null)) {
if (Object.prototype.hasOwnProperty.call(source, nextKey) &&
(to[nextKey] === undefined || to[nextKey] === null)) {
to[nextKey] = source[nextKey];

@@ -63,3 +74,2 @@ }

}
;
function getUploadCore(options, callbacks) {

@@ -69,3 +79,2 @@ return new UploadCore(options, callbacks);

exports.getUploadCore = getUploadCore;
;
function getUploader(options, callbacks) {

@@ -75,5 +84,4 @@ return new Uploader(options, callbacks);

exports.getUploader = getUploader;
;
function getValueOrResult(valueOrGetter) {
if (typeof valueOrGetter === 'function')
if (typeof valueOrGetter === "function")
return valueOrGetter();

@@ -85,7 +93,7 @@ return valueOrGetter;

var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
/* tslint:disable */
var r = (d + Math.random() * 16) % 16 | 0;
var r = ((d + Math.random() * 16) % 16) | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
/* tslint:enable */

@@ -96,9 +104,15 @@ });

exports.newGuid = newGuid;
;
function getDefaultLocalizer() {
return {
fileSizeInvalid: function (maxFileSize) { return 'The selected file exceeds the allowed size of ' + maxFileSize
+ ' or its size is 0 MB. Please choose another file.'; },
fileTypeInvalid: function (accept) { return 'File format is not allowed. Only ' + (accept ? accept : '') + ' files are allowed.'; },
invalidResponseFromServer: function () { return 'Invalid response from server'; }
fileSizeInvalid: function (maxFileSize) {
return "The selected file exceeds the allowed size of " +
maxFileSize +
" or its size is 0 MB. Please choose another file.";
},
fileTypeInvalid: function (accept) {
return "File format is not allowed. Only " +
(accept ? accept : "") +
" files are allowed.";
},
invalidResponseFromServer: function () { return "Invalid response from server"; }
};

@@ -113,3 +127,3 @@ }

if (elem.detachEvent) {
elem.detachEvent('on' + event, handler);
elem.detachEvent("on" + event, handler);
}

@@ -122,3 +136,3 @@ else {

exports.removeEventHandler = removeEventHandler;
var UploadArea = (function () {
var UploadArea = /** @class */ (function () {
function UploadArea(targetElement, options, uploader) {

@@ -133,3 +147,3 @@ this.targetElement = targetElement;

else {
throw 'Only browsers with FileAPI supported.';
throw "Only browsers with FileAPI supported.";
}

@@ -163,3 +177,4 @@ }

this.unregisterOnDragLeaveGlobal();
document.body.removeChild(this.fileInput);
if (this.fileInput)
document.body.removeChild(this.fileInput);
};

@@ -172,3 +187,3 @@ UploadArea.prototype.defaultOptions = function () {

clickable: true,
accept: '*.*',
accept: "*.*",
validateExtension: false,

@@ -198,4 +213,4 @@ multiple: true,

file.url = _this.uploadCore.getUrl(file);
file.onError = _this.options.onFileError || (function () { ; });
file.onCancel = _this.options.onFileCanceled || (function () { ; });
file.onError = _this.options.onFileError || (function () { });
file.onCancel = _this.options.onFileCanceled || (function () { });
if (_this.validateFile(file)) {

@@ -207,3 +222,5 @@ file.start = function () {

}
file.start = function () { return; };
file.start = function () {
return;
};
};

@@ -232,11 +249,14 @@ }

var _this = this;
this.fileInput = document.createElement('input');
this.fileInput.setAttribute('type', 'file');
this.fileInput.setAttribute('accept', this.options.accept ? this.options.accept : '');
this.fileInput.style.display = 'none';
this.fileInput = document.createElement("input");
this.fileInput.setAttribute("type", "file");
this.fileInput.setAttribute("accept", this.options.accept ? this.options.accept : "");
this.fileInput.style.display = "none";
var onChange = function (e) { return _this.onChange(e); };
addEventHandler(this.fileInput, 'change', onChange);
this.unregisterOnChange = function () { return removeEventHandler(_this.fileInput, 'change', onchange); };
addEventHandler(this.fileInput, "change", onChange);
this.unregisterOnChange = function () {
if (_this.fileInput)
removeEventHandler(_this.fileInput, "change", onchange);
};
if (this.options.multiple) {
this.fileInput.setAttribute('multiple', '');
this.fileInput.setAttribute("multiple", "");
}

@@ -250,19 +270,35 @@ this.registerEvents();

var onClick = function () { return _this.onClick(); };
addEventHandler(this.targetElement, 'click', onClick);
this.unregisterOnClick = function () { return removeEventHandler(_this.targetElement, 'click', onClick); };
var onDrag = function (e) { return _this.onDrag(e); };
addEventHandler(this.targetElement, 'dragover', onDrag);
this.unregisterOnDragOver = function () { return removeEventHandler(_this.targetElement, 'dragover', onDrag); };
addEventHandler(this.targetElement, "click", onClick);
this.unregisterOnClick = function () {
return removeEventHandler(_this.targetElement, "click", onClick);
};
var onDrag = (function (e) {
return _this.onDrag(e);
});
addEventHandler(this.targetElement, "dragover", onDrag);
this.unregisterOnDragOver = function () {
return removeEventHandler(_this.targetElement, "dragover", onDrag);
};
var onDragLeave = function () { return _this.onDragLeave(); };
addEventHandler(this.targetElement, 'dragleave', onDragLeave);
this.unregisterOnDragOver = function () { return removeEventHandler(_this.targetElement, 'dragleave', onDragLeave); };
addEventHandler(this.targetElement, "dragleave", onDragLeave);
this.unregisterOnDragOver = function () {
return removeEventHandler(_this.targetElement, "dragleave", onDragLeave);
};
var onDragGlobal = function () { return _this.onDragGlobal(); };
addEventHandler(document.body, 'dragover', onDragGlobal);
this.unregisterOnDragOverGlobal = function () { return removeEventHandler(document.body, 'dragover', onDragGlobal); };
addEventHandler(document.body, "dragover", onDragGlobal);
this.unregisterOnDragOverGlobal = function () {
return removeEventHandler(document.body, "dragover", onDragGlobal);
};
var onDragLeaveGlobal = function () { return _this.onDragLeaveGlobal(); };
addEventHandler(document.body, 'dragleave', onDragLeaveGlobal);
this.unregisterOnDragOverGlobal = function () { return removeEventHandler(document.body, 'dragleave', onDragLeaveGlobal); };
var onDrop = function (e) { return _this.onDrop(e); };
addEventHandler(this.targetElement, 'drop', onDrop);
this.unregisterOnDrop = function () { return removeEventHandler(_this.targetElement, 'drop', onDrop); };
addEventHandler(document.body, "dragleave", onDragLeaveGlobal);
this.unregisterOnDragOverGlobal = function () {
return removeEventHandler(document.body, "dragleave", onDragLeaveGlobal);
};
var onDrop = (function (e) {
return _this.onDrop(e);
});
addEventHandler(this.targetElement, "drop", onDrop);
this.unregisterOnDrop = function () {
return removeEventHandler(_this.targetElement, "drop", onDrop);
};
};

@@ -280,6 +316,5 @@ UploadArea.prototype.onChange = function (e) {

}
catch (err) {
;
}
e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
catch (err) { }
e.dataTransfer.dropEffect =
"move" === efct || "linkMove" === efct ? "move" : "copy";
this.stopEventPropagation(e);

@@ -325,3 +360,5 @@ };

var items = e.dataTransfer.items;
if (items && items.length && (items[0].webkitGetAsEntry !== null)) {
if (items &&
items.length &&
items[0].webkitGetAsEntry !== null) {
if (!this.options.multiple) {

@@ -341,11 +378,14 @@ var newItems = [items[0]];

UploadArea.prototype.isIeVersion = function (v) {
return RegExp('msie' + (!isNaN(v) ? ('\\s' + v.toString()) : ''), 'i').test(navigator.userAgent);
return RegExp("msie" + (!isNaN(v) ? "\\s" + v.toString() : ""), "i").test(navigator.userAgent);
};
UploadArea.prototype.onClick = function () {
var _this = this;
if (!getValueOrResult(this.options.clickable))
if (!getValueOrResult(this.options.clickable) || !this.fileInput)
return;
this.fileInput.value = '';
this.fileInput.value = "";
if (this.isIeVersion(10)) {
setTimeout(function () { _this.fileInput.click(); }, 200);
setTimeout(function () {
if (_this.fileInput)
_this.fileInput.click();
}, 200);
}

@@ -360,3 +400,4 @@ else {

var item = items[i];
if ((item.webkitGetAsEntry) && (entry = item.webkitGetAsEntry())) {
if (item.webkitGetAsEntry &&
(entry = item.webkitGetAsEntry())) {
if (entry.isFile) {

@@ -370,3 +411,3 @@ this.selectFiles([item.getAsFile()]);

else if (item.getAsFile) {
if (!item.kind || item.kind === 'file') {
if (!item.kind || item.kind === "file") {
this.selectFiles([item.getAsFile()]);

@@ -385,6 +426,6 @@ }

entry.file(function (file) {
if (file.name.substring(0, 1) === '.') {
if (file.name.substring(0, 1) === ".") {
return;
}
file.fullPath = '' + path + '/' + file.name;
file.fullPath = "" + path + "/" + file.name;
self.selectFiles([file]);

@@ -394,3 +435,3 @@ });

else if (entry.isDirectory) {
self.processDirectory(entry, '' + path + '/' + entry.name);
self.processDirectory(entry, "" + path + "/" + entry.name);
}

@@ -400,4 +441,4 @@ }

dirReader.readEntries(entryReader, function (error) {
return typeof console !== 'undefined' && console !== null
? typeof console.log === 'function' ? console.log(error) : void 0
return typeof console !== "undefined" && console !== null
? typeof console.log === "function" ? console.log(error) : void 0
: void 0;

@@ -413,3 +454,4 @@ });

var maxFileSize = this.options.maxFileSize * 1024 * 1024; // max file size in bytes
if (file.size > maxFileSize || (!this.options.allowEmptyFile && file.size === 0))
if (file.size > maxFileSize ||
(!this.options.allowEmptyFile && file.size === 0))
return false;

@@ -419,11 +461,16 @@ return true;

UploadArea.prototype.isFileTypeInvalid = function (file) {
if (file.name && this.options.accept && (this.options.accept.trim() !== '*' || this.options.accept.trim() !== '*.*') &&
this.options.validateExtension && this.options.accept.indexOf('/') === -1) {
var acceptedExtensions = this.options.accept.split(',');
var fileExtension = file.name.substring(file.name.lastIndexOf('.'), file.name.length);
if (fileExtension.indexOf('.') === -1)
if (file.name &&
this.options.accept &&
(this.options.accept.trim() !== "*" ||
this.options.accept.trim() !== "*.*") &&
this.options.validateExtension &&
this.options.accept.indexOf("/") === -1) {
var acceptedExtensions = this.options.accept.split(",");
var fileExtension = file.name.substring(file.name.lastIndexOf("."), file.name.length);
if (fileExtension.indexOf(".") === -1)
return true;
var isFileExtensionExisted = true;
for (var i = 0; i < acceptedExtensions.length; i++) {
if (acceptedExtensions[i].toUpperCase().trim() === fileExtension.toUpperCase()) {
if (acceptedExtensions[i].toUpperCase().trim() ===
fileExtension.toUpperCase()) {
isFileExtensionExisted = false;

@@ -448,3 +495,3 @@ }

exports.UploadArea = UploadArea;
var UploadCore = (function () {
var UploadCore = /** @class */ (function () {
function UploadCore(options, callbacks) {

@@ -464,3 +511,3 @@ if (callbacks === void 0) { callbacks = {}; }

UploadCore.prototype.getUrl = function (file) {
return typeof this.options.url === 'function'
return typeof this.options.url === "function"
? this.options.url(file)

@@ -486,8 +533,8 @@ : this.options.url;

return;
if (!this.options.headers['Accept'])
xhr.setRequestHeader('Accept', 'application/json');
if (!this.options.headers['Cache-Control'])
xhr.setRequestHeader('Cache-Control', 'no-cache');
if (!this.options.headers['X-Requested-With'])
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
if (!this.options.headers["Accept"])
xhr.setRequestHeader("Accept", "application/json");
if (!this.options.headers["Cache-Control"])
xhr.setRequestHeader("Cache-Control", "no-cache");
if (!this.options.headers["X-Requested-With"])
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
Object.keys(this.options.headers).forEach(function (headerName) {

@@ -498,3 +545,3 @@ if (!_this.options.headers)

if (headerValue !== undefined && headerValue !== null)
xhr.setRequestHeader(headerName, (headerValue || '').toString());
xhr.setRequestHeader(headerName, (headerValue || "").toString());
});

@@ -540,13 +587,15 @@ };

}
formData.append('file', file, file.name);
formData.append("file", file, file.name);
return formData;
};
UploadCore.prototype.castParamType = function (param) {
return this.isBoolean(param) || this.isNumber(param) ? param.toString() : param;
return this.isBoolean(param) || this.isNumber(param)
? param.toString()
: param;
};
UploadCore.prototype.isNumber = function (param) {
return typeof param === 'number';
return typeof param === "number";
};
UploadCore.prototype.isBoolean = function (param) {
return typeof param === 'number';
return typeof param === "number";
};

@@ -606,8 +655,10 @@ UploadCore.prototype.handleError = function (file, xhr) {

};
;
UploadCore.prototype.setResponse = function (file, xhr) {
file.responseCode = xhr.status;
file.responseText = xhr.responseText || xhr.statusText || (xhr.status
? xhr.status.toString()
: '' || this.options.localizer.invalidResponseFromServer());
file.responseText =
xhr.responseText ||
xhr.statusText ||
(xhr.status
? xhr.status.toString()
: "" || this.options.localizer.invalidResponseFromServer());
};

@@ -623,9 +674,37 @@ UploadCore.prototype.getDefaultOptions = function () {

UploadCore.prototype.setFullCallbacks = function (callbacks) {
this.callbacks.onProgressCallback = callbacks.onProgressCallback || (function () { return; });
this.callbacks.onCancelledCallback = callbacks.onCancelledCallback || (function () { return; });
this.callbacks.onFinishedCallback = callbacks.onFinishedCallback || (function () { return; });
this.callbacks.onUploadedCallback = callbacks.onUploadedCallback || (function () { return; });
this.callbacks.onErrorCallback = callbacks.onErrorCallback || (function () { return; });
this.callbacks.onUploadStartedCallback = callbacks.onUploadStartedCallback || (function () { return; });
this.callbacks.onFileStateChangedCallback = callbacks.onFileStateChangedCallback || (function () { return; });
this.callbacks.onProgressCallback =
callbacks.onProgressCallback ||
(function () {
return;
});
this.callbacks.onCancelledCallback =
callbacks.onCancelledCallback ||
(function () {
return;
});
this.callbacks.onFinishedCallback =
callbacks.onFinishedCallback ||
(function () {
return;
});
this.callbacks.onUploadedCallback =
callbacks.onUploadedCallback ||
(function () {
return;
});
this.callbacks.onErrorCallback =
callbacks.onErrorCallback ||
(function () {
return;
});
this.callbacks.onUploadStartedCallback =
callbacks.onUploadStartedCallback ||
(function () {
return;
});
this.callbacks.onFileStateChangedCallback =
callbacks.onFileStateChangedCallback ||
(function () {
return;
});
};

@@ -635,29 +714,3 @@ return UploadCore;

exports.UploadCore = UploadCore;
var Uploader = (function () {
function Uploader(options, callbacks) {
if (options === void 0) { options = {}; }
if (callbacks === void 0) { callbacks = {}; }
this.setOptions(options);
this.uploadAreas = [];
this.queue = new UploadQueue(options, callbacks);
}
Uploader.prototype.setOptions = function (options) {
this.options = options;
};
Uploader.prototype.registerArea = function (element, options) {
var uploadArea = new UploadArea(element, options, this);
this.uploadAreas.push(uploadArea);
return uploadArea;
};
Uploader.prototype.unregisterArea = function (area) {
var areaIndex = this.uploadAreas.indexOf(area);
if (areaIndex >= 0) {
this.uploadAreas[areaIndex].destroy();
this.uploadAreas.splice(areaIndex, 1);
}
};
return Uploader;
}());
exports.Uploader = Uploader;
var UploadQueue = (function () {
var UploadQueue = /** @class */ (function () {
function UploadQueue(options, callbacks) {

@@ -674,3 +727,6 @@ this.offset = { fileCount: 0, running: false };

files.forEach(function (file) {
if (!_this.queuedFiles.some(function (queuedFile) { return queuedFile === file || (!!queuedFile.guid && queuedFile.guid === file.guid); })) {
if (!_this.queuedFiles.some(function (queuedFile) {
return queuedFile === file ||
(!!queuedFile.guid && queuedFile.guid === file.guid);
})) {
_this.queuedFiles.push(file);

@@ -711,3 +767,6 @@ file.remove = decorateSimpleFunction(file.remove, function () {

if (!cancelProcessing)
excludeStatuses = excludeStatuses.concat([UploadStatus.queued, UploadStatus.uploading]);
excludeStatuses = excludeStatuses.concat([
UploadStatus.queued,
UploadStatus.uploading
]);
this.queuedFiles

@@ -729,4 +788,5 @@ .filter(function (file) { return excludeStatuses.indexOf(file.uploadStatus) < 0; })

UploadQueue.prototype.checkAllFinished = function () {
var unfinishedFiles = this.queuedFiles
.filter(function (file) { return [UploadStatus.queued, UploadStatus.uploading].indexOf(file.uploadStatus) >= 0; });
var unfinishedFiles = this.queuedFiles.filter(function (file) {
return [UploadStatus.queued, UploadStatus.uploading].indexOf(file.uploadStatus) >= 0;
});
if (unfinishedFiles.length === 0 && this.callbacks.onAllFinishedCallback) {

@@ -744,6 +804,22 @@ this.callbacks.onAllFinishedCallback();

var _this = this;
this.callbacks.onFileAddedCallback = this.callbacks.onFileAddedCallback || (function () { return; });
this.callbacks.onFileRemovedCallback = this.callbacks.onFileRemovedCallback || (function () { return; });
this.callbacks.onAllFinishedCallback = this.callbacks.onAllFinishedCallback || (function () { return; });
this.callbacks.onQueueChangedCallback = this.callbacks.onQueueChangedCallback || (function () { return; });
this.callbacks.onFileAddedCallback =
this.callbacks.onFileAddedCallback ||
(function () {
return;
});
this.callbacks.onFileRemovedCallback =
this.callbacks.onFileRemovedCallback ||
(function () {
return;
});
this.callbacks.onAllFinishedCallback =
this.callbacks.onAllFinishedCallback ||
(function () {
return;
});
this.callbacks.onQueueChangedCallback =
this.callbacks.onQueueChangedCallback ||
(function () {
return;
});
this.callbacks.onFileStateChangedCallback = function () { return _this.filesChanged(); };

@@ -757,3 +833,5 @@ };

this.queuedFiles
.filter(function (file) { return [UploadStatus.uploaded, UploadStatus.canceled].indexOf(file.uploadStatus) >= 0; })
.filter(function (file) {
return [UploadStatus.uploaded, UploadStatus.canceled].indexOf(file.uploadStatus) >= 0;
})
.forEach(function (file) { return _this.removeFile(file, true); });

@@ -765,5 +843,11 @@ };

file.uploadStatus = UploadStatus.removed;
file.cancel = function () { return; };
file.remove = function () { return; };
file.start = function () { return; };
file.cancel = function () {
return;
};
file.remove = function () {
return;
};
file.start = function () {
return;
};
};

@@ -784,3 +868,4 @@ UploadQueue.prototype.getWaitingFiles = function () {

}
count = Math.min(this.offset.fileCount + count, this.options.maxParallelUploads) - this.offset.fileCount;
count =
Math.min(this.offset.fileCount + count, this.options.maxParallelUploads) - this.offset.fileCount;
this.offset.fileCount += count;

@@ -814,1 +899,24 @@ }

})(UploadStatus = exports.UploadStatus || (exports.UploadStatus = {}));
var Uploader = /** @class */ (function () {
function Uploader(options, callbacks) {
if (options === void 0) { options = {}; }
if (callbacks === void 0) { callbacks = {}; }
this.options = options;
this.uploadAreas = [];
this.queue = new UploadQueue(options, callbacks);
}
Uploader.prototype.registerArea = function (element, options) {
var uploadArea = new UploadArea(element, options, this);
this.uploadAreas.push(uploadArea);
return uploadArea;
};
Uploader.prototype.unregisterArea = function (area) {
var areaIndex = this.uploadAreas.indexOf(area);
if (areaIndex >= 0) {
this.uploadAreas[areaIndex].destroy();
this.uploadAreas.splice(areaIndex, 1);
}
};
return Uploader;
}());
exports.Uploader = Uploader;

@@ -1,999 +0,1165 @@

export function addEventHandler(el: Element | HTMLElement, event: string, handler: (ev: UIEvent) => void) {
if (el.addEventListener) {
el.addEventListener(event, handler);
export interface IFileExt extends File {
kind: string;
webkitGetAsEntry: () => File;
getAsFile: () => File;
file: (callback: (file: IFileExt) => void) => void;
createReader: Function;
isFile: boolean;
isDirectory: boolean;
fullPath: string;
}
export function addEventHandler(
el: Element | HTMLElement,
event: string,
handler: EventListenerOrEventListenerObject
) {
if (el.addEventListener) {
el.addEventListener(event, handler);
} else {
let elem = <IElementWithEvents>el;
if (elem.attachEvent) {
elem.attachEvent("on" + event, handler as EventListener);
} else {
let elem = <IElementWithEvents>el;
if (elem.attachEvent) {
elem.attachEvent('on' + event, handler);
} else {
elem[event] = handler;
}
elem[event] = handler;
}
}
}
interface IElementWithEvents extends HTMLElement {
[key: string]: Function | Object | string | void | null | number | boolean;
attachEvent: (event: string, handler: (ev: UIEvent) => void) => void;
[key: string]: Function | Object | string | void | null | number | boolean;
attachEvent: (event: string, handler: (ev: UIEvent) => void) => void;
}
export const isFileApi: boolean = !!((<{ File?: Object }>window).File && (<{ FormData?: Object }>window).FormData);
export function castFiles(fileList: File[] | Object, status?: UploadStatus): IUploadFile[] {
let files: IUploadFile[];
export const isFileApi: boolean = !!(
(<{ File?: Object }>window).File && (<{ FormData?: Object }>window).FormData
);
if (typeof fileList === 'object') {
files = Object.keys(fileList)
.filter(key => key !== 'length')
.map(key => (<IFileOrObjectWithIndexer>fileList)[key]);
} else {
files = <IUploadFile[]>fileList;
}
export function castFiles(
fileList: File[] | Object,
status?: UploadStatus
): IUploadFile[] {
let files: IUploadFile[];
files.forEach((file: IUploadFile) => {
file.uploadStatus = status || file.uploadStatus;
file.responseCode = file.responseCode || 0;
file.responseText = file.responseText || '';
file.progress = file.progress || 0;
file.sentBytes = file.sentBytes || 0;
file.cancel = file.cancel || (() => { return; });
});
if (typeof fileList === "object") {
files = Object.keys(fileList)
.filter(key => key !== "length")
.map(key => (<IFileOrObjectWithIndexer>fileList)[key]);
} else {
files = <IUploadFile[]>fileList;
}
return files;
files.forEach((file: IUploadFile) => {
file.uploadStatus = status || file.uploadStatus;
file.responseCode = file.responseCode || 0;
file.responseText = file.responseText || "";
file.progress = file.progress || 0;
file.sentBytes = file.sentBytes || 0;
file.cancel =
file.cancel ||
(() => {
return;
});
});
return files;
}
interface IFileOrObjectWithIndexer {
[key: string]: IUploadFile;
[key: string]: IUploadFile;
}
export function decorateSimpleFunction(origFn: () => void, newFn: () => void, newFirst: boolean = false): () => void {
if (!origFn)
return newFn;
return newFirst
? () => { newFn(); origFn(); }
: () => { origFn(); newFn(); };
export function decorateSimpleFunction(
origFn: () => void,
newFn: () => void,
newFirst: boolean = false
): () => void {
if (!origFn) return newFn;
return newFirst
? () => {
newFn();
origFn();
}
: () => {
origFn();
newFn();
};
}
function applyDefaults<T, S>(target: T, source: S): T & S {
let to = Object(target);
let to = Object(target);
for (let nextKey in source) {
if (Object.prototype.hasOwnProperty.call(source, nextKey) && (to[nextKey] === undefined || to[nextKey] === null)) {
to[nextKey] = source[nextKey];
}
for (let nextKey in source) {
if (
Object.prototype.hasOwnProperty.call(source, nextKey) &&
(to[nextKey] === undefined || to[nextKey] === null)
) {
to[nextKey] = source[nextKey];
}
return to;
};
export function getUploadCore(options: IUploadOptions, callbacks: IUploadCallbacks): UploadCore {
return new UploadCore(options, callbacks);
};
}
return to;
}
export function getUploader(options: IUploadQueueOptions, callbacks: IUploadQueueCallbacks): Uploader {
return new Uploader(options, callbacks);
};
export function getUploadCore(
options: IUploadOptions,
callbacks: IUploadCallbacks
): UploadCore {
return new UploadCore(options, callbacks);
}
export function getUploader(
options: IUploadQueueOptions,
callbacks: IUploadQueueCallbacks
): Uploader {
return new Uploader(options, callbacks);
}
export function getValueOrResult<T>(valueOrGetter?: T | (() => T)): T | undefined {
if (typeof valueOrGetter === 'function')
return valueOrGetter();
if (typeof valueOrGetter === "function") return valueOrGetter();
return valueOrGetter;
return valueOrGetter;
}
export function newGuid(): string {
let d = new Date().getTime();
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
/* tslint:disable */
let r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
/* tslint:enable */
});
return uuid;
};
export interface IFileExt extends File {
kind: string;
webkitGetAsEntry: () => File;
getAsFile: () => File;
file: (callback: (file: IFileExt) => void) => void;
createReader: Function;
isFile: boolean;
isDirectory: boolean;
fullPath: string;
let d = new Date().getTime();
let uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(
c
) {
/* tslint:disable */
let r = ((d + Math.random() * 16) % 16) | 0;
d = Math.floor(d / 16);
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
/* tslint:enable */
});
return uuid;
}
export interface IFullUploadAreaOptions extends IUploadAreaOptions {
maxFileSize: number;
allowDragDrop: boolean | (() => boolean);
clickable: boolean | (() => boolean);
accept: string;
multiple: boolean;
validateExtension: boolean;
maxFileSize: number;
allowDragDrop: boolean | (() => boolean);
clickable: boolean | (() => boolean);
accept: string;
multiple: boolean;
validateExtension: boolean;
localizer: ILocalizer;
localizer: ILocalizer;
}
export interface IFullUploadOptions extends IUploadOptions {
withCredentials: boolean;
headers: { [key: string]: string | number | boolean };
params: { [key: string]: string | number | boolean | Blob };
localizer: ILocalizer;
withCredentials: boolean;
headers: { [key: string]: string | number | boolean };
params: { [key: string]: string | number | boolean | Blob };
localizer: ILocalizer;
}
export interface ILocalizer {
fileSizeInvalid: (maxFileSize: number) => string;
fileTypeInvalid: (accept: string) => string;
invalidResponseFromServer: () => string;
fileSizeInvalid: (maxFileSize: number) => string;
fileTypeInvalid: (accept: string) => string;
invalidResponseFromServer: () => string;
}
function getDefaultLocalizer(): ILocalizer {
return {
fileSizeInvalid: (maxFileSize) => 'The selected file exceeds the allowed size of ' + maxFileSize
+ ' or its size is 0 MB. Please choose another file.',
fileTypeInvalid: accept => 'File format is not allowed. Only ' + (accept ? accept : '') + ' files are allowed.',
invalidResponseFromServer: () => 'Invalid response from server'
};
return {
fileSizeInvalid: maxFileSize =>
"The selected file exceeds the allowed size of " +
maxFileSize +
" or its size is 0 MB. Please choose another file.",
fileTypeInvalid: accept =>
"File format is not allowed. Only " +
(accept ? accept : "") +
" files are allowed.",
invalidResponseFromServer: () => "Invalid response from server"
};
}
export interface IOffsetInfo {
running: boolean;
fileCount: number;
running: boolean;
fileCount: number;
}
export interface IUploadAreaOptions extends IUploadOptions {
maxFileSize?: number;
allowDragDrop?: boolean | (() => boolean);
clickable?: boolean | (() => boolean);
accept?: string;
multiple?: boolean;
validateExtension?: boolean;
manualStart?: boolean;
allowEmptyFile?: boolean;
dragOverStyle?: string;
dragOverGlobalStyle?: string;
maxFileSize?: number;
allowDragDrop?: boolean | (() => boolean);
clickable?: boolean | (() => boolean);
accept?: string;
multiple?: boolean;
validateExtension?: boolean;
manualStart?: boolean;
allowEmptyFile?: boolean;
dragOverStyle?: string;
dragOverGlobalStyle?: string;
onFileAdded?: (file: IUploadFile) => void;
onFileSelected?: (file: IUploadFile) => void;
onFileError?: (file: IUploadFile) => void;
onFileCanceled?: (file: IUploadFile) => void;
onFileAdded?: (file: IUploadFile) => void;
onFileSelected?: (file: IUploadFile) => void;
onFileError?: (file: IUploadFile) => void;
onFileCanceled?: (file: IUploadFile) => void;
}
export interface IUploadCallbacks {
onProgressCallback?: (file: IUploadFile) => void;
onCancelledCallback?: (file: IUploadFile) => void;
onFinishedCallback?: (file: IUploadFile) => void;
onUploadedCallback?: (file: IUploadFile) => void;
onErrorCallback?: (file: IUploadFile) => void;
onUploadStartedCallback?: (file: IUploadFile) => void;
onProgressCallback?: (file: IUploadFile) => void;
onCancelledCallback?: (file: IUploadFile) => void;
onFinishedCallback?: (file: IUploadFile) => void;
onUploadedCallback?: (file: IUploadFile) => void;
onErrorCallback?: (file: IUploadFile) => void;
onUploadStartedCallback?: (file: IUploadFile) => void;
}
export interface IUploadCallbacksExt extends IUploadCallbacks {
onFileStateChangedCallback?: (file: IUploadFile) => void;
onFileStateChangedCallback?: (file: IUploadFile) => void;
}
export interface IUploadFile extends File {
guid: string;
url: string;
uploadStatus: UploadStatus;
responseCode: number;
responseText: string;
progress: number;
sentBytes: number;
guid: string;
url: string;
uploadStatus: UploadStatus;
responseCode: number;
responseText: string;
progress: number;
sentBytes: number;
cancel: () => void;
remove: () => void;
start: () => void;
onError: (file: IUploadFile) => void;
onCancel: (file: IUploadFile) => void;
cancel: () => void;
remove: () => void;
start: () => void;
onError: (file: IUploadFile) => void;
onCancel: (file: IUploadFile) => void;
}
export interface IUploadOptions {
url: string | ((file: IUploadFile) => string);
method: string;
withCredentials?: boolean;
headers?: { [key: string]: string | number | boolean };
params?: { [key: string]: string | number | boolean | Blob };
localizer?: ILocalizer;
url: string | ((file: IUploadFile) => string);
method: string;
withCredentials?: boolean;
headers?: { [key: string]: string | number | boolean };
params?: { [key: string]: string | number | boolean | Blob };
localizer?: ILocalizer;
}
export interface IUploadQueueCallbacks extends IUploadCallbacks {
onFileAddedCallback?: (file: IUploadFile) => void;
onFileRemovedCallback?: (file: IUploadFile) => void;
onAllFinishedCallback?: () => void;
onQueueChangedCallback?: (queue: IUploadFile[]) => void;
onFileAddedCallback?: (file: IUploadFile) => void;
onFileRemovedCallback?: (file: IUploadFile) => void;
onAllFinishedCallback?: () => void;
onQueueChangedCallback?: (queue: IUploadFile[]) => void;
}
export interface IUploadQueueCallbacksExt extends IUploadQueueCallbacks, IUploadCallbacksExt {
}
export interface IUploadQueueCallbacksExt
extends IUploadQueueCallbacks,
IUploadCallbacksExt {}
export interface IUploadQueueOptions {
maxParallelUploads?: number;
parallelBatchOffset?: number;
autoStart?: boolean;
autoRemove?: boolean;
maxParallelUploads?: number;
parallelBatchOffset?: number;
autoStart?: boolean;
autoRemove?: boolean;
}
export function removeEventHandler(el: HTMLInputElement | Element, event: string, handler: (ev: UIEvent) => void) {
if (el.removeEventListener) {
el.removeEventListener(event, handler);
export function removeEventHandler(
el: HTMLInputElement | Element,
event: string,
handler: EventListenerOrEventListenerObject
) {
if (el.removeEventListener) {
el.removeEventListener(event, handler);
} else {
let elem = <IElementWithDettachEvent>el;
if (elem.detachEvent) {
elem.detachEvent("on" + event, handler as EventListener);
} else {
let elem = <IElementWithDettachEvent>el;
if (elem.detachEvent) {
elem.detachEvent('on' + event, handler);
} else {
elem[event] = null;
}
elem[event] = null;
}
}
}
interface IElementWithDettachEvent extends HTMLElement {
[key: string]: Function | Object | string | void | null | number | boolean;
detachEvent: (event: string, handler: (ev: UIEvent) => void) => void;
[key: string]: Function | Object | string | void | null | number | boolean;
detachEvent: (event: string, handler: (ev: UIEvent) => void) => void;
}
export class UploadArea {
public targetElement: HTMLElement;
public uploader: Uploader;
public options: IFullUploadAreaOptions;
private uploadCore: UploadCore;
private fileInput: HTMLInputElement;
private fileList?: IUploadFile[] | null;
private unregisterOnClick: () => void;
private unregisterOnDrop: () => void;
private unregisterOnDragOver: () => void;
private unregisterOnDragLeave: () => void;
private unregisterOnDragOverGlobal: () => void;
private unregisterOnDragLeaveGlobal: () => void;
private unregisterOnChange: () => void;
public targetElement: HTMLElement;
public uploader: Uploader;
public options: IFullUploadAreaOptions;
private uploadCore: UploadCore;
private fileInput?: HTMLInputElement;
private fileList?: IUploadFile[] | null;
private unregisterOnClick?: () => void;
private unregisterOnDrop?: () => void;
private unregisterOnDragOver?: () => void;
private unregisterOnDragLeave?: () => void;
private unregisterOnDragOverGlobal?: () => void;
private unregisterOnDragLeaveGlobal?: () => void;
private unregisterOnChange?: () => void;
constructor(targetElement: HTMLElement, options: IUploadAreaOptions, uploader: Uploader) {
this.targetElement = targetElement;
this.options = applyDefaults(options, this.defaultOptions());
this.uploader = uploader;
this.uploadCore = getUploadCore(this.options, this.uploader.queue.callbacks);
if (isFileApi) {
this.setupFileApiElements();
} else {
throw 'Only browsers with FileAPI supported.';
}
constructor(
targetElement: HTMLElement,
options: IUploadAreaOptions,
uploader: Uploader
) {
this.targetElement = targetElement;
this.options = applyDefaults(options, this.defaultOptions());
this.uploader = uploader;
this.uploadCore = getUploadCore(
this.options,
this.uploader.queue.callbacks
);
if (isFileApi) {
this.setupFileApiElements();
} else {
throw "Only browsers with FileAPI supported.";
}
}
start(autoClear: boolean = false) {
if (this.options.manualStart && this.fileList) {
this.putFilesToQueue();
if (autoClear)
this.clear();
}
start(autoClear: boolean = false) {
if (this.options.manualStart && this.fileList) {
this.putFilesToQueue();
if (autoClear) this.clear();
}
}
clear() {
this.fileList = null;
}
clear() {
this.fileList = null;
}
destroy(): void {
if (this.unregisterOnClick)
this.unregisterOnClick();
destroy(): void {
if (this.unregisterOnClick) this.unregisterOnClick();
if (this.unregisterOnDrop)
this.unregisterOnDrop();
if (this.unregisterOnDrop) this.unregisterOnDrop();
if (this.unregisterOnChange)
this.unregisterOnChange();
if (this.unregisterOnChange) this.unregisterOnChange();
if (this.unregisterOnDragOver)
this.unregisterOnDragOver();
if (this.unregisterOnDragOver) this.unregisterOnDragOver();
if (this.unregisterOnDragLeave)
this.unregisterOnDragLeave();
if (this.unregisterOnDragLeave) this.unregisterOnDragLeave();
if (this.unregisterOnDragOverGlobal)
this.unregisterOnDragOverGlobal();
if (this.unregisterOnDragOverGlobal) this.unregisterOnDragOverGlobal();
if (this.unregisterOnDragLeaveGlobal)
this.unregisterOnDragLeaveGlobal();
if (this.unregisterOnDragLeaveGlobal) this.unregisterOnDragLeaveGlobal();
document.body.removeChild(this.fileInput);
}
if (this.fileInput) document.body.removeChild(this.fileInput);
}
private defaultOptions() {
return {
localizer: getDefaultLocalizer(),
maxFileSize: 1024,
allowDragDrop: true,
clickable: true,
accept: '*.*',
validateExtension: false,
multiple: true,
allowEmptyFile: false
};
}
private defaultOptions() {
return {
localizer: getDefaultLocalizer(),
maxFileSize: 1024,
allowDragDrop: true,
clickable: true,
accept: "*.*",
validateExtension: false,
multiple: true,
allowEmptyFile: false
};
}
private selectFiles(fileList: FileList | File[]) {
this.fileList = castFiles(fileList);
private selectFiles(fileList: FileList | File[]) {
this.fileList = castFiles(fileList);
if (this.options.onFileSelected)
this.fileList.forEach((file: IUploadFile) => {
if (this.options.onFileSelected)
this.options.onFileSelected(file);
});
if (this.options.onFileSelected)
this.fileList.forEach((file: IUploadFile) => {
if (this.options.onFileSelected) this.options.onFileSelected(file);
});
if (!this.options.manualStart)
this.putFilesToQueue();
}
if (!this.options.manualStart) this.putFilesToQueue();
}
private putFilesToQueue(): void {
if (!this.fileList)
return;
private putFilesToQueue(): void {
if (!this.fileList) return;
this.fileList.forEach((file: IUploadFile) => {
file.guid = newGuid();
delete file.uploadStatus;
file.url = this.uploadCore.getUrl(file);
file.onError = this.options.onFileError || (() => { ; });
file.onCancel = this.options.onFileCanceled || (() => { ; });
if (this.validateFile(file)) {
file.start = () => {
this.uploadCore.upload([file]);
this.fileList.forEach((file: IUploadFile) => {
file.guid = newGuid();
delete file.uploadStatus;
file.url = this.uploadCore.getUrl(file);
file.onError = this.options.onFileError || (() => {});
file.onCancel = this.options.onFileCanceled || (() => {});
if (this.validateFile(file)) {
file.start = () => {
this.uploadCore.upload([file]);
if (this.options.onFileAdded) {
this.options.onFileAdded(file);
}
file.start = () => { return; };
};
} else {
file.onError(file);
}
});
this.uploader.queue.addFiles(this.fileList);
}
if (this.options.onFileAdded) {
this.options.onFileAdded(file);
}
file.start = () => {
return;
};
};
} else {
file.onError(file);
}
});
this.uploader.queue.addFiles(this.fileList);
}
private validateFile(file: IUploadFile): boolean {
if (!this.isFileSizeValid(file)) {
file.uploadStatus = UploadStatus.failed;
file.responseText = this.options.localizer.fileSizeInvalid(this.options.maxFileSize);
return false;
}
if (this.isFileTypeInvalid(file)) {
file.uploadStatus = UploadStatus.failed;
file.responseText = this.options.localizer.fileTypeInvalid(this.options.accept);
return false;
}
return true;
private validateFile(file: IUploadFile): boolean {
if (!this.isFileSizeValid(file)) {
file.uploadStatus = UploadStatus.failed;
file.responseText = this.options.localizer.fileSizeInvalid(
this.options.maxFileSize
);
return false;
}
if (this.isFileTypeInvalid(file)) {
file.uploadStatus = UploadStatus.failed;
file.responseText = this.options.localizer.fileTypeInvalid(
this.options.accept
);
return false;
}
return true;
}
private setupFileApiElements(): void {
this.fileInput = document.createElement('input');
this.fileInput.setAttribute('type', 'file');
this.fileInput.setAttribute('accept', this.options.accept ? this.options.accept : '');
this.fileInput.style.display = 'none';
private setupFileApiElements(): void {
this.fileInput = document.createElement("input");
this.fileInput.setAttribute("type", "file");
this.fileInput.setAttribute(
"accept",
this.options.accept ? this.options.accept : ""
);
this.fileInput.style.display = "none";
const onChange = (e: Event) => this.onChange(e);
addEventHandler(this.fileInput, 'change', onChange);
this.unregisterOnChange = () => removeEventHandler(this.fileInput, 'change', onchange);
const onChange = (e: Event) => this.onChange(e);
addEventHandler(this.fileInput, "change", onChange);
this.unregisterOnChange = () => {
if (this.fileInput)
removeEventHandler(this.fileInput, "change", onchange);
};
if (this.options.multiple) {
this.fileInput.setAttribute('multiple', '');
}
if (this.options.multiple) {
this.fileInput.setAttribute("multiple", "");
}
this.registerEvents();
this.registerEvents();
// attach to body
document.body.appendChild(this.fileInput);
}
// attach to body
document.body.appendChild(this.fileInput);
}
private registerEvents() {
const onClick = () => this.onClick();
addEventHandler(this.targetElement, 'click', onClick);
this.unregisterOnClick = () => removeEventHandler(this.targetElement, 'click', onClick);
private registerEvents() {
const onClick = () => this.onClick();
addEventHandler(this.targetElement, "click", onClick);
this.unregisterOnClick = () =>
removeEventHandler(this.targetElement, "click", onClick);
const onDrag = (e: DragEvent) => this.onDrag(e);
addEventHandler(this.targetElement, 'dragover', onDrag);
this.unregisterOnDragOver = () => removeEventHandler(this.targetElement, 'dragover', onDrag);
const onDrag = ((e: DragEvent) =>
this.onDrag(e)) as EventListenerOrEventListenerObject;
addEventHandler(this.targetElement, "dragover", onDrag);
this.unregisterOnDragOver = () =>
removeEventHandler(this.targetElement, "dragover", onDrag);
const onDragLeave = () => this.onDragLeave();
addEventHandler(this.targetElement, 'dragleave', onDragLeave);
this.unregisterOnDragOver = () => removeEventHandler(this.targetElement, 'dragleave', onDragLeave);
const onDragLeave = () => this.onDragLeave();
addEventHandler(this.targetElement, "dragleave", onDragLeave);
this.unregisterOnDragOver = () =>
removeEventHandler(this.targetElement, "dragleave", onDragLeave);
const onDragGlobal = () => this.onDragGlobal();
addEventHandler(document.body, 'dragover', onDragGlobal);
this.unregisterOnDragOverGlobal = () => removeEventHandler(document.body, 'dragover', onDragGlobal);
const onDragGlobal = () => this.onDragGlobal();
addEventHandler(document.body, "dragover", onDragGlobal);
this.unregisterOnDragOverGlobal = () =>
removeEventHandler(document.body, "dragover", onDragGlobal);
const onDragLeaveGlobal = () => this.onDragLeaveGlobal();
addEventHandler(document.body, 'dragleave', onDragLeaveGlobal);
this.unregisterOnDragOverGlobal = () => removeEventHandler(document.body, 'dragleave', onDragLeaveGlobal);
const onDragLeaveGlobal = () => this.onDragLeaveGlobal();
addEventHandler(document.body, "dragleave", onDragLeaveGlobal);
this.unregisterOnDragOverGlobal = () =>
removeEventHandler(document.body, "dragleave", onDragLeaveGlobal);
const onDrop = (e: DragEvent) => this.onDrop(e);
addEventHandler(this.targetElement, 'drop', onDrop);
this.unregisterOnDrop = () => removeEventHandler(this.targetElement, 'drop', onDrop);
}
const onDrop = ((e: DragEvent) =>
this.onDrop(e)) as EventListenerOrEventListenerObject;
addEventHandler(this.targetElement, "drop", onDrop);
this.unregisterOnDrop = () =>
removeEventHandler(this.targetElement, "drop", onDrop);
}
private onChange(e: Event): void {
this.selectFiles(<FileList>(<HTMLInputElement>e.target).files);
}
private onChange(e: Event): void {
this.selectFiles(<FileList>(<HTMLInputElement>e.target).files);
}
private onDrag(e: DragEvent): void {
if (!getValueOrResult(this.options.allowDragDrop))
return;
private onDrag(e: DragEvent): void {
if (!getValueOrResult(this.options.allowDragDrop)) return;
this.addDragOverStyle(this.options.dragOverStyle);
let efct: string | undefined = undefined;
try {
efct = e.dataTransfer.effectAllowed;
} catch (err) { ; }
e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
this.stopEventPropagation(e);
}
this.addDragOverStyle(this.options.dragOverStyle);
let efct: string | undefined = undefined;
try {
efct = e.dataTransfer.effectAllowed;
} catch (err) {}
e.dataTransfer.dropEffect =
"move" === efct || "linkMove" === efct ? "move" : "copy";
this.stopEventPropagation(e);
}
private onDragLeave(): void {
if (!getValueOrResult(this.options.allowDragDrop))
return;
private onDragLeave(): void {
if (!getValueOrResult(this.options.allowDragDrop)) return;
this.removeDragOverStyle(this.options.dragOverStyle);
}
this.removeDragOverStyle(this.options.dragOverStyle);
}
private onDragGlobal(): void {
if (!getValueOrResult(this.options.allowDragDrop))
return;
private onDragGlobal(): void {
if (!getValueOrResult(this.options.allowDragDrop)) return;
this.addDragOverStyle(this.options.dragOverGlobalStyle);
}
this.addDragOverStyle(this.options.dragOverGlobalStyle);
}
private onDragLeaveGlobal(): void {
if (!getValueOrResult(this.options.allowDragDrop))
return;
private onDragLeaveGlobal(): void {
if (!getValueOrResult(this.options.allowDragDrop)) return;
this.removeDragOverStyle(this.options.dragOverGlobalStyle);
}
this.removeDragOverStyle(this.options.dragOverGlobalStyle);
}
private removeDragOverStyle(style?: string) {
if (!style)
return;
private removeDragOverStyle(style?: string) {
if (!style) return;
this.targetElement.classList.remove(style);
}
this.targetElement.classList.remove(style);
}
private addDragOverStyle(style?: string) {
if (!style)
return;
private addDragOverStyle(style?: string) {
if (!style) return;
this.targetElement.classList.add(style);
}
this.targetElement.classList.add(style);
}
private onDrop(e: DragEvent): void {
if (!getValueOrResult(this.options.allowDragDrop))
return;
private onDrop(e: DragEvent): void {
if (!getValueOrResult(this.options.allowDragDrop)) return;
this.stopEventPropagation(e);
if (!e.dataTransfer) {
return;
}
this.stopEventPropagation(e);
if (!e.dataTransfer) {
return;
}
this.removeDragOverStyle(this.options.dragOverStyle);
this.removeDragOverStyle(this.options.dragOverStyle);
let files: FileList | File[] = e.dataTransfer.files;
if (files.length) {
if (!this.options.multiple)
files = [files[0]];
let files: FileList | File[] = e.dataTransfer.files;
if (files.length) {
if (!this.options.multiple) files = [files[0]];
let items = e.dataTransfer.items;
if (items && items.length && ((<{ webkitGetAsEntry?: Object }>items[0]).webkitGetAsEntry !== null)) {
if (!this.options.multiple) {
let newItems = [items[0]];
this.addFilesFromItems(newItems);
} else {
this.addFilesFromItems(items);
}
} else {
this.handleFiles(files);
}
let items = e.dataTransfer.items;
if (
items &&
items.length &&
(<{ webkitGetAsEntry?: Object }>items[0]).webkitGetAsEntry !== null
) {
if (!this.options.multiple) {
let newItems = [items[0]];
this.addFilesFromItems(newItems);
} else {
this.addFilesFromItems(items);
}
} else {
this.handleFiles(files);
}
}
}
private isIeVersion(v: number): boolean {
return RegExp('msie' + (!isNaN(v) ? ('\\s' + v.toString()) : ''), 'i').test(navigator.userAgent);
}
private isIeVersion(v: number): boolean {
return RegExp("msie" + (!isNaN(v) ? "\\s" + v.toString() : ""), "i").test(
navigator.userAgent
);
}
private onClick(): void {
if (!getValueOrResult(this.options.clickable))
return;
private onClick(): void {
if (!getValueOrResult(this.options.clickable) || !this.fileInput) return;
this.fileInput.value = '';
this.fileInput.value = "";
if (this.isIeVersion(10)) {
setTimeout(() => { this.fileInput.click(); }, 200);
} else {
this.fileInput.click();
}
if (this.isIeVersion(10)) {
setTimeout(() => {
if (this.fileInput) this.fileInput.click();
}, 200);
} else {
this.fileInput.click();
}
}
private addFilesFromItems(items: FileList | File[] | DataTransferItemList | DataTransferItem[]): void {
let entry: IFileExt;
for (let i = 0; i < items.length; i++) {
let item: IFileExt = <IFileExt>items[i];
if ((item.webkitGetAsEntry) && (entry = <IFileExt>item.webkitGetAsEntry())) {
if (entry.isFile) {
this.selectFiles([item.getAsFile()]);
} else if (entry.isDirectory) {
this.processDirectory(entry, entry.name);
}
} else if (item.getAsFile) {
if (!item.kind || item.kind === 'file') {
this.selectFiles([item.getAsFile()]);
}
}
private addFilesFromItems(
items: FileList | File[] | DataTransferItemList | DataTransferItem[]
): void {
let entry: IFileExt;
for (let i = 0; i < items.length; i++) {
let item: IFileExt = <IFileExt>items[i];
if (
item.webkitGetAsEntry &&
(entry = <IFileExt>item.webkitGetAsEntry())
) {
if (entry.isFile) {
this.selectFiles([item.getAsFile()]);
} else if (entry.isDirectory) {
this.processDirectory(entry, entry.name);
}
} else if (item.getAsFile) {
if (!item.kind || item.kind === "file") {
this.selectFiles([item.getAsFile()]);
}
}
}
}
private processDirectory(directory: { createReader: Function }, path: string): void {
let dirReader = directory.createReader();
let self = this;
let entryReader = (entries: (IFileExt & { createReader: Function })[]) => {
for (let i = 0; i < entries.length; i++) {
let entry = entries[i];
if (entry.isFile) {
entry.file((file: IFileExt) => {
if (file.name.substring(0, 1) === '.') {
return;
}
file.fullPath = '' + path + '/' + file.name;
self.selectFiles([file]);
});
} else if (entry.isDirectory) {
self.processDirectory(entry, '' + path + '/' + entry.name);
}
private processDirectory(
directory: { createReader: Function },
path: string
): void {
let dirReader = directory.createReader();
let self = this;
let entryReader = (entries: (IFileExt & { createReader: Function })[]) => {
for (let i = 0; i < entries.length; i++) {
let entry = entries[i];
if (entry.isFile) {
entry.file((file: IFileExt) => {
if (file.name.substring(0, 1) === ".") {
return;
}
};
dirReader.readEntries(entryReader, function (error: string) {
return typeof console !== 'undefined' && console !== null
? typeof console.log === 'function' ? console.log(error) : void 0
: void 0;
});
}
private handleFiles(files: FileList | File[]): void {
for (let i = 0; i < files.length; i++) {
this.selectFiles([files[i]]);
file.fullPath = "" + path + "/" + file.name;
self.selectFiles([file]);
});
} else if (entry.isDirectory) {
self.processDirectory(entry, "" + path + "/" + entry.name);
}
}
}
};
dirReader.readEntries(entryReader, function(error: string) {
return typeof console !== "undefined" && console !== null
? typeof console.log === "function" ? console.log(error) : void 0
: void 0;
});
}
private isFileSizeValid(file: File): boolean {
let maxFileSize = this.options.maxFileSize * 1024 * 1024; // max file size in bytes
if (file.size > maxFileSize || (!this.options.allowEmptyFile && file.size === 0)) return false;
return true;
private handleFiles(files: FileList | File[]): void {
for (let i = 0; i < files.length; i++) {
this.selectFiles([files[i]]);
}
}
private isFileTypeInvalid(file: File): boolean {
if (file.name && this.options.accept && (this.options.accept.trim() !== '*' || this.options.accept.trim() !== '*.*') &&
this.options.validateExtension && this.options.accept.indexOf('/') === -1) {
let acceptedExtensions = this.options.accept.split(',');
let fileExtension = file.name.substring(file.name.lastIndexOf('.'), file.name.length);
if (fileExtension.indexOf('.') === -1) return true;
let isFileExtensionExisted = true;
for (let i = 0; i < acceptedExtensions.length; i++) {
if (acceptedExtensions[i].toUpperCase().trim() === fileExtension.toUpperCase()) {
isFileExtensionExisted = false;
}
}
return isFileExtensionExisted;
private isFileSizeValid(file: File): boolean {
let maxFileSize = this.options.maxFileSize * 1024 * 1024; // max file size in bytes
if (
file.size > maxFileSize ||
(!this.options.allowEmptyFile && file.size === 0)
)
return false;
return true;
}
private isFileTypeInvalid(file: File): boolean {
if (
file.name &&
this.options.accept &&
(this.options.accept.trim() !== "*" ||
this.options.accept.trim() !== "*.*") &&
this.options.validateExtension &&
this.options.accept.indexOf("/") === -1
) {
let acceptedExtensions = this.options.accept.split(",");
let fileExtension = file.name.substring(
file.name.lastIndexOf("."),
file.name.length
);
if (fileExtension.indexOf(".") === -1) return true;
let isFileExtensionExisted = true;
for (let i = 0; i < acceptedExtensions.length; i++) {
if (
acceptedExtensions[i].toUpperCase().trim() ===
fileExtension.toUpperCase()
) {
isFileExtensionExisted = false;
}
return false;
}
return isFileExtensionExisted;
}
return false;
}
private stopEventPropagation(e: Event) {
e.stopPropagation();
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
private stopEventPropagation(e: Event) {
e.stopPropagation();
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
}
}
export class UploadCore {
public options: IFullUploadOptions;
public callbacks: IUploadCallbacksExt;
public options: IFullUploadOptions;
public callbacks: IUploadCallbacksExt;
constructor(options: IUploadOptions, callbacks: IUploadCallbacksExt = {}) {
this.callbacks = callbacks;
this.options = applyDefaults(options, this.getDefaultOptions());
this.setFullCallbacks(callbacks);
}
constructor(options: IUploadOptions, callbacks: IUploadCallbacksExt = {}) {
this.callbacks = callbacks;
this.options = applyDefaults(options, this.getDefaultOptions());
this.setFullCallbacks(callbacks);
}
upload(fileList: File[] | Object): void {
if (!isFileApi)
return;
let files = castFiles(fileList, UploadStatus.uploading);
files.forEach((file: IUploadFile) => this.processFile(file));
}
upload(fileList: File[] | Object): void {
if (!isFileApi) return;
let files = castFiles(fileList, UploadStatus.uploading);
files.forEach((file: IUploadFile) => this.processFile(file));
}
getUrl(file: IUploadFile): string {
return typeof this.options.url === 'function'
? (<(file: IUploadFile) => string>this.options.url)(file)
: <string>this.options.url;
}
getUrl(file: IUploadFile): string {
return typeof this.options.url === "function"
? (<(file: IUploadFile) => string>this.options.url)(file)
: <string>this.options.url;
}
private processFile(file: IUploadFile): void {
let xhr = this.createRequest(file);
this.setCallbacks(xhr, file);
this.send(xhr, file);
}
private processFile(file: IUploadFile): void {
let xhr = this.createRequest(file);
this.setCallbacks(xhr, file);
this.send(xhr, file);
}
private createRequest(file: IUploadFile): XMLHttpRequest {
let xhr = new XMLHttpRequest();
let url = file.url || this.getUrl(file);
xhr.open(this.options.method, url, true);
private createRequest(file: IUploadFile): XMLHttpRequest {
let xhr = new XMLHttpRequest();
let url = file.url || this.getUrl(file);
xhr.open(this.options.method, url, true);
xhr.withCredentials = !!this.options.withCredentials;
this.setHeaders(xhr);
return xhr;
}
xhr.withCredentials = !!this.options.withCredentials;
this.setHeaders(xhr);
return xhr;
}
private setHeaders(xhr: XMLHttpRequest) {
if (!this.options.headers)
return;
private setHeaders(xhr: XMLHttpRequest) {
if (!this.options.headers) return;
if (!this.options.headers['Accept'])
xhr.setRequestHeader('Accept', 'application/json');
if (!this.options.headers['Cache-Control'])
xhr.setRequestHeader('Cache-Control', 'no-cache');
if (!this.options.headers['X-Requested-With'])
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
if (!this.options.headers["Accept"])
xhr.setRequestHeader("Accept", "application/json");
if (!this.options.headers["Cache-Control"])
xhr.setRequestHeader("Cache-Control", "no-cache");
if (!this.options.headers["X-Requested-With"])
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
Object.keys(this.options.headers).forEach((headerName: string) => {
if (!this.options.headers)
return;
let headerValue = this.options.headers[headerName];
if (headerValue !== undefined && headerValue !== null)
xhr.setRequestHeader(headerName, (headerValue || '').toString());
});
}
Object.keys(this.options.headers).forEach((headerName: string) => {
if (!this.options.headers) return;
let headerValue = this.options.headers[headerName];
if (headerValue !== undefined && headerValue !== null)
xhr.setRequestHeader(headerName, (headerValue || "").toString());
});
}
private setCallbacks(xhr: XMLHttpRequest, file: IUploadFile) {
file.cancel = decorateSimpleFunction(
file.cancel, () => {
xhr.abort();
file.uploadStatus = UploadStatus.canceled;
if (file.onCancel)
file.onCancel(file);
if (this.callbacks.onCancelledCallback)
this.callbacks.onCancelledCallback(file);
private setCallbacks(xhr: XMLHttpRequest, file: IUploadFile) {
file.cancel = decorateSimpleFunction(
file.cancel,
() => {
xhr.abort();
file.uploadStatus = UploadStatus.canceled;
if (file.onCancel) file.onCancel(file);
if (this.callbacks.onCancelledCallback)
this.callbacks.onCancelledCallback(file);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
if (this.callbacks.onFinishedCallback)
this.callbacks.onFinishedCallback(file);
},
true);
if (this.callbacks.onFinishedCallback)
this.callbacks.onFinishedCallback(file);
},
true
);
xhr.onload = () => this.onload(file, xhr);
xhr.onerror = () => this.handleError(file, xhr);
xhr.upload.onprogress = (e: ProgressEvent) => this.updateProgress(file, e);
}
xhr.onload = () => this.onload(file, xhr);
xhr.onerror = () => this.handleError(file, xhr);
xhr.upload.onprogress = (e: ProgressEvent) => this.updateProgress(file, e);
}
private send(xhr: XMLHttpRequest, file: IUploadFile) {
let formData = this.createFormData(file);
if (this.callbacks.onUploadStartedCallback)
this.callbacks.onUploadStartedCallback(file);
private send(xhr: XMLHttpRequest, file: IUploadFile) {
let formData = this.createFormData(file);
if (this.callbacks.onUploadStartedCallback)
this.callbacks.onUploadStartedCallback(file);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
xhr.send(formData);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
xhr.send(formData);
}
private createFormData(file: IUploadFile): FormData {
let formData = new FormData();
if (this.options.params) {
Object.keys(this.options.params).forEach((paramName: string) => {
if (!this.options.params) return;
let paramValue = this.options.params[paramName];
if (paramValue !== undefined && paramValue !== null)
formData.append(paramName, this.castParamType(paramValue));
});
}
private createFormData(file: IUploadFile): FormData {
let formData = new FormData();
if (this.options.params) {
Object.keys(this.options.params).forEach((paramName: string) => {
if (!this.options.params)
return;
let paramValue = this.options.params[paramName];
if (paramValue !== undefined && paramValue !== null)
formData.append(paramName, this.castParamType(paramValue));
});
}
formData.append("file", file, file.name);
return formData;
}
formData.append('file', file, file.name);
return formData;
}
private castParamType(
param: string | number | boolean | Blob
): string | Blob {
return this.isBoolean(param) || this.isNumber(param)
? param.toString()
: param;
}
private castParamType(param: string | number | boolean | Blob): string | Blob {
return this.isBoolean(param) || this.isNumber(param) ? param.toString() : param;
}
private isNumber(param: string | number | boolean | Blob): param is number {
return typeof param === "number";
}
private isNumber(param: string | number | boolean | Blob): param is number {
return typeof param === 'number';
}
private isBoolean(param: string | number | boolean | Blob): param is boolean {
return typeof param === "number";
}
private isBoolean(param: string | number | boolean | Blob): param is boolean {
return typeof param === 'number';
private handleError(file: IUploadFile, xhr: XMLHttpRequest): void {
file.uploadStatus = UploadStatus.failed;
this.setResponse(file, xhr);
if (file.onError) {
file.onError(file);
}
private handleError(file: IUploadFile, xhr: XMLHttpRequest): void {
file.uploadStatus = UploadStatus.failed;
this.setResponse(file, xhr);
if (file.onError) {
file.onError(file);
}
if (this.callbacks.onErrorCallback) this.callbacks.onErrorCallback(file);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
if (this.callbacks.onFinishedCallback)
this.callbacks.onFinishedCallback(file);
}
if (this.callbacks.onErrorCallback)
this.callbacks.onErrorCallback(file);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
if (this.callbacks.onFinishedCallback)
this.callbacks.onFinishedCallback(file);
private updateProgress(file: IUploadFile, e?: ProgressEvent) {
if (e) {
if (e.lengthComputable) {
file.progress = Math.round(100 * (e.loaded / e.total));
file.sentBytes = e.loaded;
} else {
file.progress = 0;
file.sentBytes = 0;
}
} else {
file.progress = 100;
file.sentBytes = file.size;
}
private updateProgress(file: IUploadFile, e?: ProgressEvent) {
if (e) {
if (e.lengthComputable) {
file.progress = Math.round(100 * (e.loaded / e.total));
file.sentBytes = e.loaded;
} else {
file.progress = 0;
file.sentBytes = 0;
}
} else {
file.progress = 100;
file.sentBytes = file.size;
}
if (this.callbacks.onProgressCallback)
this.callbacks.onProgressCallback(file);
}
if (this.callbacks.onProgressCallback)
this.callbacks.onProgressCallback(file);
}
private onload(file: IUploadFile, xhr: XMLHttpRequest) {
if (xhr.readyState !== 4) return;
private onload(file: IUploadFile, xhr: XMLHttpRequest) {
if (xhr.readyState !== 4)
return;
if (file.progress !== 100) this.updateProgress(file);
if (file.progress !== 100)
this.updateProgress(file);
if (xhr.status === 200) {
this.finished(file, xhr);
} else {
this.handleError(file, xhr);
}
if (xhr.status === 200) {
this.finished(file, xhr);
} else {
this.handleError(file, xhr);
}
}
private finished(file: IUploadFile, xhr: XMLHttpRequest) {
file.uploadStatus = UploadStatus.uploaded;
this.setResponse(file, xhr);
private finished(file: IUploadFile, xhr: XMLHttpRequest) {
file.uploadStatus = UploadStatus.uploaded;
this.setResponse(file, xhr);
if (this.callbacks.onUploadedCallback)
this.callbacks.onUploadedCallback(file);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
if (this.callbacks.onFinishedCallback)
this.callbacks.onFinishedCallback(file);
};
if (this.callbacks.onUploadedCallback)
this.callbacks.onUploadedCallback(file);
if (this.callbacks.onFileStateChangedCallback)
this.callbacks.onFileStateChangedCallback(file);
if (this.callbacks.onFinishedCallback)
this.callbacks.onFinishedCallback(file);
}
private setResponse(file: IUploadFile, xhr: XMLHttpRequest) {
file.responseCode = xhr.status;
file.responseText = xhr.responseText || xhr.statusText || (xhr.status
? xhr.status.toString()
: '' || this.options.localizer.invalidResponseFromServer());
}
private setResponse(file: IUploadFile, xhr: XMLHttpRequest) {
file.responseCode = xhr.status;
file.responseText =
xhr.responseText ||
xhr.statusText ||
(xhr.status
? xhr.status.toString()
: "" || this.options.localizer.invalidResponseFromServer());
}
private getDefaultOptions(): IFullUploadOptions {
return {
headers: {},
params: {},
withCredentials: false,
localizer: getDefaultLocalizer()
} as IFullUploadOptions;
}
private getDefaultOptions(): IFullUploadOptions {
return {
headers: {},
params: {},
withCredentials: false,
localizer: getDefaultLocalizer()
} as IFullUploadOptions;
}
private setFullCallbacks(callbacks: IUploadCallbacksExt) {
this.callbacks.onProgressCallback = callbacks.onProgressCallback || (() => { return; });
this.callbacks.onCancelledCallback = callbacks.onCancelledCallback || (() => { return; });
this.callbacks.onFinishedCallback = callbacks.onFinishedCallback || (() => { return; });
this.callbacks.onUploadedCallback = callbacks.onUploadedCallback || (() => { return; });
this.callbacks.onErrorCallback = callbacks.onErrorCallback || (() => { return; });
this.callbacks.onUploadStartedCallback = callbacks.onUploadStartedCallback || (() => { return; });
this.callbacks.onFileStateChangedCallback = callbacks.onFileStateChangedCallback || (() => { return; });
}
private setFullCallbacks(callbacks: IUploadCallbacksExt) {
this.callbacks.onProgressCallback =
callbacks.onProgressCallback ||
(() => {
return;
});
this.callbacks.onCancelledCallback =
callbacks.onCancelledCallback ||
(() => {
return;
});
this.callbacks.onFinishedCallback =
callbacks.onFinishedCallback ||
(() => {
return;
});
this.callbacks.onUploadedCallback =
callbacks.onUploadedCallback ||
(() => {
return;
});
this.callbacks.onErrorCallback =
callbacks.onErrorCallback ||
(() => {
return;
});
this.callbacks.onUploadStartedCallback =
callbacks.onUploadStartedCallback ||
(() => {
return;
});
this.callbacks.onFileStateChangedCallback =
callbacks.onFileStateChangedCallback ||
(() => {
return;
});
}
}
export class Uploader {
uploadAreas: UploadArea[];
queue: UploadQueue;
options: IUploadQueueOptions;
export class UploadQueue {
offset: IOffsetInfo = { fileCount: 0, running: false };
options: IUploadQueueOptions;
callbacks: IUploadQueueCallbacksExt;
queuedFiles: IUploadFile[] = [];
constructor(options: IUploadQueueOptions = {}, callbacks: IUploadQueueCallbacks = {}) {
this.setOptions(options);
this.uploadAreas = [];
this.queue = new UploadQueue(options, callbacks);
}
constructor(
options: IUploadQueueOptions,
callbacks: IUploadQueueCallbacksExt
) {
this.options = options;
this.callbacks = callbacks;
this.setFullOptions();
this.setFullCallbacks();
}
setOptions(options: IUploadQueueOptions): void {
this.options = options;
}
addFiles(files: IUploadFile[]): void {
files.forEach(file => {
if (
!this.queuedFiles.some(
queuedFile =>
queuedFile === file ||
(!!queuedFile.guid && queuedFile.guid === file.guid)
)
) {
this.queuedFiles.push(file);
registerArea(element: HTMLElement, options: IUploadAreaOptions): UploadArea {
const uploadArea = new UploadArea(element, options, this);
this.uploadAreas.push(uploadArea);
return uploadArea;
}
file.remove = decorateSimpleFunction(file.remove, () => {
this.removeFile(file);
});
}
unregisterArea(area: UploadArea): void {
const areaIndex = this.uploadAreas.indexOf(area);
if (areaIndex >= 0) {
this.uploadAreas[areaIndex].destroy();
this.uploadAreas.splice(areaIndex, 1);
if (this.callbacks.onFileAddedCallback)
this.callbacks.onFileAddedCallback(file);
if (file.uploadStatus === UploadStatus.failed) {
if (this.callbacks.onErrorCallback) {
this.callbacks.onErrorCallback(file);
}
}
}
} else {
file.uploadStatus = UploadStatus.queued;
}
});
export class UploadQueue {
offset: IOffsetInfo = { fileCount: 0, running: false };
options: IUploadQueueOptions;
callbacks: IUploadQueueCallbacksExt;
queuedFiles: IUploadFile[] = [];
this.filesChanged();
}
constructor(options: IUploadQueueOptions, callbacks: IUploadQueueCallbacksExt) {
this.options = options;
this.callbacks = callbacks;
this.setFullOptions();
this.setFullCallbacks();
}
removeFile(file: IUploadFile, blockRecursive: boolean = false) {
let index = this.queuedFiles.indexOf(file);
addFiles(files: IUploadFile[]): void {
files.forEach(file => {
if (!this.queuedFiles.some(queuedFile => queuedFile === file || (!!queuedFile.guid && queuedFile.guid === file.guid))) {
this.queuedFiles.push(file);
if (index < 0) return;
file.remove = decorateSimpleFunction(file.remove, () => {
this.removeFile(file);
});
}
this.deactivateFile(file);
this.queuedFiles.splice(index, 1);
if (this.callbacks.onFileAddedCallback)
this.callbacks.onFileAddedCallback(file);
if (this.callbacks.onFileRemovedCallback)
this.callbacks.onFileRemovedCallback(file);
if (file.uploadStatus === UploadStatus.failed) {
if (this.callbacks.onErrorCallback) {
this.callbacks.onErrorCallback(file);
}
} else {
file.uploadStatus = UploadStatus.queued;
}
});
if (!blockRecursive) this.filesChanged();
}
this.filesChanged();
}
clearFiles(
excludeStatuses: UploadStatus[] = [],
cancelProcessing: boolean = false
) {
if (!cancelProcessing)
excludeStatuses = excludeStatuses.concat([
UploadStatus.queued,
UploadStatus.uploading
]);
removeFile(file: IUploadFile, blockRecursive: boolean = false) {
let index = this.queuedFiles.indexOf(file);
this.queuedFiles
.filter(
(file: IUploadFile) => excludeStatuses.indexOf(file.uploadStatus) < 0
)
.forEach(file => this.removeFile(file, true));
if (index < 0)
return;
if (this.callbacks.onQueueChangedCallback)
this.callbacks.onQueueChangedCallback(this.queuedFiles);
}
this.deactivateFile(file);
this.queuedFiles.splice(index, 1);
private filesChanged(): void {
if (this.options.autoRemove) this.removeFinishedFiles();
if (this.callbacks.onFileRemovedCallback)
this.callbacks.onFileRemovedCallback(file);
if (this.options.autoStart) this.startWaitingFiles();
if (!blockRecursive)
this.filesChanged();
}
if (this.callbacks.onQueueChangedCallback)
this.callbacks.onQueueChangedCallback(this.queuedFiles);
clearFiles(excludeStatuses: UploadStatus[] = [], cancelProcessing: boolean = false) {
if (!cancelProcessing)
excludeStatuses = excludeStatuses.concat([UploadStatus.queued, UploadStatus.uploading]);
this.checkAllFinished();
}
this.queuedFiles
.filter((file: IUploadFile) => excludeStatuses.indexOf(file.uploadStatus) < 0)
.forEach(file => this.removeFile(file, true)
);
private checkAllFinished(): void {
const unfinishedFiles = this.queuedFiles.filter(
file =>
[UploadStatus.queued, UploadStatus.uploading].indexOf(
file.uploadStatus
) >= 0
);
if (this.callbacks.onQueueChangedCallback)
this.callbacks.onQueueChangedCallback(this.queuedFiles);
if (unfinishedFiles.length === 0 && this.callbacks.onAllFinishedCallback) {
this.callbacks.onAllFinishedCallback();
}
}
private filesChanged(): void {
if (this.options.autoRemove)
this.removeFinishedFiles();
private setFullOptions(): void {
this.options.maxParallelUploads = this.options.maxParallelUploads || 0;
this.options.parallelBatchOffset = this.options.parallelBatchOffset || 0;
this.options.autoStart = isFileApi && (this.options.autoStart || false);
this.options.autoRemove = this.options.autoRemove || false;
}
if (this.options.autoStart)
this.startWaitingFiles();
private setFullCallbacks(): void {
this.callbacks.onFileAddedCallback =
this.callbacks.onFileAddedCallback ||
(() => {
return;
});
this.callbacks.onFileRemovedCallback =
this.callbacks.onFileRemovedCallback ||
(() => {
return;
});
this.callbacks.onAllFinishedCallback =
this.callbacks.onAllFinishedCallback ||
(() => {
return;
});
this.callbacks.onQueueChangedCallback =
this.callbacks.onQueueChangedCallback ||
(() => {
return;
});
if (this.callbacks.onQueueChangedCallback)
this.callbacks.onQueueChangedCallback(this.queuedFiles);
this.callbacks.onFileStateChangedCallback = () => this.filesChanged();
}
this.checkAllFinished();
}
private startWaitingFiles(): void {
this.getWaitingFiles().forEach(file => file.start());
}
private checkAllFinished(): void {
const unfinishedFiles = this.queuedFiles
.filter(file => [UploadStatus.queued, UploadStatus.uploading].indexOf(file.uploadStatus) >= 0);
private removeFinishedFiles(): void {
this.queuedFiles
.filter(
file =>
[UploadStatus.uploaded, UploadStatus.canceled].indexOf(
file.uploadStatus
) >= 0
)
.forEach(file => this.removeFile(file, true));
}
if (unfinishedFiles.length === 0 && this.callbacks.onAllFinishedCallback) {
this.callbacks.onAllFinishedCallback();
}
}
private deactivateFile(file: IUploadFile) {
if (file.uploadStatus === UploadStatus.uploading) file.cancel();
private setFullOptions(): void {
this.options.maxParallelUploads = this.options.maxParallelUploads || 0;
this.options.parallelBatchOffset = this.options.parallelBatchOffset || 0;
this.options.autoStart = isFileApi && (this.options.autoStart || false);
this.options.autoRemove = this.options.autoRemove || false;
file.uploadStatus = UploadStatus.removed;
file.cancel = () => {
return;
};
file.remove = () => {
return;
};
file.start = () => {
return;
};
}
}
private getWaitingFiles() {
if (!this.options.autoStart) return [];
private setFullCallbacks(): void {
this.callbacks.onFileAddedCallback = this.callbacks.onFileAddedCallback || (() => { return; });
this.callbacks.onFileRemovedCallback = this.callbacks.onFileRemovedCallback || (() => { return; });
this.callbacks.onAllFinishedCallback = this.callbacks.onAllFinishedCallback || (() => { return; });
this.callbacks.onQueueChangedCallback = this.callbacks.onQueueChangedCallback || (() => { return; });
let result = this.queuedFiles.filter(
file => file.uploadStatus === UploadStatus.queued
);
this.callbacks.onFileStateChangedCallback = () => this.filesChanged();
}
if (this.options.maxParallelUploads) {
const uploadingFilesCount = this.queuedFiles.filter(
file => file.uploadStatus === UploadStatus.uploading
).length;
private startWaitingFiles(): void {
this.getWaitingFiles().forEach(file => file.start());
}
let count = Math.min(
result.length,
this.options.maxParallelUploads - uploadingFilesCount
);
private removeFinishedFiles(): void {
this.queuedFiles
.filter(file => [UploadStatus.uploaded, UploadStatus.canceled].indexOf(file.uploadStatus) >= 0)
.forEach(file => this.removeFile(file, true));
}
if (count <= 0) {
return [];
}
private deactivateFile(file: IUploadFile) {
if (file.uploadStatus === UploadStatus.uploading)
file.cancel();
if (this.options.parallelBatchOffset) {
if (!this.offset.running) {
this.startOffset();
}
file.uploadStatus = UploadStatus.removed;
file.cancel = () => { return; };
file.remove = () => { return; };
file.start = () => { return; };
count =
Math.min(
this.offset.fileCount + count,
this.options.maxParallelUploads
) - this.offset.fileCount;
this.offset.fileCount += count;
}
result = result.slice(0, count);
}
private getWaitingFiles() {
if (!this.options.autoStart)
return [];
return result;
}
let result = this.queuedFiles.filter(file => file.uploadStatus === UploadStatus.queued);
private startOffset() {
this.offset.fileCount = 0;
this.offset.running = true;
if (this.options.maxParallelUploads) {
const uploadingFilesCount = this.queuedFiles.filter(file => file.uploadStatus === UploadStatus.uploading).length;
setTimeout(() => {
this.offset.fileCount = 0;
this.offset.running = false;
this.filesChanged();
}, this.options.parallelBatchOffset);
}
}
let count = Math.min(result.length, this.options.maxParallelUploads - uploadingFilesCount);
export enum UploadStatus {
queued,
uploading,
uploaded,
failed,
canceled,
removed
}
if (count <= 0) {
return [];
}
export class Uploader {
uploadAreas: UploadArea[];
queue: UploadQueue;
options: IUploadQueueOptions;
if (this.options.parallelBatchOffset) {
if (!this.offset.running) {
this.startOffset();
}
constructor(
options: IUploadQueueOptions = {},
callbacks: IUploadQueueCallbacks = {}
) {
this.options = options;
this.uploadAreas = [];
this.queue = new UploadQueue(options, callbacks);
}
count = Math.min(this.offset.fileCount + count, this.options.maxParallelUploads) - this.offset.fileCount;
this.offset.fileCount += count;
}
registerArea(element: HTMLElement, options: IUploadAreaOptions): UploadArea {
const uploadArea = new UploadArea(element, options, this);
this.uploadAreas.push(uploadArea);
return uploadArea;
}
result = result.slice(0, count);
}
return result;
unregisterArea(area: UploadArea): void {
const areaIndex = this.uploadAreas.indexOf(area);
if (areaIndex >= 0) {
this.uploadAreas[areaIndex].destroy();
this.uploadAreas.splice(areaIndex, 1);
}
private startOffset() {
this.offset.fileCount = 0;
this.offset.running = true;
setTimeout(
() => {
this.offset.fileCount = 0;
this.offset.running = false;
this.filesChanged();
},
this.options.parallelBatchOffset
);
}
}
}
export enum UploadStatus {
queued,
uploading,
uploaded,
failed,
canceled,
removed
}
{
"name": "pure-upload",
"version": "4.2.1",
"version": "5.0.0",
"description": "The pure upload library without dependencies",

@@ -13,6 +13,2 @@ "author": {

"email": "trut.cz@gmail.com"
},
{
"name": "Marek Horyna",
"email": "marek.horyna@outlook.com"
}

@@ -38,8 +34,7 @@ ],

"@types/cors": "^2.8.0",
"@types/jasmine": "^2.5.43",
"@types/karma": "^0.13.33",
"@types/jasmine": "^2.8.6",
"@types/multer": "0.0.33",
"cors": "^2.8.1",
"express": "^4.14.1",
"gulp": "^3.9.0",
"gulp": "^3.9.1",
"gulp-clean": "^0.3.1",

@@ -67,4 +62,5 @@ "gulp-concat": "^2.6.0",

"run-sequence": "^1.1.2",
"typescript": "^2.3.1"
}
}
"typescript": "^2.7.2"
},
"dependencies": {}
}
declare module "pure-upload" {
export function addEventHandler(el: Element | HTMLElement, event: string, handler: (ev: UIEvent) => void): void;
export const isFileApi: boolean;
export function castFiles(fileList: File[] | Object, status?: UploadStatus): IUploadFile[];
export function decorateSimpleFunction(origFn: () => void, newFn: () => void, newFirst?: boolean): () => void;
export function getUploadCore(options: IUploadOptions, callbacks: IUploadCallbacks): UploadCore;
export function getUploader(options: IUploadQueueOptions, callbacks: IUploadQueueCallbacks): Uploader;
export function getValueOrResult<T>(valueOrGetter?: T | (() => T)): T | undefined;
export function newGuid(): string;
export interface IFileExt extends File {

@@ -20,2 +12,10 @@ kind: string;

}
export function addEventHandler(el: Element | HTMLElement, event: string, handler: EventListenerOrEventListenerObject): void;
export const isFileApi: boolean;
export function castFiles(fileList: File[] | Object, status?: UploadStatus): IUploadFile[];
export function decorateSimpleFunction(origFn: () => void, newFn: () => void, newFirst?: boolean): () => void;
export function getUploadCore(options: IUploadOptions, callbacks: IUploadCallbacks): UploadCore;
export function getUploader(options: IUploadQueueOptions, callbacks: IUploadQueueCallbacks): Uploader;
export function getValueOrResult<T>(valueOrGetter?: T | (() => T)): T | undefined;
export function newGuid(): string;
export interface IFullUploadAreaOptions extends IUploadAreaOptions {

@@ -116,3 +116,3 @@ maxFileSize: number;

}
export function removeEventHandler(el: HTMLInputElement | Element, event: string, handler: (ev: UIEvent) => void): void;
export function removeEventHandler(el: HTMLInputElement | Element, event: string, handler: EventListenerOrEventListenerObject): void;
export class UploadArea {

@@ -123,11 +123,11 @@ targetElement: HTMLElement;

private uploadCore;
private fileInput;
private fileInput?;
private fileList?;
private unregisterOnClick;
private unregisterOnDrop;
private unregisterOnDragOver;
private unregisterOnDragLeave;
private unregisterOnDragOverGlobal;
private unregisterOnDragLeaveGlobal;
private unregisterOnChange;
private unregisterOnClick?;
private unregisterOnDrop?;
private unregisterOnDragOver?;
private unregisterOnDragLeave?;
private unregisterOnDragOverGlobal?;
private unregisterOnDragLeaveGlobal?;
private unregisterOnChange?;
constructor(targetElement: HTMLElement, options: IUploadAreaOptions, uploader: Uploader);

@@ -183,11 +183,2 @@ start(autoClear?: boolean): void;

}
export class Uploader {
uploadAreas: UploadArea[];
queue: UploadQueue;
options: IUploadQueueOptions;
constructor(options?: IUploadQueueOptions, callbacks?: IUploadQueueCallbacks);
setOptions(options: IUploadQueueOptions): void;
registerArea(element: HTMLElement, options: IUploadAreaOptions): UploadArea;
unregisterArea(area: UploadArea): void;
}
export class UploadQueue {

@@ -220,2 +211,10 @@ offset: IOffsetInfo;

}
export class Uploader {
uploadAreas: UploadArea[];
queue: UploadQueue;
options: IUploadQueueOptions;
constructor(options?: IUploadQueueOptions, callbacks?: IUploadQueueCallbacks);
registerArea(element: HTMLElement, options: IUploadAreaOptions): UploadArea;
unregisterArea(area: UploadArea): void;
}
}

@@ -0,0 +0,0 @@ # Pure-upload

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc