package.src.cache.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mikado Show documentation
Show all versions of mikado Show documentation
Web's fastest template library to build user interfaces.
The newest version!
// COMPILER BLOCK -->
import { MIKADO_NODE_CACHE, PROFILER } from "./config.js";
import { tick } from "./profiler.js";
// <-- COMPILER BLOCK
import { NodeCache } from "./type.js";
import { idl_attributes } from "./factory.js";
const regex_css = /[^;:]+/g;
const regex_class = / +/;
// -------------------------------------------------------------
/**
* @param {Element} node
* @param {string|number} text
*/
export function setText(node, text){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let child, tmp;
if(cache){
tmp = cache._t;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(tmp !== text){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.text");
cache._t = text;
cache._h = null;
child = node.firstChild;
if(child /*(node.nodeType === 3 && (child = node)) || (child = node.firstChild)*/){
child.nodeValue = /** @type {string} */ (text);
}
else{
node.appendChild(document.createTextNode(text));
//node.textContent = text;
}
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {Element|Node} node
* @return {string}
*/
export function getText(node){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let child, tmp;
if(cache){
tmp = cache._t;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof tmp !== "string"){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.text");
child = node.firstChild;
cache._t = tmp = child ? child.nodeValue : "";
// if(child /*(node.nodeType === 3 && (child = node)) || (child = node.firstChild)*/){
//
// cache._t = tmp = child.nodeValue;
// }
// else{
//
// cache._t = tmp = ""; //node.textContent;
// }
}
else{
PROFILER && tick("cache.match");
}
return tmp;
}
// -------------------------------------------------------------
/**
* @param {Element} node
* @param {string|Object} attr
* @param {string|number|boolean=} value
*/
export function setAttribute(node, attr, value){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
if(!cache){
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof attr === "object"){
for(let key in attr){
_setAttribute(node, key, attr[key], cache);
}
}
else{
_setAttribute(node, attr, /** @type {string} */ (value), cache);
}
}
/**
* @param {Element} node
* @param {string} attr
* @param {string|number|boolean} value
* @param {NodeCache=} cache
*/
function _setAttribute(node, attr, value, cache){
if(cache["_a" + attr] !== value){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.attr");
cache["_a" + attr] = value;
// does never apply on factory
if(idl_attributes[attr]){
node[attr] = value;
}
else{
value === false
? node.removeAttribute(attr)
: node.setAttribute(attr, value);
}
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {Element} node
* @param {string|Array} arr
*/
export function removeAttribute(node, arr){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
if(!cache){
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof arr === "object"){
for(let i = 0; i < arr.length; i++){
_removeAttribute(node, arr[i], cache);
}
}
else{
_removeAttribute(node, /** @type {string} */ (arr), cache);
}
}
/**
* @param {Element} node
* @param {string} attr
* @param {NodeCache=} cache
*/
function _removeAttribute(node, attr, cache){
if(cache["_a" + attr] !== false){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.attr");
cache["_a" + attr] = false;
if(idl_attributes[attr]){
node[attr] = false;
}
else{
node.removeAttribute(attr);
}
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {Element} node
* @param {string} attr
* @return {string|null}
*/
export function getAttribute(node, attr){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache["_a" + attr];
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof tmp !== "string"){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.attr");
if(idl_attributes[attr]){
tmp = node[attr];
}
else{
tmp = node.getAttribute(attr);
}
cache["_a" + attr] = tmp;
}
else{
PROFILER && tick("cache.match");
}
return tmp;
}
/**
* @param {Element} node
* @param {string} attr
* @return {boolean}
*/
export function hasAttribute(node, attr){
const tmp = getAttribute(node, attr);
return !!(tmp || tmp === "");
}
// -------------------------------------------------------------
/**
* @param {Element} node
* @param {string|Array} classname
*/
export function setClass(node, classname){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._c;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof classname === "object"){
classname = classname.join(" ");
}
if(tmp !== classname){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.class");
cache._c = classname;
node.className = classname;
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {Element} node
* @return {Array}
*/
export function getClass(node){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._c;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof tmp !== "string"){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.class");
// TODO do not transform back
cache._c = tmp = node.className;
}
else{
PROFILER && tick("cache.match");
}
tmp = tmp.split(regex_class);
return tmp[0] === "" ? [] : tmp;
}
/**
* @param {Element} node
* @return {Object}
*/
function transformClassCache(node){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._c;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(!tmp){
return cache._c = {};
}
if(typeof tmp === "string"){
PROFILER && tick("cache.transform");
const matches = tmp.trim().split(regex_class);
cache._c = tmp = {};
for(let i = 0, match; i < matches.length; i++){
match = matches[i];
match && (tmp[matches[i]] = 1);
}
}
return /** @type {Object} */ (tmp);
}
/**
* @param {Element} node
* @param {string|Array} classname
*/
export function addClass(node, classname){
/** @type {Object} */
const cache = transformClassCache(node);
if(typeof classname === "object"){
for(let i = 0; i < classname.length; i++){
_addClass(node, classname[i], cache);
}
}
else{
_addClass(node, classname, cache);
}
}
/**
* @param {Element} node
* @param {string} classname
* @param {Object=} cache
*/
function _addClass(node, classname, cache){
const tmp = cache[classname];
if(!tmp){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.class");
cache[classname] = 1;
node.classList.add(classname);
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {Element} node
* @param {string|Array} classname
*/
export function removeClass(node, classname){
const cache = transformClassCache(node);
if(typeof classname === "object"){
for(let i = 0; i < classname.length; i++){
_removeClass(node, classname[i], cache);
}
}
else{
_removeClass(node, classname, cache);
}
}
/**
* @param {Element} node
* @param {string} classname
* @param {Object=} cache
*/
function _removeClass(node, classname, cache){
const tmp = cache[classname];
if(tmp !== 0){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.class");
cache[classname] = 0;
node.classList.remove(classname);
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {Element} node
* @param {string} classname
* @return {boolean}
*/
export function hasClass(node, classname){
const cache = transformClassCache(node);
let tmp = cache[classname];
if(typeof tmp !== "number"){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.class");
cache[classname] = tmp = node.classList.contains(classname) ? 1 : 0;
}
else{
PROFILER && tick("cache.match");
}
return !!tmp;
}
/**
* @param {Element} node
* @param {string|Array|Object} classname
* @param {boolean|number|undefined=} state
*/
export function toggleClass(node, classname, state){
const cache = transformClassCache(node);
if(typeof classname === "object"){
if(classname.constructor === Array){
for(let i = 0; i < classname.length; i++){
_toggleClass(node, /** @type {string} */ (classname[i]), state, cache);
}
}
else{
for(let key in classname){
_toggleClass(node, key, /** @type {boolean|number} */ (classname[key]), cache);
}
}
}
else{
_toggleClass(node, /** @type {string} */ (classname), state, cache);
}
}
/**
* @param {Element} node
* @param {string} classname
* @param {boolean|number|undefined=} state
* @param {Object=} cache
*/
function _toggleClass(node, classname, state, cache){
let tmp = !!cache[classname];
state = typeof state === "undefined" ? !tmp : !!state;
if(tmp !== state){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.class");
cache[classname] = state ? 1 : 0;
state ? node.classList.add(classname)
: node.classList.remove(classname);
}
else{
PROFILER && tick("cache.match");
}
}
// -------------------------------------------------------------
/**
* @param {HTMLElement} node
* @param {string} css
*/
export function setCss(node, css){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._s;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(tmp !== css){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.style");
cache._s = css;
node.style.cssText = css;
// const arr = css.match(regex_css);
//
// for(let i = 0, key, val; i < arr.length; i+=2){
//
// //_style.setProperty(arr[i], arr[i+1]);
//
// key = arr[i];
// val = arr[i + 1];
//
// if(_cache["_s" + key] !== val){
//
// _cache["_s" + key] = val;
// (_style || (_style = node.style)).setProperty(key, val);
// }
// }
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {HTMLElement} node
* @return {string}
*/
export function getCss(node){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._s;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof tmp !== "string"){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.css");
cache._s = tmp = node.style.cssText;
}
else{
PROFILER && tick("cache.match");
}
return tmp;
}
/**
* @param {Element} node
* @return {Object}
*/
function transformStyleCache(node){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._s;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(!tmp){
return cache._s = {};
}
if(typeof tmp === "string"){
PROFILER && tick("cache.transform");
const matches = tmp.match(regex_css);
cache._s = tmp = {};
for(let i = 0; i < matches.length; i += 2){
tmp[matches[i].trim()] = matches[i + 1].trim();
}
}
return /** @type {Object} */ (tmp);
}
/**
* @param {HTMLElement} node
* @param {string|Object} property
* @param {string|number=} value
*/
export function setStyle(node, property, value){
const cache = transformStyleCache(node);
const prop = node.style;
if(typeof property === "object"){
for(const style in property){
_setStyle(node, style, property[style], prop, cache);
}
}
else{
_setStyle(node, property, /** @type {string} */ (value), prop, cache);
}
}
/**
* @param {HTMLElement} node
* @param {string} property
* @param {string|number} value
* @param {CSSStyleDeclaration} _style
* @param {Object=} cache
*/
function _setStyle(node, property, value, _style, cache){
if(cache[property] !== value){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.style");
cache[property] = value;
(_style || node.style).setProperty(property, /** @type {string} */ (value));
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {HTMLElement} node
* @param {string} property
* @return {string}
*/
export function getStyle(node, property){
const cache = transformStyleCache(node);
let tmp = cache[property];
if(typeof tmp !== "string"){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.style");
cache[property] = tmp = node.style.getPropertyValue(property);
}
else{
PROFILER && tick("cache.match");
}
return tmp;
}
// -------------------------------------------------------------
/**
* @param {Element} node
* @param {string} html
*/
export function setHtml(node, html){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._h;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(tmp !== html){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.html");
node.innerHTML = html;
cache._h = html;
cache._t = null;
}
else{
PROFILER && tick("cache.match");
}
}
/**
* @param {Element} node
* @return {string}
*/
export function getHtml(node){
/** @type {NodeCache} */
let cache = node[MIKADO_NODE_CACHE];
let tmp;
if(cache){
tmp = cache._h || cache._t;
}
else{
node[MIKADO_NODE_CACHE] = cache = {};
}
if(typeof tmp !== "string"){
PROFILER && tick("cache.miss");
PROFILER && tick("cache.html");
cache._h = tmp = node.innerHTML;
}
else{
PROFILER && tick("cache.match");
}
return tmp;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy