UploaderQueue = function(o={}) {
for(var i in o){
if (o.hasOwnProperty(i))
if(UploaderQueue.ATTRS.hasOwnProperty(i))UploaderQueue.ATTRS[i]=o[i];
}
CONTINUE= "continue",
STOP= "stop",
RESTART_ASAP= "restartasap",
RESTART_AFTER= "restartafter",
STOPPED= "stopped",
UPLOADING= "uploading",
NAME= 'uploaderqueue',
this.queuedFiles = [];
this.uploadRetries = {};
this.numberOfUploads = 0;
this.currentUploadedByteValues = {};
this.currentFiles = {};
this.totalBytesUploaded = 0;
this.totalBytes = 0;
};
UploaderQueue.prototype = {
_currentState: UploaderQueue.STOPPED,
uploadCompleteHandler:null,
uploadProgressHandler:null,
uploadStartHandler:null,
uploadCancelHandler:null,
uploadErrorHandler:null,
_uploadStartHandler : function (event) {
var updatedEvent = {};
updatedEvent.file = event.target;
updatedEvent.originEvent = event;
this.fire("uploadstart", updatedEvent);
},
each: function(a,f){for(var i=0;i< a.length;i++)f(a[i]);},
fire:function(e,o={},canBubble=false,cancelable=false){
var evt = document.createEvent("HTMLEvents");
evt.initEvent(e, canBubble, cancelable);
Object.assign(evt,o);
document.dispatchEvent(evt);
},
get:function(s){
if(UploaderQueue.ATTRS.hasOwnProperty(s))return UploaderQueue.ATTRS[s];
},
set:function(s,o){
if(UploaderQueue.ATTRS.hasOwnProperty(s))return UploaderQueue.ATTRS[s]=o;
},
_uploadErrorHandler : function (event) {
var errorAction = this.get("errorAction"),
updatedEvent = event,
fileid,
retries;
updatedEvent.file = event.target;
updatedEvent.originEvent = event;
this.numberOfUploads-=1;
delete this.currentFiles[event.target.id];
this._detachFileEvents(event.target);
event.target.cancelUpload();
if (errorAction === UploaderQueue.STOP) {
this.pauseUpload();
}
else if (errorAction === UploaderQueue.RESTART_ASAP) {
fileid = event.target.id;
retries = this.uploadRetries[fileid] || 0;
if (retries < this.get("retryCount")) {
this.uploadRetries[fileid] = retries + 1;
this.addToQueueTop(event.target);
}
this._startNextFile();
}
else if (errorAction === UploaderQueue.RESTART_AFTER) {
fileid = event.target.id;
retries = this.uploadRetries[fileid] || 0;
if (retries < this.get("retryCount")) {
this.uploadRetries[fileid] = retries + 1;
this.addToQueueBottom(event.target);
}
this._startNextFile();
}
this.fire("uploaderror", updatedEvent);
},
_startNextFile : function () {
if (this.queuedFiles.length > 0) {
var currentFile = this.queuedFiles.shift(),
fileId = currentFile.id,
parameters = this.get("perFileParameters"),
fileParameters = parameters.hasOwnProperty(fileId) ? parameters[fileId] : parameters;
this.currentUploadedByteValues[fileId] = 0;
this.uploadCompleteHandler = this._uploadCompleteHandler.bind(this);
this.uploadProgressHandler = this._uploadProgressHandler.bind(this);
this.uploadStartHandler = this._uploadStartHandler.bind(this);
this.uploadCancelHandler = this._uploadCancelHandler.bind(this);
this.uploadErrorHandler = this._uploadErrorHandler.bind(this);
currentFile.on("uploadstart", this.uploadStartHandler);
currentFile.on("uploadprogress", this.uploadProgressHandler);
currentFile.on("uploadcomplete", this.uploadCompleteHandler);
currentFile.on("uploaderror", this.uploadErrorHandler);
currentFile.on("uploadcancel", this.uploadCancelHandler);
currentFile.xhrHeaders = this.get("uploadHeaders");
currentFile.xhrWithCredentials = this.get("withCredentials");
currentFile.startUpload(this.get("uploadURL"), fileParameters, this.get("fileFieldName"));
this._registerUpload(currentFile);
}
},
/**
* Register a new upload process.
*
* @method _registerUpload
* @private
*/
_registerUpload : function (file) {
this.numberOfUploads += 1;
this.currentFiles[file.id] = file;
},
/**
* Unregisters a new upload process.
*
* @method _unregisterUpload
* @private
*/
_unregisterUpload : function (file) {
if (this.numberOfUploads > 0) {
this.numberOfUploads -= 1;
}
delete this.currentFiles[file.id];
delete this.uploadRetries[file.id];
this._detachFileEvents(file);
},
_detachFileEvents : function (file) {
file.detach("uploadstart", this.uploadStartHandler);
file.detach("uploadprogress", this.uploadProgressHandler);
file.detach("uploadcomplete", this.uploadCompleteHandler);
file.detach("uploaderror", this.uploadErrorHandler);
file.detach("uploadcancel", this.uploadCancelHandler);
},
/**
* Handles and retransmits upload complete event.
*
* @method _uploadCompleteHandler
* @param event The event dispatched during the upload process.
* @private
*/
_uploadCompleteHandler : function (event) {
this._unregisterUpload(event.file);
this.totalBytesUploaded += event.file.size;
delete this.currentUploadedByteValues[event.file.id];
if (this.queuedFiles.length > 0 && this._currentState === UploaderQueue.UPLOADING) {
this._startNextFile();
}
var updatedEvent = {},
uploadedTotal = this.totalBytesUploaded,
percentLoaded = Math.min(100, Math.round(10000*uploadedTotal/this.totalBytes) / 100);
updatedEvent.file = event.file;
updatedEvent.originEvent = event;
this.each(this.currentUploadedByteValues, function (value) {
uploadedTotal += value;
});
this.fire("totaluploadprogress", {
bytesLoaded: uploadedTotal,
bytesTotal: this.totalBytes,
percentLoaded: percentLoaded
});
this.fire("uploadcomplete", updatedEvent);
if (this.queuedFiles.length === 0 && this.numberOfUploads <= 0) {
this.fire("alluploadscomplete");
this._currentState = UploaderQueue.STOPPED;
}
},
/**
* Handles and retransmits upload cancel event.
*
* @method _uploadCancelHandler
* @param event The event dispatched during the upload process.
* @private
*/
_uploadCancelHandler : function (event) {
var updatedEvent = {};
updatedEvent.originEvent = event;
updatedEvent.file = event.target;
this.fire("uploadcancel", updatedEvent);
},
_uploadProgressHandler : function (event) {
this.currentUploadedByteValues[event.file.id] = event.bytesLoaded;
var updatedEvent = {},
uploadedTotal = this.totalBytesUploaded,
percentLoaded = Math.min(100, Math.round(10000*uploadedTotal/this.totalBytes) / 100);
updatedEvent.originEvent = event;
updatedEvent.file = event.file;
this.fire("uploadprogress", updatedEvent);
this.each(this.currentUploadedByteValues, function (value) {
uploadedTotal += value;
});
this.fire("totaluploadprogress", {
bytesLoaded: uploadedTotal,
bytesTotal: this.totalBytes,
percentLoaded: percentLoaded
});
},
/**
* Starts uploading the queued up file list.
*
* @method startUpload
*/
startUpload: function() {
this.queuedFiles = this.get("fileList").slice(0);
this.numberOfUploads = 0;
this.currentUploadedByteValues = {};
this.currentFiles = {};
this.totalBytesUploaded = 0;
this._currentState = UploaderQueue.UPLOADING;
while (this.numberOfUploads < this.get("simUploads") && this.queuedFiles.length > 0) {
this._startNextFile();
}
},
pauseUpload: function () {this._currentState = UploaderQueue.STOPPED;},
restartUpload: function () {
this._currentState = UploaderQueue.UPLOADING;
while (this.numberOfUploads < this.get("simUploads")) {
this._startNextFile();
}
},
forceReupload : function (file) {
var id = file.id;
if (this.currentFiles.hasOwnProperty(id)) {
file.cancelUpload();
this._unregisterUpload(file);
this.addToQueueTop(file);
this._startNextFile();
}
},
addToQueueTop: function (file) {this.queuedFiles.unshift(file); },
addToQueueBottom: function (file) {this.queuedFiles.push(file);},
cancelUpload: function (file) {
var id,
i,
fid;
if (file) {
id = file.id;
if (this.currentFiles[id]) {
this.currentFiles[id].cancelUpload();
this._unregisterUpload(this.currentFiles[id]);
if (this._currentState === UploaderQueue.UPLOADING) {
this._startNextFile();
}
}
else {
for (i = 0, len = this.queuedFiles.length; i < len; i++) {
if (this.queuedFiles[i].id === id) {
this.queuedFiles.splice(i, 1);
break;
}
}
}
}
else {
for (fid in this.currentFiles) {
this.currentFiles[fid].cancelUpload();
this._unregisterUpload(this.currentFiles[fid]);
}
this.currentUploadedByteValues = {};
this.currentFiles = {};
this.totalBytesUploaded = 0;
this.fire("alluploadscancelled");
this._currentState = UploaderQueue.STOPPED;
}
}
};
UploaderQueue.ATTRS = {
simUploads: 2,
errorAction: {
value: "continue",
validator: function (val) {
return (
val === UploaderQueue.CONTINUE ||
val === UploaderQueue.STOP ||
val === UploaderQueue.RESTART_ASAP ||
val === UploaderQueue.RESTART_AFTER
);
}
},
bytesUploaded: 0,
bytesTotal: 0,
fileList: [],
fileFieldName: "Filedata",
uploadURL: '',
uploadHeaders:{},
withCredentials: true,
perFileParameters: {},
retryCount: 3
}