olova 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -17
- package/dist/olova.js +1 -0
- package/package.json +4 -15
- package/dist/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
# olova
|
|
1
|
+
# olova
|
|
2
2
|
|
|
3
3
|
```html
|
|
4
|
-
<div id="
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
</template>
|
|
4
|
+
<div id="app">
|
|
5
|
+
<template>
|
|
6
|
+
<div>
|
|
7
|
+
<div>{ count }</div>
|
|
8
|
+
<button @click="increment">Increment</button>
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
</div>
|
|
11
12
|
|
|
12
13
|
<script type="module">
|
|
13
|
-
|
|
14
|
-
olova
|
|
14
|
+
let rander = document.querySelector("template").innerHTML;
|
|
15
|
+
import { createApp } from "//unpkg.com/olova";
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const app = createApp({
|
|
18
|
+
data: {
|
|
19
|
+
count: 0,
|
|
20
|
+
},
|
|
21
|
+
methods: {
|
|
22
|
+
increment() {
|
|
23
|
+
this.count++;
|
|
24
|
+
},
|
|
20
25
|
},
|
|
21
|
-
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
console.log("component mounted!");
|
|
26
|
+
template: rander,
|
|
24
27
|
});
|
|
28
|
+
app.mount("#app");
|
|
25
29
|
</script>
|
|
26
30
|
```
|
package/dist/olova.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
let createApp=({data:e,computed:t,methods:r,watch:l,mounted:a,beforeMount:n,beforeUpdate:o,template:i,plugins:c=[],components:s={}})=>{let u,f={},d={},h={},p={},m={},E=new Map,y=new Map,b=(e,t)=>{y.set(e,t)},g=(e,t)=>{m[e]=t},v=e=>{Array.from(e.attributes).forEach(t=>{let r=t.name.startsWith("$")?t.name.slice(1):null;if(r&&m[r]){let l=t.value;m[r](e,l,M),e.removeAttribute(t.name)}})},w=e=>new Proxy(e,{get:(e,t)=>"object"==typeof e[t]&&null!==e[t]?w(e[t]):e[t],set:(e,t,r)=>(e[t]!==r&&(e[t]=r,k(t)),!0)});class A extends Error{constructor(e){super(e),this.name="TemplateError"}}class N extends Error{constructor(e){super(e),this.name="StateError"}}let C=(e,t,r=Error)=>function(...l){try{return e.apply(this,l)}catch(a){throw new r(`${t}: ${a.message}`)}};n&&C(n,"Error in beforeMount hook",N).call(M);let x=new Set,T=e=>{f[e]&&(x.add(e),requestAnimationFrame(()=>{x.forEach(e=>{f[e].forEach(C(t=>{t.node?t.node.textContent=t.originalText.replace(/\{(.*?)\}/g,(e,t)=>Function("state",`with(state) { return ${t} }`)(M)):t.element&&t.attrName?(t.element.setAttribute(t.attrName,M[e]),t.element.removeAttribute(`:${t.attrName}`)):t.update&&t.update()},"Error updating bindings"))}),x.clear()}))},S=e=>{if("function"==typeof e){let t=C(e,"Error in onUpdated callback");h.__updated__||(h.__updated__=[]),h.__updated__.push({callback:t})}},k=e=>{o&&C(o,"Error in beforeUpdate hook").call(M,e),T(e),L(),q(e),h.__updated__&&h.__updated__.forEach(e=>e.callback.call(M))},L=()=>{Object.keys(d).forEach(e=>delete d[e])},q=e=>{h[e]&&h[e].forEach(t=>{t.debounce?(clearTimeout(t.timeout),t.timeout=setTimeout(()=>t.callback.call(M,M[e]),t.debounce)):t.throttle?(!t.lastCalled||Date.now()-t.lastCalled>t.throttle)&&(t.callback.call(M,M[e]),t.lastCalled=Date.now()):t.callback.call(M,M[e])})};l&&Object.keys(l).forEach(e=>{"function"==typeof l[e]?h[e]=[{callback:l[e]}]:"object"==typeof l[e]?h[e]=[{...l[e]}]:h[e]=Array.isArray(l[e])?l[e].map(e=>({callback:e})):[{callback:l[e]}]});let M=w({...e,$refs:new Proxy(p,{get:(e,t)=>e[t],set(){throw Error("$refs is read-only")}})}),O={},$={};t&&Object.keys(t).forEach(e=>{let r=t[e];O[e]=[],Object.defineProperty(M,e,{get:()=>"function"==typeof r&&"AsyncFunction"===r.constructor.name?($[e]||(d[e]=new Proxy(M,{get:(t,r)=>(O[e].includes(r)||O[e].push(r),t[r])}),$[e]=r.call(M).then(t=>(d[e]=t,delete $[e],T(e),t)).catch(t=>{console.error(`Error in async computed property "${e}":`,t)})),$[e]):(d.hasOwnProperty(e)||(d[e]=new Proxy(M,{get:(t,r)=>(O[e].includes(r)||O[e].push(r),t[r])}),d[e]=r.call(M)),d[e]),enumerable:!0})});let D=e=>{Object.keys(O).forEach(t=>{O[t].includes(e)&&(delete d[t],T(t))})},B=()=>{u.querySelectorAll("[\\$style]").forEach(e=>{if(!(e instanceof HTMLElement))return;let t=e.getAttribute("$style");if(!t)return;let r=()=>{try{let r=Function("state",`with(state) { return ${t} }`)(M);"object"==typeof r&&null!==r?Object.entries(r).forEach(([t,r])=>{e.style[t]=r}):"string"==typeof r&&e.setAttribute("style",r)}catch(l){console.error("Error applying style directive:",l)}};r(),T(t)})},_=()=>{u.querySelectorAll("[\\$if]").forEach(e=>{if(!(e instanceof HTMLElement))return;let t=e.getAttribute("$if");if(!t)return;let r=e.parentNode,l=document.createComment("$if placeholder");r?.insertBefore(l,e);let a=e.nextElementSibling;for(;a&&!a.hasAttribute("$else");)a=a.nextElementSibling;let n=()=>{try{Function("state",`with(state) { return ${t} }`)(M)?(e.style.display="",e.parentNode!==r&&r?.insertBefore(e,l.nextSibling),a&&(a.style.display="none")):(e.style.display="none",a&&(a.style.display=""))}catch(n){console.error("Error evaluating :if directive:",n)}};n(),T(t)})},j=e=>{if(!(e instanceof HTMLElement))return;let t=e.getAttribute("$show");if(!t)return;let r=()=>{try{let r=Function("state",`with(state) { return ${t} }`)(M);e.style.display=r?"":"none"}catch(l){console.error("Error evaluating $show directive:",l)}};r(),f[t]||(f[t]=[]),f[t].push({element:e,update:r})},H=()=>{u.querySelectorAll("[\\$for]").forEach(e=>{if(!(e instanceof HTMLElement))return;let t=e.getAttribute("$for");if(!t)return;let r=t.match(/^\s*(\w+)\s+(?:of|in)\s+(\w+)\s*$/);if(!r){console.error("Invalid :for expression:",t);return}let[,l,a]=r,n=e.parentNode,o=document.createComment("$for placeholder");n?.insertBefore(o,e),e.removeAttribute("$for");let i=e.cloneNode(!0);n?.removeChild(e);let c=()=>{let e=document.createDocumentFragment(),t=M[a];for(Array.isArray(t)&&t.forEach((t,r)=>{let a=i.cloneNode(!0),n={[l]:t,index:r},o=new Proxy(n,{get:(e,t)=>(t in e)?e[t]:M[t]}),c=e=>{if(e.nodeType===Node.TEXT_NODE){let t=e.textContent;t.includes("{")&&t.includes("}")&&(e.textContent=t.replace(/\{(.*?)\}/g,(e,t)=>Function("state",`with(state) { return ${t} }`)(o)))}else e.nodeType===Node.ELEMENT_NODE&&Array.from(e.childNodes).forEach(c)};c(a),a.querySelectorAll("*").forEach(e=>{Array.from(e.attributes).forEach(t=>{if(t.value.includes("{")&&t.value.includes("}")){let r=t.value.replace(/\{(.*?)\}/g,(e,t)=>Function("state",`with(state) { return ${t} }`)(o));e.setAttribute(t.name,r)}})}),e.appendChild(a)});o.nextSibling;)n?.removeChild(o.nextSibling);n?.insertBefore(e,o.nextSibling)};c(),f[a]||(f[a]=[]),f[a].push({updateFor:c})})},U=()=>{u.querySelectorAll("[\\$ref]").forEach(e=>{if(!(e instanceof HTMLElement))return;let t=e.getAttribute("$ref");t&&(p[t]=e,e.removeAttribute("$ref"))})},W=()=>{u.querySelectorAll("[\\$model]").forEach(e=>{if(!(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement))return;let t=e.getAttribute("$model");t&&(e.value=M[t]||"",e.addEventListener("input",e=>{M[t]=e.target.value}),f[t]||(f[t]=[]),f[t].push({element:e,updateModel(){e.value=M[t]||""}}),e.removeAttribute("$model"))})},F=e=>{if(e.nodeType===Node.ELEMENT_NODE){let t=e.tagName.toLowerCase();if(y.has(t)){let r=y.get(t),l=Array.from(e.attributes).reduce((e,t)=>(e[t.name]=t.value,e),{}),a=r(l),n=document.createElement("div");n.innerHTML=a;let o=n.firstElementChild;return e.parentNode.replaceChild(o,e),o}}return e},P=()=>{let e=document.createElement("div");e.innerHTML=i.trim();let t=e.getElementsByTagName("template");if(t.length>0){let r=t[0].content;u.innerHTML="",u.appendChild(r.cloneNode(!0))}else u.innerHTML="",u.appendChild(e);let l=e=>{e.nodeType===Node.ELEMENT_NODE&&Array.from((e=F(e)).childNodes).forEach(l)};Array.from(u.childNodes).forEach(l),u.querySelectorAll("*").forEach(e=>{if(e instanceof HTMLElement){v(e);let t=[...e.childNodes].filter(e=>e.nodeType===Node.TEXT_NODE&&/\{.*?\}/.test(e.textContent||""));t.forEach(e=>{let t=e.textContent||"",r=t.match(/\{(.*?)\}/g);r&&r.forEach(r=>{let l=r.replace(/\{|\}/g,"").trim();f[l]||(f[l]=[]),f[l].push({node:e,originalText:t})})}),Array.from(e.attributes).forEach(t=>{if(t.name.startsWith("$")){let r=t.value.trim(),l=t.name.slice(1);f[r]||(f[r]=[]),f[r].push({element:e,attrName:l})}})}})};Object.entries(s).forEach(([e,t])=>{b(e,t)});let X=()=>{c.forEach(e=>{"function"==typeof e&&e({createPlugin:g,state:M,bindings:f})})},G=()=>{u.querySelectorAll("*").forEach(e=>{Array.from(e.attributes).forEach(t=>{if(t.name.startsWith("@")){let l=t.name.slice(1),a=t.value.trim();e.addEventListener(l,e=>{if(r&&r[a])r[a].call(M,e);else try{Function("state","event",`with(state) { ${a} }`).call(M,M,e),k()}catch(t){console.error(`Error executing inline event expression: ${a}`,t)}})}})})},I=()=>{u.querySelectorAll("[\\$class]").forEach(e=>{if(!(e instanceof HTMLElement))return;let t=e.getAttribute("$class");if(!t)return;let r=()=>{try{let r=Function("state",`with(state) { return ${t} }`)(M);"object"==typeof r&&null!==r?Object.entries(r).forEach(([t,r])=>{r?e.classList.add(t):e.classList.remove(t)}):"string"==typeof r&&(e.className=r)}catch(l){console.error("Error applying class directive:",l)}e.removeAttribute("$class")};r(),f[t]||(f[t]=[]),f[t].push({updateClass:r})})},z=(e,t)=>{E.has(e)||E.set(e,[]),E.get(e).forEach(e=>e(t))},J=(e,t)=>(E.has(e)||E.set(e,[]),E.get(e).push(t),()=>{let r=E.get(e),l=r.indexOf(t);-1!==l&&r.splice(l,1)}),K={beforeCreate:[],created:[],beforeMount:[],mounted:[],beforeUpdate:[],updated:[],beforeUnmount:[],unmounted:[]},Q=(e,t)=>{K[e]&&K[e].push(t)},R=e=>{K[e]&&K[e].forEach(e=>e.call(M))},V=e=>{e.data&&Object.assign(M,e.data()),e.methods&&Object.assign(r,e.methods),e.computed&&Object.assign(t,e.computed),e.watch&&Object.keys(e.watch).forEach(t=>{l[t]||(l[t]=[]),l[t].push(e.watch[t])}),e.mounted&&Q("mounted",e.mounted)},Y=e=>{console.error("Global error:",e)};return window.addEventListener("error",Y),{mount:C(function(e){if(!(u=document.querySelector(e)))throw Error(`Element with selector "${e}" not found.`);R("beforeCreate"),R("created"),n&&n.call(M),R("beforeMount"),X(),P(),G(),B(),_(),H(),U(),W(),I(),D(),u.querySelectorAll("[\\$show]").forEach(e=>{e instanceof HTMLElement&&j(e)}),a&&a.call(M),R("mounted"),Object.keys(M).forEach(e=>T(e))},"Error mounting application"),onUpdated:S,createPlugin:g,emit:z,on:J,addLifecycleHook:Q,applyMixin:V,component:b}};export{createApp};
|
package/package.json
CHANGED
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "olova",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A lightweight JavaScript framework for building reactive applications.",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "vite build",
|
|
9
|
-
"preview": "vite preview",
|
|
10
|
-
"test": "jest"
|
|
11
|
-
},
|
|
12
5
|
"keywords": [
|
|
13
6
|
"javascript",
|
|
14
7
|
"framework",
|
|
15
8
|
"reactive",
|
|
16
|
-
"olova"
|
|
9
|
+
"olova",
|
|
10
|
+
"olovajs"
|
|
17
11
|
],
|
|
18
12
|
"author": "Nazmul Hossain",
|
|
19
|
-
"license": "MIT"
|
|
20
|
-
"dependencies": {},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"vite": "^4.0.0",
|
|
23
|
-
"jest": "^30.1.0"
|
|
24
|
-
}
|
|
13
|
+
"license": "MIT"
|
|
25
14
|
}
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class olova{constructor(){this.$elements={},this.listeners={},this.components={},this.plugins={},this.refs={},this.$refs=new Proxy({},{get:(e,t)=>this.refs[t]}),this.data={},this.dependencies=new Map,this.subscribers=new Map,this.effects=[],this.cleanupEffects=[]}registerPlugin(e,t){this.plugins[e]=t}registerComponent(e,t){this.components[e]=t,this.defineCustomElement(e)}defineCustomElement(e){const t=this;class i extends HTMLElement{connectedCallback(){this.render()}render(){const i=this.getProps(),n=(0,t.components[e])(i),s=document.createElement("div");s.innerHTML=n.trim();const r=this.parentNode,o=s.firstChild;o&&(r.replaceChild(o,this),t.applyDirectivesToElement(o),t.initReactiveSystem(),t.runEffects())}getProps(){const e={};for(const t of this.attributes)e[t.name]=t.value;return e}static get observedAttributes(){return Object.keys(t.components[e]({})||{})}attributeChangedCallback(e,t,i){this.render()}}customElements.define(e,i)}applyDirectivesToElement(e){this.applyShowDirective(e),this.applyIfDirective(e),this.applyForDirective(e),this.applyModelDirective(e),this.applyAttrDirective(e),this.applyClassDirective(e),this.applyStyleDirective(e),this.applyBindDirective(e),this.applyRefDirective(e),e.querySelectorAll("*").forEach((e=>{this.applyShowDirective(e),this.applyIfDirective(e),this.applyForDirective(e),this.applyModelDirective(e),this.applyAttrDirective(e),this.applyClassDirective(e),this.applyStyleDirective(e),this.applyBindDirective(e),this.applyRefDirective(e)}))}applyShowDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$show");t&&this.effect((()=>{const i=this.evaluateExpression(t);e.style.display=i?"":"none"}))}applyIfDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$if");if(!t)return;const i=e.parentNode,n=document.createComment("$if placeholder");i?.insertBefore(n,e);let s=e.nextElementSibling;for(;s&&!s.hasAttribute("$else");)s=s.nextElementSibling;s&&i?.removeChild(s),this.effect((()=>{this.evaluateExpression(t)?(e.style.display="",e.parentNode!==i&&i?.insertBefore(e,n.nextSibling),s&&(s.style.display="none",s.parentNode===i&&i?.removeChild(s))):(e.style.display="none",e.parentNode===i&&i?.removeChild(e),s&&(s.style.display="",s.parentNode!==i&&i?.insertBefore(s,n.nextSibling)))}))}applyForDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$for");if(!t)return;const[i,n]=t.split(" in "),s=e.parentNode,r=document.createComment("$for placeholder");s?.insertBefore(r,e),e.remove(),this.effect((()=>{const t=this.evaluateExpression(n),o=new Set;let c=r.nextSibling;for(;c&&c.nodeType===Node.ELEMENT_NODE;)o.add(c),c=c.nextSibling;t.forEach(((t,n)=>{let c=Array.from(o).find((e=>e.getAttribute("key")===String(n)));c?o.delete(c):(c=e.cloneNode(!0),c.setAttribute("key",String(n)),s?.insertBefore(c,r.nextSibling)),this.interpolateElement(c,{[i]:t,index:n})})),o.forEach((e=>e.remove()))}))}applyModelDirective(e){if(!(e instanceof HTMLInputElement))return;const t=e.getAttribute("$model");t&&(e.addEventListener("input",(e=>{this.setExpressionValue(t,e.target.value)})),this.effect((()=>{e.value=this.evaluateExpression(t)})))}applyAttrDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$attr")?.split(",");t&&t.forEach((t=>{const[i,n]=t.split(":");this.effect((()=>{e.setAttribute(i,this.evaluateExpression(n))}))}))}applyClassDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$class");t&&this.effect((()=>{const i=this.evaluateExpression(t);"object"==typeof i&&null!==i?Object.entries(i).forEach((([t,i])=>{i?e.classList.add(t):e.classList.remove(t)})):"string"==typeof i&&(e.className=i)}))}applyStyleDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$style");t&&this.effect((()=>{const i=this.evaluateExpression(t);"object"==typeof i&&null!==i?Object.keys(i).forEach((t=>{e.style[t]=i[t]})):"string"==typeof i&&e.setAttribute("style",i)}))}applyBindDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$bind");t&&(this.effect((()=>{const i=this.evaluateExpression(t);this.setElementValue(e,i)})),e.addEventListener("input",(e=>{const i=this.getElementValue(e.target);this.setExpressionValue(t,i)})),"checkbox"!==e.type&&"radio"!==e.type||e.addEventListener("change",(e=>{const i=this.getElementValue(e.target);this.setExpressionValue(t,i)})))}applyRefDirective(e){if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$ref");t&&this.registerRef(t,e)}setElementValue(e,t){e instanceof HTMLInputElement?"checkbox"===e.type?e.checked=!!t:"radio"===e.type?e.checked=e.value===t:e.value=t:(e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)&&(e.value=t)}getElementValue(e){return e instanceof HTMLInputElement?"checkbox"===e.type?e.checked:"radio"===e.type?e.checked?e.value:null:e.value:e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value:void 0}useEffect(e){this.effects.push(e)}runEffects(){this.effects.forEach((e=>{const t=e();"function"==typeof t&&this.cleanupEffects.push(t)})),this.effects=[]}cleanup(){this.cleanupEffects.forEach((e=>e())),this.cleanupEffects=[]}getRef(e){return void 0!==this.refs[e]?this.refs[e]:(console.warn(`Ref '${e}' not found.`),null)}registerRef(e,t){this.refs[e]=t}defineReactive(e,t,i){this.listeners[t]=[],Object.defineProperty(e,t,{get:()=>(this.track(t),i),set:e=>{i!==e&&(i=e,this.notify(t))}})}watch(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)}track(e){olova.activeEffect&&(this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependencies.get(e).add(olova.activeEffect))}notify(e){this.dependencies.has(e)&&this.dependencies.get(e).forEach((e=>e())),this.listeners[e]&&this.listeners[e].forEach((e=>e()))}effect(e){olova.activeEffect=e,e(),olova.activeEffect=null}makeReactive(e){for(const t in e)e.hasOwnProperty(t)&&this.defineReactive(e,t,e[t])}initReactiveSystem(){this.makeReactive(window.useSignal),this.initDirectives(),this.initEvents(),this.initDataBinding()}initDirectives(){this.initIfDirective(),this.initRefDirective(),this.initShowDirective(),this.initForDirective(),this.initModelDirective(),this.initAttrDirective(),this.initClassDirective(),this.initStyleDirective(),this.initBindDirective(),this.initHtmlDirective(),Object.keys(this.plugins).forEach((e=>{document.querySelectorAll(`[\\$${e}]`).forEach((t=>{const i=t.getAttribute(`$${e}`);this.effect((()=>{const n=this.evaluateExpression(i);this.plugins[e](t,n,this)}))}))}))}initHtmlDirective(){document.querySelectorAll("[\\$html]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$html");t&&this.effect((()=>{const i=this.evaluateExpression(t);e.innerHTML=i,e.removeAttribute("$html")}))}))}initClassDirective(){document.querySelectorAll("[\\$class]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$class");t&&this.effect((()=>{const i=this.evaluateExpression(t);"object"==typeof i&&null!==i?Object.entries(i).forEach((([t,i])=>{i?e.classList.add(t):e.classList.remove(t)})):"string"==typeof i&&(e.className=i)}))}))}initShowDirective(){document.querySelectorAll("[\\$show]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$show");t&&this.effect((()=>{const i=this.evaluateExpression(t);e.style.display=i?"":"none"}))}))}initBindDirective(){document.querySelectorAll("[\\$bind]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$bind");t&&(this.effect((()=>{const i=this.evaluateExpression(t);this.setElementValue(e,i)})),e.addEventListener("input",(e=>{const i=this.getElementValue(e.target);this.setExpressionValue(t,i)})),"checkbox"!==e.type&&"radio"!==e.type||e.addEventListener("change",(e=>{const i=this.getElementValue(e.target);this.setExpressionValue(t,i)})))}))}setElementValue(e,t){e instanceof HTMLInputElement?"checkbox"===e.type?e.checked=!!t:"radio"===e.type?e.checked=e.value===t:e.value=t:(e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)&&(e.value=t)}getElementValue(e){return e instanceof HTMLInputElement?"checkbox"===e.type?e.checked:"radio"===e.type?e.checked?e.value:null:e.value:e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value:void 0}initStyleDirective(){document.querySelectorAll("[\\$style]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$style");t&&this.effect((()=>{const i=this.evaluateExpression(t);"object"==typeof i&&null!==i?Object.keys(i).forEach((t=>{e.style[t]=i[t]})):"string"==typeof i&&e.setAttribute("style",i)}))}))}initIfDirective(){document.querySelectorAll("[\\$if]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$if");if(!t)return;const i=e.parentNode,n=document.createComment("$if placeholder");i?.insertBefore(n,e);let s=e.nextElementSibling;for(;s&&!s.hasAttribute("$else");)s=s.nextElementSibling;s&&i?.removeChild(s),this.effect((()=>{this.evaluateExpression(t)?(e.style.display="",e.parentNode!==i&&i?.insertBefore(e,n.nextSibling),s&&(s.style.display="none",s.parentNode===i&&i?.removeChild(s))):(e.style.display="none",e.parentNode===i&&i?.removeChild(e),s&&(s.style.display="",s.parentNode!==i&&i?.insertBefore(s,n.nextSibling)))}))}))}initRefDirective(){document.querySelectorAll("[\\$ref]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$ref");t&&this.registerRef(t,e),e.removeAttribute("$ref")}))}initForDirective(){document.querySelectorAll("[\\$for]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$for");if(!t)return;const[i,n]=t.split(" in "),s=e.parentNode,r=document.createComment("$for placeholder");s?.insertBefore(r,e),e.removeAttribute("$for");const o=e.cloneNode(!0);e.remove(),this.effect((()=>{const e=this.evaluateExpression(n),t=new Set;let c=r.nextSibling;for(;c&&c.nodeType===Node.ELEMENT_NODE;)t.add(c),c=c.nextSibling;e.forEach(((e,n)=>{let c=Array.from(t).find((e=>e.getAttribute("key")===String(n)));c?t.delete(c):(c=o.cloneNode(!0),c.setAttribute("key",String(n)),s?.insertBefore(c,r.nextSibling)),this.interpolateElement(c,{[i]:e,index:n})})),t.forEach((e=>e.remove()))}))}))}initModelDirective(){document.querySelectorAll("[\\$model]").forEach((e=>{if(!(e instanceof HTMLInputElement))return;const t=e.getAttribute("$model");t&&(e.addEventListener("input",(e=>{this.setExpressionValue(t,e.target.value)})),this.effect((()=>{e.value=this.evaluateExpression(t)})))}))}initAttrDirective(){document.querySelectorAll("[\\$attr]").forEach((e=>{if(!(e instanceof HTMLElement))return;const t=e.getAttribute("$attr")?.split(",");t&&t.forEach((t=>{const[i,n]=t.split(":");this.effect((()=>{e.setAttribute(i,this.evaluateExpression(n))}))}))}))}initEvents(){["click","input","change","mouseover","mousemove","mouseout","keydown","keyup","mousedown","mouseup","dblclick","focus","blur","contextmenu","drag","drop","scroll","resize","touchstart","touchmove","touchend","paste","copy","cut","error","load","submit","animationstart","animationend","animationiteration","transitionend","hashchange","beforeunload","fullscreenchange","message","canplay","canplaythrough","durationchange","emptied","ended","invalid","progress","ratechange","waiting","volumechange","wheel","focusin","focusout","pointerenter","pointerleave","touchcancel"].forEach((e=>{document.querySelectorAll(`[\\@${e}]`).forEach((t=>{if(!(t instanceof HTMLElement))return;const i=t.getAttribute(`@${e}`);i&&t.addEventListener(e,(t=>{try{let e=i.trim();if(e in window.useSignal&&"function"==typeof window.useSignal[e])window.useSignal[e](t);else{new Function("event, $",`with($) { ${e} }`)(t,window.useSignal)}}catch(t){console.error(`Error executing handler '${i}' for event '${e}':`,t)}}))}))}))}initDataBinding(){this.compileTextNodes(document.body)}compileTextNodes(e){const t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);let i;const n=[];for(;i=t.nextNode();)i.textContent.includes("{")&&i.textContent.includes("}")&&n.push(i);n.forEach((e=>{const t=e.textContent.split(/(\{.*?\})/),i=document.createDocumentFragment();t.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=document.createTextNode(""),n=e.slice(2,-2).trim();this.effect((()=>{t.textContent=this.evaluateExpression(n)})),i.appendChild(t)}else i.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(i,e)}))}interpolateTextNodes(e,t){const i=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);let n;const s=[];for(;n=i.nextNode();)n.textContent.includes("{")&&n.textContent.includes("}")&&s.push(n);s.forEach((e=>{const i=e.textContent.split(/(\{.*?\})/),n=document.createDocumentFragment();i.forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const i=document.createTextNode(""),s=e.slice(2,-2).trim();this.effect((()=>{i.textContent=this.evaluateExpression(s,t)})),n.appendChild(i)}else n.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(n,e)}))}evaluateExpression(e,t={}){try{return new Function("useSignal","with(useSignal) { return "+e+" }")({...window.useSignal,...t})}catch(t){return console.error(`Error evaluating expression: ${e}`,t),""}}setExpressionValue(e,t){try{new Function("useSignal","value",`with(useSignal) { ${e} = value }`)(window.useSignal,t)}catch(t){console.error(`Error setting value for expression: ${e}`,t)}}interpolateElement(e,t){this.interpolateAttributes(e,t),this.interpolateTextNodes(e,t),Array.from(e.children).forEach((e=>this.interpolateElement(e,t)))}interpolateAttributes(e,t){Array.from(e.attributes).forEach((e=>{e.value.includes("{")&&e.value.includes("}")&&this.effect((()=>{e.value=this.interpolate(e.value,t)}))}))}interpolateTextNodes(e,t){const i=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);let n;const s=[];for(;n=i.nextNode();)n.textContent.includes("{")&&n.textContent.includes("}")&&s.push(n);s.forEach((e=>{const i=document.createDocumentFragment();e.textContent.split(/(\{.*?\})/).forEach((e=>{if(e.startsWith("{")&&e.endsWith("}")){const n=document.createElement("span"),s=e.slice(2,-2).trim();this.effect((()=>{n.textContent=this.evaluateExpression(s,t)})),i.appendChild(n)}else i.appendChild(document.createTextNode(e))})),e.parentNode.replaceChild(i,e)}))}interpolate(e,t){return e.replace(/\{\{(.*?)\}\}/g,((e,i)=>this.evaluateExpression(i,t)))}static init(){const e=new olova;window.$refs=e.$refs,window.$=t=>e.$(t);return window.useSignal=new Proxy(((e={})=>{Object.assign(window.useSignal,e)}),{get:(t,i)=>("call"===i||"apply"===i||e.track(i),Reflect.get(t,i)),set:(t,i,n)=>(Reflect.get(t,i)!==n&&(Reflect.set(t,i,n),e.notify(i),e.runEffects()),!0)}),document.addEventListener("DOMContentLoaded",(()=>{e.renderTemplate()})),window.addEventListener("beforeunload",(()=>{e.cleanup()})),window.useEffect=t=>{e.useEffect(t)},window.component=(t,i)=>{e.registerComponent(t,i)},window.plugin=(t,i)=>e.registerPlugin(t,i),e}renderTemplate(){const e=document.getElementById("root"),t=document.querySelector("template");if(e&&t){let i=t.innerHTML;i=i.replace(/<([a-z-]+)><\/\1>/g,""),e.innerHTML=i,t.remove(),this.initReactiveSystem(),this.runEffects()}else console.error("Root element or app template not found")}}olova.activeEffect=null;export default olova;
|