UNPKG

fundom.js

Version:

JS library for creating reactive ui elements in declarative way

2 lines (1 loc) 7.51 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).FD={})}(this,(function(e){"use strict";const t=Symbol("fnType"),n=Symbol("format"),s=Symbol("compute"),o=Symbol("stateGetter"),r=Symbol("caseHandler"),l=(e,t,n,s,o)=>{if(0!==t.length)for(let r of t)r(e,n,s,o)},i=e=>({childrenLength:e.children.length,innerHTML:e.innerHTML,innerText:e.innerText,textContent:e.textContent||"",style:e.style,attributes:e.attributes,classList:e.classList}),a=(e,t,n)=>{g(e,t)||(n?e.insertBefore(t,n.nextSibling):e.appendChild(t))},f=e=>d(e)&&e[t]===o,c=e=>d(e)&&e[t]===n,u=e=>d(e)&&e[t]===s,m=(e,t,n)=>{if(u(e))e(t);else if(c(e))e(t);else if(f(e)){const s=e((e=>t(e)),{releaseEffect:()=>(e=>{e&&(e.snapshot=null)})(n)});t(s)}else t(e)},h=(e,t)=>{const n=((e="")=>Math.random().toString(36).replace("0.",e))("ctrlFlow_"),s=document.createComment("");let o=[],r=[];return(f,c,u,h)=>{if(!w(f))return console.warn(new y("ifElse/ifOnly/match").message),f;return n in c||(c[n]=((e,t)=>({snapshot:i(e),comment:t}))(f,s),a(f,s,c[u]?.comment)),m(e,(e=>{if(h)o!==r&&(l(f,o,c,n,!0),r=o);else{const s=t(e);o!==s&&(l(f,o,c,n,!0),l(f,s,c,n,!1),o=s,r=[])}}),c[n]),f}},g=(e,t)=>t.parentNode===e,p=(e,...t)=>{for(let n of t)g(e,n)&&e.removeChild(n)},d=e=>"function"==typeof e,w=e=>e&&e instanceof HTMLElement;class y extends Error{constructor(e){super(),this.message=`value passed to ${e} is not HTMLElement type`}}class b extends Error{constructor(e){super(),this.message=`snapshot for id ${e} does not exist`}}const x=(e,...t)=>(...n)=>{const s=document.createElement(e);return l(s,[...t,...n],{},"",!1),s};function S(...e){const t=[];return(n,s,o,r)=>{if(!w(n))return console.warn(new y("children").message),n;const l=e=>{if(d(e)){const n=e();w(n)?t.push(n):console.warn("[children] passed function does not return HTMLElement type",n)}else w(e)?t.push(e):console.warn("[children] passed argument is not HTMLElement type")};return m(1===e.length?e[0]:e,(e=>{if(Array.isArray(e)){if(0===t.length)for(let t of e)l(t)}else t.length>0&&(p(n,...t),t.length=0),l(e);if(r)p(n,...t);else{const e=s[o]?.comment;for(let s of t)g(n,s)||(e&&e instanceof Comment?n.insertBefore(s,e):n.appendChild(s))}})),n}}const L=e=>(...t)=>(...n)=>h(e,(e=>Boolean(e)?t:n));e.attr=e=>(t,n,s,o)=>{if(!w(t))return console.warn(new y("attr").message),t;for(let[r,l]of Object.entries(e)){m(l,(e=>{if(o){const e=n[s]?.snapshot;e?e.attributes.getNamedItem(r)?t.setAttribute(r,e.attributes.getNamedItem(r)?.value||""):t.removeAttribute(r):console.warn(new b(s).message)}else t.setAttribute(r,String(e))}))}return t},e.child=(e,...t)=>{let n=null;return(s,o,r,i)=>w(s)?(w(n)||(n=x(e,...t)()),l(s,[S(n)],o,r,i),s):(console.warn(new y("child").message),s)},e.children=S,e.classList=(...e)=>(t,n,s,o)=>{if(!w(t))return console.warn(new y("classList").message),t;for(let r of e){let e;m(r,(r=>{const l=String(r);if(o){const e=n[s]?.snapshot;e?t.classList.remove(l):console.warn(new b(s).message)}else e&&t.classList.remove(e),t.classList.add(l),e=l}))}return t},e.cmp=(e,n)=>{function o(t){if(f(e)){const s=e((e=>{t(n(e))}));t(n(s))}else console.warn(`${e} is not of FunStateGetter type, passing it to cmp function`),t(n(e))}return o[t]=s,o},e.elem=x,e.fmt=(...e)=>{function s(t){const n=[];if(e.length<2)return console.warn("fmt util needs at least 2 arguments to make sense"),s(e[0]??""),t(n.join(""));if("string"==typeof e[0]){const t=e[0].split("{}");if(t.length===e.length){s(t.shift()??"");for(let n=1;n<e.length;n++){s(e[n]??""),t.length>0&&s(t.shift()||"")}}else console.warn("number of {} in fmt util is not equal to number of dynamic arguments, falling back to concatenating all"),o()}else console.warn("first argument of fmt is not a string type, falling back to concatenating all"),o();function s(e){let s=n.length;if(u(e)||c(e))e((e=>{n.length>s?(n[s]=e,t(n.join(""))):n.push(e)}));else if(f(e)){const o=e((e=>{n[s]=e,t(n.join(""))}));n.push(o)}else n.push(e)}function o(){for(let t of e)s(t)}t(n.join(""))}return s[t]=n,s},e.funState=e=>{const n=[],s=[];let r=e;const l=e=>n.findIndex((([t])=>t===e)),i=e=>{if(e){const t=l(e);if(t>-1){const e=n.splice(t,1);if(e[0]){const t=e[0][1];d(t.releaseEffect)&&t.releaseEffect()}}else console.warn("[funState] no such subscriber to release: ",e)}else n.forEach((e=>{d(e[1].releaseEffect)&&e[1].releaseEffect()})),n.length=0},a=(e,t)=>{switch(e){case"pause":(e=>{if(e){if(-1===l(e))return void console.warn("[funState] no such subscriber to pause: ",e);-1===s.indexOf(e)?s.push(e):console.warn(`[funState] ignore pause of ${e} as it is already paused`)}else for(const e of n)-1===s.indexOf(e[0])&&s.push(e[0])})(t);break;case"resume":(e=>{if(e){if(-1===l(e))return void console.warn("[funState] no such subscriber to pause: ",e);const t=s.indexOf(e);t>-1?s.splice(t,1):console.warn(`[funState] ignore resume of ${e} as it is not paused`)}else s.length=0})(t);break;case"release":i(t);break;default:console.warn(`[funState] unknown action ${e} provided`)}},f=(e,t)=>{if(e)if(d(e)){-1===l(e)&&n.push([e,t||{}])}else console.warn("[funState] provided value is not a function: ",e);return r};f[t]=o;return[f,(e,t)=>{if(d(e))e(a);else{const o=()=>{r=e,n.forEach((([e,{once:t}])=>{-1===s.indexOf(e)&&(e(r),t&&i(e))}))};t&&t.force?o():Object.is(e,r)||o()}}]},e.html=e=>(t,n,s,o)=>{if(!w(t))return console.warn(new y("html").message),t;return m(e,(e=>{if(o){const e=n[s]?.snapshot;e?t.innerHTML=e.innerHTML:console.warn(new b(s).message)}else t.innerHTML=String(e)})),t},e.ifElse=L,e.ifOnly=e=>(...t)=>L(e)(...t)(),e.list=(e,t)=>{const n=document.createComment("");let s=[],o=[];return(r,i,f,c)=>{if(!w(r))return console.warn(new y("list").message),r;a(r,n,i[f]?.comment);return m(e,(e=>{if(Array.isArray(e))if(d(t))if(c)o.length>0&&(l(r,[S(...s)],i,f,c),s=[],o=[]);else{const n=[];if(o.length>0){for(let[a,u]of e.entries())if(Object.is(u,o[a]))n.push(s[a]);else{const e=t(u,a)();n.push(e),a<o.length?r.replaceChild(e,s[a]):l(r,[S(e)],i,f,c)}if(o.length>e.length)for(let t=o.length-1;t>=e.length;t--)p(r,s[t])}else{for(let[s,o]of e.entries())n.push(t(o,s)());l(r,[S(...n)],i,f,c)}s=n,o=e}else console.warn("[list] second argument of list should be ReturnType<typeof elem>");else console.warn("[list] first argument of list should be Array")})),r}},e.match=e=>(...n)=>h(e,(e=>{for(let[o,l]of n.entries())if(d(s=l)&&s[t]===r){const t=l(e,o===n.length-1);if(t.length>0)return t}var s;return[]})),e.matchCase=e=>(...n)=>{function s(t,s){if(void 0===e&&s)return n;if(d(e)){if(e(t))return n}else if(e===t)return n;return[]}return s[t]=r,s},e.on=(e,t,n)=>s=>w(s)?(s.addEventListener(e,t,n),n&&n.offTrigger&&n.offTrigger((()=>{s.removeEventListener(e,t)})),s):(console.warn(new y("on").message),s),e.style=e=>(t,n,s,o)=>{if(!w(t))return console.warn(new y("style").message),t;for(let[l,i]of Object.entries(e)){const e="string"!=typeof(r=l)?"":r.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();m(i,(r=>{if(o){const o=n[s]?.snapshot;o?""!==o.style.getPropertyValue(e)?t.style.setProperty(e,o.style.getPropertyValue(e)):t.style.removeProperty(e):console.warn(new b(s).message)}else t.style.setProperty(e,String(r))}))}var r;return t},e.txt=(e,t={useTextContent:!1})=>(n,s,o,r)=>{if(!w(n))return console.warn(new y("txt").message),n;const l=t.useTextContent?"textContent":"innerText";return m(e,(e=>{if(r){const e=s[o]?.snapshot;e?n[l]=e[l]:console.warn(new b(o).message)}else n[l]=String(e)})),n}}));