esbuild/eslint installer, eslint setup

Minor code cleanup
This commit is contained in:
2025-03-07 13:57:19 +09:00
parent b5d1c9d8c8
commit d95160cfe1
6 changed files with 1632 additions and 1 deletions

View File

@@ -0,0 +1,532 @@
/* AJAX File upload simple */
/* jshint esversion: 6 */
/* global errorCatch */
/**
* CUSTOM SUB CALL FUNCTIONS as passsd on in init call
* fileChange(target_file, target_router)
* fileBeforeUpload(target_file, target_router)
* fileUploaded(target_file, target_router, control_data)
* fileUploadError(target_file, target_router, control_data)
*/
var AFUS_strings = {};
/**
* [5-A] show progress circle
* Hides the submit button
* If a "confirm" button is present hides this one too
* !TODO! call external function for additional checks
* and move eg confirm buttons check there
* @param {String} target_file prefix for elements
*/
function showProgress(target_file)
{
// console.log('Show progress circle');
// hide the upload button itself so we don't press twice
$('#' + target_file + '-submit').hide();
if ($('#mask-' + target_file).length > 0) {
$('#mask-' + target_file).hide();
} else {
$('#' + target_file + '-file').hide();
}
// check if we have button "confirm" and disable it
if ($('#confirm').length > 0) {
$('#confirm').prop('disabled', true);
}
}
/**
* [7-C] hide progress circle
* Show submit button again
* If a "confirm" button is present show this one too
* !TODO! call external function for additional checks
* and move eg confirm buttons check there
* @param {String} target_file prefix for elements
*/
function hideProgress(target_file)
{
// console.log('Hide progress circle');
// show the upload button again after upload
$('#' + target_file + '-submit').show();
if ($('#' + target_file + '-submit-div').length > 0) {
$('#' + target_file + '-submit-div').show();
}
if ($('#mask-' + target_file).length > 0) {
$('#mask-' + target_file).show();
// on mask hide button after upload
$('#' + target_file + '-submit').hide();
if ($('#' + target_file + '-submit-div').length > 0) {
$('#' + target_file + '-submit-div').hide();
}
} else {
$('#' + target_file + '-file').show();
}
// check if we have button "confirm" and disable it
if ($('#confirm').length > 0) {
$('#confirm').prop('disabled', false);
}
}
/**
* [7-B] upload error
* prints upload error messages into the status field
* @param {String} target_file prefix for elements
* @param {Array} error_message error message, if not set standard error is shown
* @param {Boolean} is_error if set true, then add error message class
*/
function uploadError(target_file, error_message, is_error)
{
// set if empty
if (error_message.length == 0) {
error_message.push('[JS Upload Lib] Upload Error');
}
// write error message
document.getElementById(target_file + '-upload-status').innerHTML = error_message.join('<br>');
// add error style to upload status
if (is_error === true) {
$('#' + target_file + '-upload-status').addClass('SubError');
} else {
$('#' + target_file + '-upload-status').removeClass('SubError');
}
}
/**
* [3] pass through event
* Checks if a mask- element is present and then attaches
* the passthrough event to the internal files button
* checks if fileChange variable is a function and calls it
* @param {String} target_file Prefix for elements
* @param {String} target_router Router target name
* @param {Boolean} auto_submit If set true will pass by submit button click
* and automatically upload
* @param {Function} fileChange A function with two string parameters
* target_file, target_router
* Is called on change of -file entry
*/
function passThroughEvent(target_file, target_router, auto_submit, fileChange)
{
console.log('[AJAX Uploader: %s] Element exists: %s',target_file, $('#mask-' + target_file + '-file').length);
if ($('#mask-' + target_file + '-file').length > 0) {
// hide the other elements
// hide submit button until file is selected
$('#' + target_file + '-file, #mask-' + target_file + '-file, #' + target_file + '-submit, #' + target_file + '-submit-div').hide();
// init wipe upload status
$('#' + target_file + '-upload-status').html('');
// write file name to upload status
// show submit button
$('#' + target_file + '-file').change(function() {
$('#mask-' + target_file + '-file').val($('#' + target_file + '-file').val());
$('#' + target_file + '-upload-status').html(document.getElementById(target_file + '-file').files[0].name);
$('#' + target_file + '-upload-status').show();
if (auto_submit === false) {
$('#' + target_file + '-submit').show();
if ($('#' + target_file + '-submit-div').length > 0) {
$('#' + target_file + '-submit-div').show();
}
}
// file upload changed function
if (typeof fileChange === 'function') {
fileChange(target_file, target_router);
}
// if auto submit flaged
console.log('AUTO SUBMIT: %s', auto_submit);
if (auto_submit === true) {
document.getElementById(target_file + '-submit').click();
}
});
$('#mask-' + target_file + '-file').click(function() {
var $elm = $('#' + target_file + '-file');
if (document.createEvent) {
var e = document.createEvent('MouseEvents');
e.initEvent('click', true, true );
$elm.get(0).dispatchEvent(e);
} else {
$elm.trigger('click');
}
return false;
});
}
}
/**
* [7-A] final step after upload
* The last action to be called, fills all the hidden values
* - uid
* - file_name
* - file_size
* Inserts thumbnail if url exists
* Adds uploaded file name and file size if flags show_name/show_size are set
* The function checks for "fileUploaded" and if it exists
* it will be called with the "other_data" object
* @param {String} target_file Prefix for elements
* @param {String} target_router Target router name
* @param {Object} file_info Object with all the additional data returned from AJAX
* @param {Object} data Full Object set (including file_info)
* @param {Function} fileUploaded A function with two string and one object parameters
* target_file, target_router, data
* Is called after the upload has finished successfully
*/
function postUpload(target_file, target_router, file_info, data, fileUploaded)
{
console.log('[AJAX Uploader: %s] Post upload: File: %s, URL: %s, Name: %s, Size: %s', target_file, file_info.file_uid, file_info.file_url, file_info.file_name, file_info.file_size);
// reset upload file, etc
document.getElementById(target_file + '-file').value = '';
// safari issues?
document.getElementById(target_file + '-file').type = '';
document.getElementById(target_file + '-file').type = 'file';
// set internal uid
document.getElementById(target_file + '-uid').value = file_info.file_uid;
// name & size
document.getElementById(target_file + '-file_name').value = file_info.file_name;
document.getElementById(target_file + '-file_size').value = file_info.file_size_raw;
// set thumb here, if we haveone
// file_info also holds the output flags show_name, show_size if we want to show additional info
// add remove file from here too (submits with uid to remove tmp uploaded file)
// clear any previous content
document.getElementById(target_file + '-uploaded').innerHTML = '';
var element;
// set base CSS prefix if set or use standard one
var base_css = file_info.css ? file_info.css : 'image-upload';
if (file_info.file_url) {
element = document.createElement('img');
element.src = file_info.file_url;
element.id = target_file + '-input-thumbnail';
element.className = base_css + '-img';
document.getElementById(target_file + '-uploaded').appendChild(element);
$('#' + target_file + '-uploaded').show();
}
// if we have name/size addition
if (file_info.show_name || file_info.show_size) {
element = document.createElement('div');
element.className = base_css + '-text';
if (file_info.show_name) {
element.innerHTML = file_info.file_name;
}
if (file_info.show_size) {
element.innerHTML += ' (' + file_info.file_size + ')';
}
document.getElementById(target_file + '-uploaded').appendChild(element);
$('#' + target_file + '-uploaded').show();
}
if (typeof fileUploaded === 'function') {
fileUploaded(target_file, target_router, data);
}
}
/**
* [2] Function that will allow us to know if Ajax uploads are supported
* @return {Boolean} true on "ajax file uploaded supported", false on not possible
*/
function supportAjaxUploadWithProgress()
{
return supportFileAPI() && supportAjaxUploadProgressEvents() && supportFormData();
// Is the File API supported?
function supportFileAPI()
{
var fi = document.createElement('INPUT');
fi.type = 'file';
return 'files' in fi;
}
// Are progress events supported?
function supportAjaxUploadProgressEvents()
{
var xhr = new XMLHttpRequest();
return !! (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
}
// Is FormData supported?
function supportFormData()
{
return !! window.FormData;
}
}
/**
* [1] this has to be called to start the uploader
* checks if ajax upload is supported and if yes
* checks if we need to set the pass through click event
* then calls the final init that loads the form.submit catcher
* @param {String} target_file prefix for the element for the file upload
* @param {String} target_form the master form in which this element sits
* @param {String} [target_router=''] value of the action _POST variable, if not set or
* if empty use "fileUpload"
* NOTE: default = '' has been removed to work with IE11
* @param {String} [target_action=''] override the target_form action field
* NOTE: default = '' has been removed to work with IE11
* @param {Object} [form_parameters={}] Key/Value list for additional parameters to add to the form submit.
* Added BEFORE fileBeforeUpload parameters
* @param {Boolean} [auto_submit=false] if we override the submit button
* and directly upload
* NOTE: default = false has been removed to work with IE11
* @param {Function} [fileChange=''] Function run on change of -file element entry
* Parameters are target_file, target_router
* NOTE: default = false has been removed to work with IE11
* @param {Function} [fileBeforeUpload=''] Function called before upload starts
* Parameters are target_file, target_router
* NOTE: default = false has been removed to work with IE11
* @param {Function} [fileUploaded=''] Function called after upload has successfully finished
* Parameters are target_file, target_router, data (object returned from upload function call)
* NOTE: default = false has been removed to work with IE11
* @param {Function} [fileUploadError=''] Function called after upload has failed
* Parameters are target_file, target_router, data (object returned from upload function call)
* NOTE: default = false has been removed to work with IE11
*/
function initAjaxUploader(target_file, target_form, target_router, target_action, form_parameters, auto_submit, fileChange, fileBeforeUpload, fileUploaded, fileUploadError)
{
// Actually confirm support
if (supportAjaxUploadWithProgress()) {
console.log('[AJAX Uploader: %s] init [%s]', target_file, target_router);
if (document.getElementById(target_file + '-submit') !== null) {
// add click event for the submit buttons to set which one submitted the file
document.getElementById(target_file + '-submit').addEventListener('click', function() {
this.form.submitted = this.id;
});
// set pass through events
passThroughEvent(target_file, target_router, auto_submit, fileChange);
// Ajax uploads are supported!
// Init the Ajax form submission
// pass on the target_file and the master form name
initFullFormAjaxUpload(target_file, target_form, target_router, target_action, form_parameters, fileBeforeUpload, fileUploaded, fileUploadError);
} else {
console.log('[AJAX Uploader: %s] Element not found for init', target_file);
}
} else {
console.log('[AJAX Uploader: %s] failed', target_file);
}
}
/**
* [4] MAIN CALL for upload
* Creates the main ajax send request if a submit on the main form is detected
* all the parameters are passed on from the init function
* The function will throw an error of not action (target) can be found
* @param {String} target_file prefix for the element for the file upload
* @param {String} target_form the master form in which this element sits
* @param {String} target_router value of the action _POST variable
* @param {String} target_action override the target_form action field (target file)
* @param {Object} form_parameters additional parameters added to the form submit
* @param {Function} fileBeforeUpload Function with two string parameters
* target_file, target_router
* Is called on submit before upload starts
* @param {Function} fileUploaded Is passed through to sendXHRequest
* @param {Function} fileUploadError Is passed through to sendXHRequest
* @return {Boolean} false to not trigger normal form submit
*/
function initFullFormAjaxUpload(target_file, target_form, target_router, target_action, form_parameters, fileBeforeUpload, fileUploaded, fileUploadError)
{
// should check that form exists
// + '-form'
var form = document.getElementById(target_form);
if (!form.getAttribute('action') && !target_action) {
console.log('!!!!! MISSING FORM ACTION ENTRY');
throw new Error('!!!!! MISSING FORM ACTION ENTRY');
}
form.onsubmit = function()
{
var path = window.location.pathname;
// do we end in .php, we need to remove the name then, we just want the path
if (path.indexOf('.php') != -1) {
// remove trailing filename (all past last / )
path = path.replace(/\w+\.php/, '');
}
if (path.substr(-1) != '/') {
path += '/';
}
// get the form.submitted text (remove -submit) and compare to target_file,
// if different overwrite the target file
var _target_file = form.submitted.split('-')[0];
console.log('[AJAX Uploader: %s] Wanted: %s, Submitted: %s', target_file, _target_file, form.submitted);
if (target_file != _target_file) {
target_file = _target_file;
}
// remove previous highlight if set
$('#' + target_file + '-upload-status').removeClass('SubError');
$('#' + target_file + '-upload-status').show();
// progress highlight
showProgress(target_file);
// console.log('[AJAX Uploader: %s] Start upload', target_file);
// create new form
var formData = new FormData();
// We send the data where the form wanted
var action = form.getAttribute('action');
// in case we have a target action set, we overwirde
if (target_action) {
action = target_action;
}
console.log('[AJAX Uploader: %s] ACTION: %s, PATH: %s', target_file, action, path);
// add action
if (!target_router) {
target_router = 'fileUpload';
}
formData.append('action', target_router);
formData.append('uploadName', target_file + '-file');
// add file only (first file found) with target file name
formData.append(target_file + '-file', document.getElementById(target_file + '-file').files[0]);
// append file uid if exists
formData.append(target_file + '-uid', $('#' + target_file + '-uid').val());
// add additional ones
for (const [key, value] of Object.entries(form_parameters)) {
formData.append(key, value);
}
// external data gets added
if (typeof fileBeforeUpload === 'function') {
for (const [key, value] of Object.entries(fileBeforeUpload(target_file, target_router))) {
formData.append(key, value);
}
}
console.log('[AJAX Uploader: %s] Send data to: %s, with path: %s', target_file, action, path);
// run translation check, must have at least two basic strings set
// if they are not set, set default values here
/*if (!Object.prototype.hasOwnProperty.call(AFUS_strings, 'upload_start')) {
AFUS_strings.upload_start = 'Upload start';
}
if (!Object.prototype.hasOwnProperty.call(AFUS_strings, 'upload_finished')) {
AFUS_strings.upload_finished = 'Upload finished';
}*/
// debugger;
// Code common to both variants
sendXHRequest(target_file, target_router, formData, path + action, fileUploaded, fileUploadError);
console.log('[AJAX Uploader: %s] Data sent to: %s', target_file, action);
// Avoid normal form submission
return false;
};
}
/**
* [5-B]
* Once the FormData instance is ready and we know
* where to send the data, the data gets submitted
* it adds event listeners for start/progress/load and general ready state change
* then it sends the data
* each event listener is called during the stages
* - start: onloadstartHandler
* - progress: onprogressHandler
* - end: onloadHandler
* - finish: onreadystatechangeHandler
* Note: on xhr.onerror function is called if an error happens
* and just calls the xhr.send again
* there are some issues on firefox that can trigger this
* @param {String} target_file Element name prefix
* @param {String} target_router Target router name
* @param {Object} formData The form data created in the init full function
* @param {String} uri The target uri to where the data should be sent
* @param {Function} fileUploaded Is passed through to onreadystatechangeHandler
* @param {Function} fileUploadError Is passed through to onreadystatechangeHandler
*/
function sendXHRequest(target_file, target_router, formData, uri, fileUploaded, fileUploadError)
{
// Get an XMLHttpRequest instance
var xhr = new XMLHttpRequest();
// Set up events
xhr.upload.addEventListener('loadstart', onloadstartHandler.bind(null, target_file), false);
xhr.upload.addEventListener('progress', onprogressHandler.bind(null, target_file), false);
xhr.upload.addEventListener('load', onloadHandler.bind(null, target_file), false);
xhr.addEventListener('readystatechange', onreadystatechangeHandler.bind(null, target_file, target_router, fileUploaded, fileUploadError), false);
// alternative pass on via target file
// xhr.targetFile = target_file;
// Set up request
xhr.open('POST', uri, true);
// Fire!
xhr.send(formData);
// on error log & try again
xhr.onerror = function() {
console.log('[AJAX Uploader: %s] upload ERROR', target_file);
// try again
xhr.open('POST', uri, true);
xhr.send(formData);
};
console.log('[AJAX Uploader: %s] SEND DATA: %o', target_file, formData);
}
/**
* [6-A] Handle the start of the transmission
* @param {String} target_file element name prefix
*/
function onloadstartHandler(target_file)
{
// console.log('[AJAX Uploader: %s] start uploading', target_file);
// must set dynamic
var div = document.getElementById(target_file + '-upload-status');
div.innerHTML = AFUS_strings.upload_start || 'Upload start';
}
/**
* [6-B] Handle the end of the transmission
* @param {String} target_file element name prefix
*/
function onloadHandler(target_file)
{
// console.log('[AJAX Uploader: %s] finished uploading', target_file);
// must set dynamic
var div = document.getElementById(target_file + '-upload-status');
div.innerHTML = AFUS_strings.upload_finished || 'Upload finished';
}
/**
* [6-C] Handle the progress
* calculates percent and show that in the upload status element
* @param {String} target_file element name prefix
* @param {Event} evt event data for upload progress
* holds file size and bytes transmitted
*/
function onprogressHandler(target_file, evt)
{
// must set dynamic
var div = document.getElementById(target_file + '-upload-status');
var percent = evt.loaded / evt.total * 100;
// console.log('[AJAX Uploader: %s] Uploading: %s', target_file, Math.round(percent));
div.innerHTML = Math.round(percent) + '%';
}
/**
* [6-D] Handle the response from the server
* If ready state is 4 it will call the final post upload function on status success
* if status is other it will call the upload error function
* on all other statii it currently only prints a debug log message
* @param {String} target_file Element name prefix
* @param {String} target_router Target router name
* @param {Function} fileUploaded Is passed through to postUpload
* @param {Function} fileUploadError Is called on error
* @param {Event} evt event data for return data and ready state info
*/
function onreadystatechangeHandler(target_file, target_router, fileUploaded, fileUploadError, evt)
{
var status, readyState, responseText, responseData;
try {
readyState = evt.target.readyState;
responseText = evt.target.responseText;
status = evt.target.status;
} catch(e) {
errorCatch(e);
return;
}
if (readyState == 4 && status == '200' && responseText) {
responseData = JSON.parse(responseText);
// must set dynamic
console.log('[AJAX Uploader: %s] Uploader response: %s -> %o', target_file, responseData.status, responseData);
uploadError(target_file, responseData.content.msg, false);
// run post uploader
if (responseData.status == 'success') {
postUpload(target_file, target_router, {
file_uid: responseData.content.file_uid,
file_url: responseData.content.file_url,
file_size: responseData.content.file_size,
file_size_raw: responseData.content.file_size_raw,
file_name: responseData.content.file_name,
show_name: responseData.content.show_name,
show_size: responseData.content.show_size,
css: responseData.content.css
}, responseData.content, fileUploaded);
} else {
// uploadError(target_file, responseData.content.msg, true);
if (typeof fileUploadError === 'function') {
fileUploadError(target_file, target_router, responseData.content);
}
}
hideProgress(target_file);
} else {
console.log('[AJAX Uploader: %s] ReadyState: %s, status: %s, Text: %o', target_file, readyState, status, responseText);
}
}