File: D:/HostingSpaces/marisrental/boldt.tech/resources/js/kms/attributes/HTML5Uploader.js
/**
* HTML 5 file uploads that report progress while uploading
*/
class HTML5Uploader {
constructor(uploadUrl, maxPostSize, maxUploadSize, translations)
{
this.constructedSuccessfully = false;
if(!uploadUrl) {
console.error('Did not get a valid upload url. Not initializing Html5Uploader');
return;
}
this.uploadUrl = uploadUrl;
if(!maxPostSize) {
console.error('Did not get the maximum post size. Not initializing Html5Uploader');
return;
}
this.maxPostSize = maxPostSize;
if(!maxUploadSize) {
console.error('Did not get the maximum upload size. Not initializing Html5Uploader');
return;
}
this.maxUploadSize = maxUploadSize;
if(!translations) {
console.error('Did not get the translations. Not initializing Html5Uploader');
return;
}
this.translations = JSON.parse(translations);
this.eventMap = {};
if(!this.isSupported()) {
console.warn('HTML 5 file upload is not supported. Not initializing Html5Uploader');
return;
}
this.constructedSuccessfully = true;
}
/**
* Returns true if the browser supports HTML 5 uploading. false if not
* @return {boolean}
*/
isSupported()
{
return window.FormData !== undefined;
}
/**
* @param {File} file
*/
receiveFile(file)
{
if(!this.isSupported()) {
console.error('HTML 5 file upload is not supported. Not uploading file.');
return;
}
}
/**
* @param {File} file
* @param {string} extraData
*/
upload(file, extraData)
{
if(!this.verifyFileSizeOrShowError(file)) return;
if(this.constructedSuccessfully === false) return;
let self = this;
let formData = new FormData();
formData.append(file.name, file);
formData.append('extraData', extraData);
let request = new XMLHttpRequest();
let uploadRequest = request.upload;
uploadRequest.addEventListener("progress", (function(file, extraData) {
return function(event) {
self.updateProgress(file, event, extraData);
};
})(file, extraData));
request.addEventListener("loadstart", (function(file, extraData) {
return function(event) {
self.uploadStart(file, extraData);
};
})(file, extraData));
request.addEventListener("error", (function(file, extraData) {
return function(event) {
self.uploadFailed(file, 'general error', extraData);
};
})(file, extraData));
request.addEventListener("abort", (function(file, extraData) {
return function(event) {
self.uploadCanceled(file, extraData);
};
})(file, extraData));
request.onreadystatechange = (function(file, extraData) {
return function() {
if(request.readyState === 4) {
if(request.status === 200) {
self.uploadComplete(file, request.responseText, extraData);
} else {
self.uploadFailed(file, request.responseText, extraData)
}
}
}
})(file, extraData);
request.open('POST', this.uploadUrl);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
let csfrTokenContainer = document.querySelector('meta[name="csrf-token"]');
if(!csfrTokenContainer) {
console.error('Not uploading file since not csrf-token could be found in a meta tag with name "csrf-token". Please add it');
return;
}
request.setRequestHeader('X-CSRF-TOKEN', csfrTokenContainer.getAttribute('content'));
request.send(formData);
}
/**
* Returns true if the file size is lower then the maximum allowed server upload size.
* Or shows an alert and returns false if it is bigger then the allowed server upload size.
*
* @param {File} file
* @return {boolean}
*/
verifyFileSizeOrShowError(file) {
if(file.size > this.maxPostSize || file.size > this.maxUploadSize) {
//Calculate file size and max file size to megabytes
let fileSizeInMegaBytes = file.size / (1024 * 1024);
let maxSizeInMegaBytes = ((this.maxUploadSize > this.maxPostSize) ? this.maxPostSize : this.maxUploadSize) / (1024 * 1024);
//Round this sizes to 2 decimals
fileSizeInMegaBytes = Math.round(fileSizeInMegaBytes * 100) / 100;
maxSizeInMegaBytes = Math.round(maxSizeInMegaBytes * 100) / 100;
//Gather translation texts
let introText = this.translations.file_to_big;
let maxFileSizeUploadTranslation = this.translations.max_file_size_upload;
let fileSizeUploadTranslation = this.translations.file_size_upload;
//Assemble alert message
let alertText = introText+'\n\n'
+maxFileSizeUploadTranslation+maxSizeInMegaBytes+' MB\n'
+fileSizeUploadTranslation+fileSizeInMegaBytes+' MB\n';
//Show alert message and return false
alert(alertText);
return false;
}
//File size is fine. Return true
return true;
}
updateProgress (file, event, extraData) {
if (event.lengthComputable) {
let percentComplete = Math.ceil(event.loaded / event.total * 100);
this.triggerEvent('updateProgress', [file, percentComplete, extraData]);
} else {
// Unable to compute progress information since the total size is unknown
this.triggerEvent('updateProgress', [file, null, extraData]);
}
}
uploadStart(file, extraData)
{
this.triggerEvent('uploadStart', [ file, extraData ]);
}
uploadComplete(file, responseText, extraData) {
this.triggerEvent('uploadComplete', [ file, responseText, extraData ]);
}
uploadFailed(file, extraData) {
this.triggerEvent('uploadFailed', [ file, extraData ]);
}
uploadCanceled(file, extraData) {
this.triggerEvent('uploadCanceled', [ file, extraData ]);
}
/**
* Registers a event to a callback and returns the a reference to the event handler for that specific event
*
* @param event (string)
* @param callback (callable)
*/
on(event, callback)
{
if(this.constructedSuccessfully === false) return;
if(!this.eventMap.hasOwnProperty(event)) this.eventMap[event] = [];
return this.eventMap[event].push(callback);
}
/**
* Call event callbacks
*
* @param event (string)
* @param eventArgs (array) an array of arguments to pass to the callback
*/
triggerEvent(event, eventArgs) {
if(!this.eventMap.hasOwnProperty(event)) return;
let nEvents = this.eventMap[event].length;
for(let index = 0; index < nEvents; index++)
{
let callback = this.eventMap[event][index];
if(eventArgs && eventArgs.length > 0) {
callback.apply(this, eventArgs)
} else {
callback.call(this);
}
}
}
}