RoutesMaker/Public/ecma/Utils/Utils.ecma.js

145 lines
4.3 KiB
JavaScript

"use strict";
import {Check} from "./Check.ecma.js";
/**
* @callback utils_preload_callback
* @param {?HTMLElement} item
* @param {!boolean} asynchronous
* @param {!boolean} ok
* @returns {void}
*/
/**
* @callback utils_execute_callback
* @param {...any} [paramenters]
* @returns {any|null}
*/
/**
* @class
* @constructor
* @returns {void}
* @access public
* @static
*/
export const Utils = (function(){
/**
* @constructs Utils
* @returns {void}
* @access private
* @static
*/
const Utils = function(){};
/**
* @param {!(string|HTMLElement)} selector
* @param {!utils_preload_callback} callback
* @param {!(Document|HTMLElement)} [root = document]
* @param {!number} [timeout = 2000]
* @returns {void}
* @access public
* @static
*/
Utils.preload = (selector, callback, root = document, timeout = 2000) => {
if(!selector)
callback(null, false, false);
else if(Check.is_html_object(selector))
callback(selector, false, true);
else if(Check.is_string(selector) && (selector = selector.trim())){
/** @type {HTMLElement|null} */
let item = null;
try{
if(item = root.querySelector(selector)){
callback(item, false, true);
return;
};
}catch(exception){
callback(null, false, false);
return;
};
/** @type {number} */
const date = Date.now();
/** @type {number} */
let interval = setInterval(() => {
if(item = root.querySelector(selector)){
clearInterval(interval);
callback(item, true, true);
}else if(Date.now() - date > timeout){
clearInterval(interval);
callback(null, false, true);
};
}, 100);
}else
callback(null, false, false);
};
/**
* @param {!utils_execute_callback} callback
* @param {...any} [parameters]
* @returns {any|null}
* @access public
* @static
*/
Utils.execute = (callback, ...parameters) => Check.is_function(callback) ? callback(...parameters) : null;
/**
* @param {!(string|HTMLElement)} selector
* @param {!Object.<string, any|null>} attributes
* @param {!(HTMLElement|Document)} [position = document]
* @returns {void}
* @access public
* @static
*/
Utils.set_attributes = (selector, attributes, position = document) => {
(Check.is_string(selector) ? position.querySelectorAll(selector) : [selector]).forEach(item => {
for(const key in attributes){
if(/^on_?/i.test(key))
item.addEventListener(
key.substring(2).replace(/[^a-z]+/g, "").toLowerCase(),
event => Utils.execute(attributes[key], item, event)
);
else
item.setAttribute(key.replace(/_|([A-Z])/g, (_, character) => {
return character ? "-" + character.toLowerCase() : "-";
}), attributes[key]);
};
});
};
/**
* @param {!(string|HTMLElement|Document)} selector
* @param {!Array.<[string, Object.<string, any|null>|null, Array.<any>|null]} items
* @param {!(HTMLElement|Document)} [position = document]
* @returns {Array.<HTMLElement>}
* @access public
* @static
*/
Utils.set_html = (selector, items, position = document) => {
Check.is_string(selector) && (selector = position.querySelector(selector));
return items.map(([tag, attributes, childs]) => {
/** @type {HTMLElement} */
const item = selector.appendChild(document.createElement(tag));
attributes && Utils.set_attributes(item, attributes);
if(!Check.is_null_or_undefined(childs)){
if(Check.is_string(childs))
item.innerHTML = childs;
else if(Check.is_array(childs))
Utils.set_html(item, childs);
};
return item;
});
};
return Utils;
})();