primo commit
This commit is contained in:
627
media/regularlabs/js/regular.js
Normal file
627
media/regularlabs/js/regular.js
Normal file
@ -0,0 +1,627 @@
|
||||
/**
|
||||
* @package Regular.js
|
||||
* @description A light and simple JavaScript Library
|
||||
*
|
||||
* @author Peter van Westen <info@regularlabs.com>
|
||||
* @link https://github.com/regularlabs/regularjs
|
||||
* @copyright Copyright © 2024 Regular Labs - All Rights Reserved
|
||||
* @license https://github.com/regularlabs/regularjs/blob/master/LICENCE MIT
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (typeof window.Regular === 'undefined'
|
||||
|| typeof Regular.version === 'undefined'
|
||||
|| Regular.version < 1.5) {
|
||||
|
||||
window.Regular = new function() {
|
||||
/**
|
||||
*
|
||||
* PUBLIC PROPERTIES
|
||||
*
|
||||
*/
|
||||
|
||||
this.version = 1.5;
|
||||
|
||||
/**
|
||||
*
|
||||
* PUBLIC METHODS
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets a global alias for the Regular class.
|
||||
*
|
||||
* @param word A string (character or word) representing the alias for the Regular class.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
this.alias = function(word) {
|
||||
if (typeof window[word] !== 'undefined') {
|
||||
console.error(`Cannot set '${word}' as an alias of Regular, as it already exists.`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
window[word] = $;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a boolean based on whether the element contains one or more of the given class names.
|
||||
*
|
||||
* @param selector A CSS selector string or a HTMLElement object.
|
||||
* @param classes A string or array of class names.
|
||||
* @param matchAll Optional boolean whether the element should have all given classes (true) or at least one (false).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
this.hasClasses = function(selector, classes, matchAll = true) {
|
||||
if ( ! selector) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelector(selector)
|
||||
: selector;
|
||||
|
||||
if ( ! element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof classes === 'string') {
|
||||
classes = classes.split(' ');
|
||||
}
|
||||
|
||||
let hasClass = false;
|
||||
|
||||
for (const clss of classes) {
|
||||
hasClass = element.classList.contains(clss);
|
||||
|
||||
if (matchAll && ! hasClass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! matchAll && hasClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasClass;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds given class name(s) to the element(s).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param classes A string or array of class names.
|
||||
*/
|
||||
this.addClasses = function(selector, classes) {
|
||||
doClasses('add', selector, classes);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes given class name(s) from the element(s).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param classes A string or array of class names.
|
||||
*/
|
||||
this.removeClasses = function(selector, classes) {
|
||||
doClasses('remove', selector, classes);
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles given class name(s) of the element(s).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param classes A string or array of class names.
|
||||
* @param force An optional boolean value that forces the class to be added or removed.
|
||||
*/
|
||||
this.toggleClasses = function(selector, classes, force) {
|
||||
switch (force) {
|
||||
case true:
|
||||
doClasses('add', selector, classes);
|
||||
break;
|
||||
|
||||
case false:
|
||||
doClasses('remove', selector, classes);
|
||||
break;
|
||||
|
||||
default:
|
||||
doClasses('toggle', selector, classes);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Makes the given element(s) visible (changes visibility and display attributes).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
*/
|
||||
this.makeVisible = function(selector) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
if ('forEach' in element) {
|
||||
element.forEach(subElement => $.makeVisible(subElement));
|
||||
return;
|
||||
}
|
||||
|
||||
let computedDisplay = getComputedStyle(element, 'display');
|
||||
|
||||
if ( ! ('origDisplay' in element)) {
|
||||
element.origDisplay = computedDisplay === 'none'
|
||||
? getDefaultComputedStyle(element, 'display')
|
||||
: computedDisplay;
|
||||
}
|
||||
|
||||
if (computedDisplay === 'none') {
|
||||
element.style.display = ('origDisplay' in element) ? element.origDisplay : '';
|
||||
}
|
||||
|
||||
let elementType = element.nodeName.toLowerCase();
|
||||
|
||||
switch (elementType) {
|
||||
case 'tr':
|
||||
elementType = 'table-row';
|
||||
break;
|
||||
case 'td':
|
||||
case 'th':
|
||||
elementType = 'table-cell';
|
||||
break;
|
||||
case 'caption':
|
||||
elementType = 'table-caption';
|
||||
break;
|
||||
case 'col':
|
||||
elementType = 'table-column';
|
||||
break;
|
||||
case 'colgroup':
|
||||
elementType = 'table-column-group';
|
||||
break;
|
||||
case 'table':
|
||||
elementType = 'table';
|
||||
break;
|
||||
case 'thead':
|
||||
elementType = 'table-header-group';
|
||||
break;
|
||||
case 'tbody':
|
||||
elementType = 'table-row-group';
|
||||
break;
|
||||
case 'tfoot':
|
||||
elementType = 'table-footer-group';
|
||||
break;
|
||||
default:
|
||||
elementType = 'block';
|
||||
break;
|
||||
}
|
||||
|
||||
element.style.display = elementType;
|
||||
element.style.visibility = 'visible';
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the given element(s) (makes visible and changes opacity attribute).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
*/
|
||||
this.show = function(selector) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
if ('forEach' in element) {
|
||||
element.forEach(subElement => $.show(subElement));
|
||||
return;
|
||||
}
|
||||
|
||||
this.makeVisible(element);
|
||||
|
||||
element.style.opacity = 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the given element(s) (changes opacity and display attributes).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
*/
|
||||
this.hide = function(selector) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
if ('forEach' in element) {
|
||||
element.forEach(subElement => $.hide(subElement));
|
||||
return;
|
||||
}
|
||||
|
||||
const computedDisplay = getComputedStyle(element, 'display');
|
||||
|
||||
if (computedDisplay !== 'none' && ! ('origDisplay' in element)) {
|
||||
element.origDisplay = computedDisplay;
|
||||
}
|
||||
|
||||
element.style.display = 'none';
|
||||
element.style.visibility = 'hidden';
|
||||
element.style.opacity = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows or hides the given element(s).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param force An optional boolean value that forces the class to be added or removed.
|
||||
*/
|
||||
this.toggle = function(selector, force) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (force) {
|
||||
case true:
|
||||
$.show(selector);
|
||||
break;
|
||||
|
||||
case false:
|
||||
$.hide(selector);
|
||||
break;
|
||||
|
||||
default:
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
if ('forEach' in element) {
|
||||
element.forEach(subElement => $.toggle(subElement));
|
||||
return;
|
||||
}
|
||||
|
||||
element.style.display === 'none' ? $.show(selector) : $.hide(selector);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fades in the given element(s).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param duration Optional duration of the effect in milliseconds.
|
||||
* @param oncomplete Optional callback function to execute when effect is completed.
|
||||
*/
|
||||
this.fadeIn = function(selector, duration = 250, oncomplete) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
this.makeVisible(element);
|
||||
|
||||
$.fadeTo(
|
||||
element,
|
||||
1,
|
||||
duration,
|
||||
() => {
|
||||
$.show(element);
|
||||
if (oncomplete) {
|
||||
oncomplete.call(element);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fades out the given element(s).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param duration Optional duration of the effect in milliseconds.
|
||||
* @param oncomplete Optional callback function to execute when effect is completed.
|
||||
*/
|
||||
this.fadeOut = function(selector, duration = 250, oncomplete) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
$.fadeTo(
|
||||
element,
|
||||
0,
|
||||
duration,
|
||||
() => {
|
||||
$.hide(element);
|
||||
if (oncomplete) {
|
||||
oncomplete.call(element);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fades out the given element(s).
|
||||
*
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param opacity Opacity Value to fade to
|
||||
* @param duration Optional duration of the effect in milliseconds.
|
||||
* @param oncomplete Optional callback function to execute when effect is completed.
|
||||
*/
|
||||
this.fadeTo = function(selector, opacity, duration = 250, oncomplete) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
if ('forEach' in element) {
|
||||
element.forEach(subElement => $.fadeTo(subElement, opacity, duration));
|
||||
return;
|
||||
}
|
||||
|
||||
const wait = 50; // amount of time between steps
|
||||
const nr_of_steps = duration / wait;
|
||||
const change = 1 / nr_of_steps; // time to wait before next step
|
||||
|
||||
element.style.opacity = getComputedStyle(element, 'opacity');
|
||||
|
||||
if (opacity === element.style.opacity) {
|
||||
element.setAttribute('data-fading', '');
|
||||
|
||||
if (oncomplete) {
|
||||
oncomplete.call(element);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.makeVisible(element);
|
||||
|
||||
const direction = opacity > element.style.opacity ? 'in' : 'out';
|
||||
|
||||
element.setAttribute('data-fading', direction);
|
||||
|
||||
(function fade() {
|
||||
if (element.getAttribute('data-fading')
|
||||
&& element.getAttribute('data-fading') !== direction
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const new_opacity = direction === 'out'
|
||||
? parseFloat(element.style.opacity) - change
|
||||
: parseFloat(element.style.opacity) + change;
|
||||
|
||||
if ((direction === 'in' && new_opacity >= opacity)
|
||||
|| (direction === 'out' && new_opacity <= opacity)
|
||||
) {
|
||||
element.style.opacity = opacity;
|
||||
|
||||
element.setAttribute('data-fading', '');
|
||||
|
||||
if (oncomplete) {
|
||||
oncomplete.call(element);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
element.style.opacity = new_opacity;
|
||||
|
||||
setTimeout(() => {
|
||||
fade.call();
|
||||
}, wait);
|
||||
})();
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs a function when the document is loaded (on ready state).
|
||||
*
|
||||
* @param func Callback function to execute when document is ready.
|
||||
*/
|
||||
this.onReady = function(func) {
|
||||
document.addEventListener('DOMContentLoaded', func);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a string with HTML code to 'DOM' elements.
|
||||
*
|
||||
* @param html String with HTML code.
|
||||
*
|
||||
* @return element
|
||||
*/
|
||||
this.createElementFromHTML = function(html) {
|
||||
return document.createRange().createContextualFragment(html);
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads a url with optional POST data and optionally calls a function on success or fail.
|
||||
*
|
||||
* @param url String containing the url to load.
|
||||
* @param data Optional string representing the POST data to send along.
|
||||
* @param success Optional callback function to execute when the url loads successfully (status 200).
|
||||
* @param fail Optional callback function to execute when the url fails to load.
|
||||
*/
|
||||
this.loadUrl = function(url, data, success, fail) {
|
||||
const request = new XMLHttpRequest();
|
||||
|
||||
request.open('POST', url, true);
|
||||
|
||||
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if (this.readyState !== 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.status === 200) {
|
||||
success && success.call(null, this.responseText, this.status, this);
|
||||
return;
|
||||
}
|
||||
|
||||
fail && fail.call(null, this.responseText, this.status, this);
|
||||
};
|
||||
|
||||
|
||||
request.send(this.toUrlQueryString(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a data object (key, value) to a serialized query string.
|
||||
*
|
||||
* @param data The object with the data to serialize.
|
||||
* @param prefix An Optional prefix.
|
||||
*/
|
||||
this.toUrlQueryString = function(data, prefix) {
|
||||
if (typeof data !== 'object') {
|
||||
return data;
|
||||
}
|
||||
|
||||
const parts = [];
|
||||
|
||||
if ( ! (Symbol.iterator in Object(data))) {
|
||||
data = Object.entries(data);
|
||||
}
|
||||
|
||||
for (let i in data) {
|
||||
let value = data[i];
|
||||
let name = '';
|
||||
|
||||
if (value instanceof Array) {
|
||||
[name, value] = value;
|
||||
}
|
||||
|
||||
let key = name ? (prefix ? `${prefix}[${name}]` : name) : prefix;
|
||||
|
||||
if ( ! key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value !== null && typeof value === 'object') {
|
||||
if (value instanceof Array) {
|
||||
key += '[]';
|
||||
}
|
||||
|
||||
parts.push(this.toUrlQueryString(value, key));
|
||||
continue;
|
||||
}
|
||||
|
||||
parts.push(`${key}=${value}`);
|
||||
}
|
||||
|
||||
return parts.join('&');
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* ALIASES
|
||||
*
|
||||
*/
|
||||
|
||||
this.as = this.alias;
|
||||
this.hasClass = this.hasClasses;
|
||||
this.addClass = this.addClasses;
|
||||
this.removeClass = this.removeClasses;
|
||||
this.toggleClass = this.toggleClasses;
|
||||
|
||||
/**
|
||||
*
|
||||
* PRIVATE FUNCTIONS
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Executes an action on the element(s) to add/remove/toggle classes.
|
||||
*
|
||||
* @param action A string that identifies the action: add|remove|toggle.
|
||||
* @param selector A CSS selector string, a HTMLElement object or a collection of HTMLElement objects.
|
||||
* @param classes A string or array of class names.
|
||||
*/
|
||||
const doClasses = function(action, selector, classes) {
|
||||
if ( ! selector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = typeof selector === 'string'
|
||||
? document.querySelectorAll(selector)
|
||||
: selector;
|
||||
|
||||
if ('forEach' in element) {
|
||||
element.forEach(subElement => doClasses(action, subElement, classes));
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof classes === 'string') {
|
||||
classes = classes.split(' ');
|
||||
}
|
||||
|
||||
element.classList[action](...classes);
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds the computed style of an element.
|
||||
*
|
||||
* @param element A HTMLElement object.
|
||||
* @param property The style property that needs to be returned.
|
||||
*
|
||||
* @returns mixed
|
||||
*/
|
||||
const getComputedStyle = function(element, property) {
|
||||
if ( ! element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return window.getComputedStyle(element).getPropertyValue(property);
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds the default computed style of an element by its type.
|
||||
*
|
||||
* @param element A HTMLElement object.
|
||||
* @param property The style property that needs to be returned.
|
||||
*
|
||||
* @returns mixed
|
||||
*/
|
||||
const getDefaultComputedStyle = function(element, property) {
|
||||
if ( ! element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const defaultElement = document.createElement(element.nodeName);
|
||||
|
||||
document.body.append(defaultElement);
|
||||
let propertyValue = window.getComputedStyle(defaultElement).getPropertyValue(property);
|
||||
defaultElement.remove();
|
||||
|
||||
return propertyValue;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* PRIVATE VARIABLES
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param $ internal shorthand for the 'this' keyword.
|
||||
*/
|
||||
const $ = this;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user