From d41690777492688de9b2a94118d136c0fb49cac3 Mon Sep 17 00:00:00 2001 From: AI Engineer Date: Thu, 11 Jun 2026 19:48:10 +0800 Subject: [PATCH] fix: restrict to only bind to 'input' event for native text input elements By: AICoder --- dist/state.js | 3 ++- dist/state.min.js | 2 +- package-lock.json | 4 ++-- package.json | 2 +- src/engine.js | 3 ++- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dist/state.js b/dist/state.js index 19de524..e161a0d 100644 --- a/dist/state.js +++ b/dist/state.js @@ -509,7 +509,8 @@ node.addEventListener(eventName, (e) => _runCode(tpl, { event: e, thisNode: node, ...e.detail || {} }, scanObj.thisObj || node, node._ref || {})); } else { if (realAttrName === "bind") { - node.addEventListener(["textarea", "text", "password"].includes(node.type || "text") || node.isContentEditable ? "input" : "change", (e) => { + const isTextInput = ["INPUT", "TEXTAREA"].includes(node.tagName) && ["textarea", "text", "password", "email", "number", "search", "url", "tel"].includes(node.type || "text") || node.isContentEditable; + node.addEventListener(isTextInput ? "input" : "change", (e) => { let newVal = node.isContentEditable ? e.target.innerHTML : node.type === "checkbox" ? e.target.checked : e.target.files || e.target.value || e.detail; _setNoWriteBack(node); setDisableRunCodeError(true); diff --git a/dist/state.min.js b/dist/state.min.js index 15077da..f38e728 100644 --- a/dist/state.min.js +++ b/dist/state.min.js @@ -1 +1 @@ -!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).ApigoState=e.ApigoState||{})}(this,function(e){"use strict";var t,n;const s={clone:globalThis.structuredClone||(e=>JSON.parse(JSON.stringify(e))),base64:e=>btoa(String.fromCharCode(...(new TextEncoder).encode(e))),unbase64:e=>(new TextDecoder).decode(Uint8Array.from(atob(e),e=>e.charCodeAt(0))),urlbase64:e=>s.base64(e).replace(/[+/=]/g,e=>({"+":"-","/":"","=":""}[e])),unurlbase64:e=>s.unbase64(e.replace(/[-_.]/g,e=>({"-":"+",_:"/",".":"="}[e])).padEnd(4*Math.ceil(e.length/4),"=")),safeJson:e=>{try{return JSON.parse(e)}catch{return null}},updateDefaults:(e,t)=>{for(const n in t)void 0===e[n]&&(e[n]=t[n])},copyFunction:(e,t,...n)=>{n.forEach(n=>e[n]=t[n].bind(t))},getFunctionBody:e=>{const t=e.toString();return t.slice(t.indexOf("{")+1,t.lastIndexOf("}")).trim()},makeDom:e=>{e.includes(">\n")&&(e=e.replace(/>\s+<").trim());const t=document.createElement("div");return t.innerHTML=e,t.children[0]},newAvg:()=>{let e=0,t=0,n=0;return{add:s=>(e+=s,t++,n=e/t),get:()=>n,clear:()=>{e=0,t=0,n=0}}},newTimeCount:()=>{let e=0,t=0,n=0;return{start:()=>e=(new Date).getTime(),end:()=>{const s=(new Date).getTime(),a=s-e;return e=s,t+=a,n++,a},avg:()=>t/n}}},a=(e,t)=>t?e.querySelector(t):document.querySelector(e),o=(e,t)=>t?e.querySelectorAll(t):document.querySelectorAll(e);globalThis.Util=s,globalThis.$=a,globalThis.$$=o;let r=null,i=null;const l=e=>r=e,c=e=>i=e,d=new Set;function h(e={},t=null,n=null){const s={},a=new Map,o=new Map,l=(e,t)=>(o.has(e)||o.set(e,new Set),t?o.get(e).add(t):o.get(e).clear(),()=>o.get(e).delete(t)),c=(e,t)=>{o.has(e)&&o.set(e,new Set),o.get(e).delete(t)},h=t||(e=>s[e]),u=n||((e,t)=>s[e]=t);return Object.assign(s,e),new Proxy(s,{get:(e,t)=>"__watch"===t?l:"__unwatch"===t?c:"__isProxy"===t||(r&&(a.has(t)||a.set(t,new Set),a.get(t).add(r),r.node._states||(r.node._states=new Set),r.node._states.add(a)),h(t)),set(e,t,n){if(h(t)!==n&&u(t,n),o.has(t)&&o.get(t).forEach(s=>{const a=s(n);void 0!==a&&(n=a,e[t]=n)}),o.has(null)&&o.get(null).forEach(e=>e(n)),a.has(t)){const e=a.get(t);for(const t of e)t.node.isConnected?i!==t.node&&d.forEach(e=>e(t)):e.delete(t)}return!0}})}globalThis.NewState=h;let u=new URLSearchParams("undefined"!=typeof globalThis&&(null==(n=null==(t=globalThis.location)?void 0:t.hash)?void 0:n.substring(1))||"");const f=h({},e=>s.safeJson(u.get(e)),(e,t)=>{const n=u.get(e),s=void 0===t?void 0:JSON.stringify(t);n===s||null===n&&void 0===s||(void 0===t?u.delete(e):u.set(e,s),globalThis.location.hash="#"+u.toString())});"undefined"!=typeof globalThis&&globalThis.addEventListener("hashchange",()=>{var e;const t=new URLSearchParams((null==(e=globalThis.location.hash)?void 0:e.substring(1))||""),n=new Set([...u.keys(),...t.keys()]);u=t,n.forEach(e=>f[e]=f[e])});const b=h({},e=>s.safeJson(localStorage.getItem(e)),(e,t)=>{const n=localStorage.getItem(e),s=void 0===t?void 0:JSON.stringify(t);n===s||null===n&&void 0===s||(void 0===t?localStorage.removeItem(e):localStorage.setItem(e,s))}),m=h({exitBlocks:0});globalThis.Hash=f,globalThis.LocalStorage=b,globalThis.State=m;let p=!1;const g=e=>{p=e},_=new Map;function y(e,t,n,s){const a={...s||{},...t||{}},o=Object.keys(a),r=Object.values(a),i=e+o.join(",");try{let t=_.get(i);return t||(t=new Function("Hash","LocalStorage","State",...o,e),_.set(i,t)),t.apply(n,[globalThis.Hash,globalThis.LocalStorage,globalThis.State,...r])}catch(a){return p||console.error(a,s,[e,s,t,n]),null}}function A(e,t,n,s){return e.includes("${")?y("return `"+e+"`",t,n,s):y("return "+e,t,n,s)}const v=new Map,E=[],T={getTemplate:e=>document.querySelector(`template[component="${e.toUpperCase()}"]`),register:(e,t,n=null,...s)=>{v.set(e.toUpperCase(),t),"loading"!==document.readyState?T._addTemplate(e,n,s):E.push([e,n,s])},exists:e=>v.has(e.toUpperCase()),getSetupFunction:e=>v.get(e.toUpperCase()),_addTemplate:(e,t,n)=>{if(t){const n=document.createElement("TEMPLATE");n.setAttribute("component",e.toUpperCase()),n.content.appendChild(t),document.body.appendChild(n)}n&&n.forEach(e=>document.body.appendChild(e))},_initPending:()=>{E.forEach(([e,t,n])=>T._addTemplate(e,t,n)),E.length=0}};function N(e,t,n,s={}){e.attributes&&Array.from(e.attributes).forEach(e=>{"class"!==e.name&&("style"===e.name?t.hasAttribute("style")?t.setAttribute("style",`${e.value}; ${t.getAttribute("style")}`):t.setAttribute("style",e.value):t.hasAttribute(e.name)||t.setAttribute(e.name,e.value))}),t.classList.add(...e.classList);const a="TEMPLATE"===t.tagName?t.content:t,o="TEMPLATE"===e.tagName?e.content.childNodes:e.childNodes;Array.from(o).forEach(e=>a.appendChild(e)),e.tagName&&T.exists(e.tagName)&&O(e.tagName,t,n,s)}function O(e,t,n,s={}){if(s[e])return;s[e]=!0,n.thisObj&&Array.from(t.attributes).forEach(e=>{(e.name.startsWith("$")||e.name.startsWith("st-"))&&e.value.includes("this.")&&(e.value=e.value.replace(/\bthis\./g,"this.parent."))});const a=T.getSetupFunction(e),r={};Array.from(t.childNodes).forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("slot")&&(r[e.getAttribute("slot")]=e,e.removeAttribute("slot"))}),t.innerHTML="",t.state=h(t.state||{});const i=T.getTemplate(e);if(i){const e=i.content.cloneNode(!0);if(e.childNodes.length){const a=e.children[0];a&&N(a,t,n,s),o(t,"[slot-id]").forEach(e=>{const t=e.getAttribute("slot-id");r[t]&&(e.removeAttribute("slot-id"),e.innerHTML="",N(r[t],e,n,s))})}}a&&a(t)}let S=(e,t)=>e&&"string"==typeof e?e.replace(/\{(.+?)\}/g,(e,n)=>t.hasOwnProperty(n)?t[n]:e):e;const j=e=>S=e,x=e=>e&&"string"==typeof e&&e.includes("{#")?e.replace(/\{#(.+?)#\}/g,(e,t)=>{const n=t.split("||").map(e=>e.trim()),s={};if(n.length>1){const e=n[0].match(/\{(.+?)\}/g);e&&e.forEach((e,t)=>s[e.substring(1,e.length-1)]=n[t+1]||"")}return S(n[0],s)}):e;if("undefined"!=typeof document)try{document.createElement("div").setAttribute("$t","1")}catch(e){const t=Element.prototype.setAttribute;Element.prototype.setAttribute=function(e,n){return e.startsWith("$")?t.call(this,"st-"+e.substring(1),n):t.call(this,e,n)}}var $;function M(e){e._renderedNodes&&e._renderedNodes.forEach(e=>e.forEach(e=>{e.remove(),e._renderedNodes&&M(e)}))}function w(e){const t=e.node;if(!t.isConnected&&"TEMPLATE"!==t.tagName)return;l(e);let n=e.exp?e.tpl?A(e.tpl,{thisNode:t},t._thisObj||t,t._ref||null):null:e.tpl;if(2===e.exp&&"string"==typeof n)try{n=A(n,{thisNode:t},t._thisObj||t,t._ref||null)}catch(e){}if(l(null),e.prop){const s=e.prop;let a=t;for(let e=0;e{t.parentNode.insertBefore(e,t),e._ref={...t._ref},e._thisObj=t._thisObj}),t._renderedNodes=[t._children]):(M(t),t._renderedNodes=[]);else if("each"===s)if(n&&"object"==typeof n){const e=t.getAttribute("as")||"item",s=t.getAttribute("index")||"index",a=t.getAttribute("key");let o,r;if(n instanceof Map)o=Array.from(n.keys()),r=e=>n.get(e);else if("function"==typeof n[Symbol.iterator]){const e=Array.isArray(n)?n:Array.from(n);o=new Array(e.length);for(let t=0;te[t]}else o=Object.keys(n),r=e=>n[e];t._keyedNodes||(t._keyedNodes=new Map);const i=new Map,l=[];o.forEach((n,o)=>{const c=r(n),d=a?c&&"object"==typeof c?c[a]:c:n,h=null==d||i.has(d)?`st_key_${o}`:d;let u=t._keyedNodes.get(h);u?(t._keyedNodes.delete(h),u.forEach(t=>{t._ref[s]=n,t._ref[e]=c,L(t)})):(u=[],t._children.forEach(a=>{const o=a.cloneNode(!0);o._ref={...t._ref,[s]:n,[e]:c},o._thisObj=t._thisObj,t.parentNode.insertBefore(o,t),u.push(o)})),i.set(h,u),l.push(u)}),t._keyedNodes.forEach(e=>e.forEach(e=>{M(e),e.remove()})),t._keyedNodes=i,t._renderedNodes=l}else M(t),t._renderedNodes=[];else if("bind"===s){if(["INPUT","SELECT","TEXTAREA"].includes(t.tagName)&&!t.hasAttribute("autocomplete")&&t.setAttribute("autocomplete","off"),"checkbox"===t.type){"on"===t.value||n||(y(`${e.tpl} = []`,{thisNode:t},t._thisObj||t,t._ref||{}),n=[]),t._checkboxMultiMode=n instanceof Array;const s=n instanceof Array?n.includes(t.value):!!n;t.checked!==s&&(t.checked=s)}else"radio"===t.type?t.checked!==(t.value===String(n??""))&&(t.checked=t.value===String(n??"")):"value"in t&&"file"!==t.type?Promise.resolve().then(()=>{t.value!==String(n??"")&&(t.value=n)}):t.isContentEditable&&t.innerHTML!==String(n??"")&&(t.innerHTML=n);t.dispatchEvent(new CustomEvent("bind",{bubbles:!1,detail:n}))}else["checked","disabled","readonly"].includes(s)&&(n=!!n),"boolean"==typeof n?n?t.setAttribute(s,""):t.removeAttribute(s):void 0!==n&&("string"!=typeof n&&(n=JSON.stringify(n)),"text"===s?t.textContent=n??"":"html"===s?t.innerHTML=n??"":"IMG"===t.tagName&&"src"===s&&n.includes(".svg")?t.setAttribute("_src",n??""):t.setAttribute(s,n??""))}}function C(e){e.node._bindings||(e.node._bindings=[]),e.node._bindings.push({attr:e.attr,prop:e.prop,tpl:e.tpl,exp:e.exp}),w(e)}$=e=>w(e),d.add($);const L=(e,t={})=>{if(3===e.nodeType){if(e._stTranslated)return;const t=x(e.textContent);return t!==e.textContent&&(e.textContent=t),void(e._stTranslated=!0)}if(1!==e.nodeType)return;if(e._stTranslated||(Array.from(e.attributes).forEach(e=>{if(!e.name.startsWith("$")&&!e.name.startsWith("st-")&&!e.name.startsWith(".")){const t=x(e.value);t!==e.value&&(e.value=t)}}),e._stTranslated=!0),"TEMPLATE"!==e.tagName&&(e.hasAttribute("$if")||e.hasAttribute("$each")||e.hasAttribute("st-if")||e.hasAttribute("st-each"))){const n=document.createElement("TEMPLATE");return Array.from(e.attributes).filter(t=>["$if","$each","st-if","st-each"].includes(t.name)||(e.hasAttribute("$each")||e.hasAttribute("st-each"))&&["as","index"].includes(t.name)).forEach(t=>{n.setAttribute(t.name,t.value),e.removeAttribute(t.name)}),e.parentNode.insertBefore(n,e),n.content.appendChild(e),n._ref=e._ref,void L(n,t)}if("TEMPLATE"===e.tagName&&(e.hasAttribute("$if")||e.hasAttribute("st-if"))&&(e.hasAttribute("$each")||e.hasAttribute("st-each"))){const t=document.createElement("TEMPLATE"),n=Array.from(e.attributes).filter(e=>["$if","$each","st-if","st-each"].includes(e.name)),s=n[n.length-1];t.setAttribute(s.name,s.value),e.removeAttribute(s.name),"$each"!==s.name&&"st-each"!==s.name||Array.from(e.attributes).filter(e=>["as","index"].includes(e.name)).forEach(n=>{t.setAttribute(n.name,n.value),e.removeAttribute(n.name)}),Array.from(e.content.childNodes).forEach(e=>t.content.appendChild(e)),e.content.appendChild(t),t._ref=e._ref}if("IMG"===e.tagName&&(e.hasAttribute("src")||e.hasAttribute("_src")||e.hasAttribute("$src"))){const t=e;Promise.resolve().then(()=>{const e=t.getAttribute("_src")||t.getAttribute("src");e&&fetch(e,{cache:"force-cache"}).then(e=>e.text()).then(e=>{const n=(new DOMParser).parseFromString(e,"image/svg+xml").querySelector("svg");n&&(Array.from(t.attributes).forEach(e=>n.setAttribute(e.name,e.value)),t.replaceWith(n))})})}if(void 0!==e._thisObj)t.thisObj=e._thisObj||null;else{let n=e;for(;n&&void 0===n._thisObj;)n=n.parentNode;t.thisObj=n?n._thisObj:null}if(void 0===e._ref){let t=e;for(;t&&void 0===t._ref;)t=t.parentNode;e._ref=t?{...t._ref}:{}}t.extendVars&&Object.assign(e._ref,t.extendVars),function(e,t){if(e._bindings)return e._states=new Set,e._bindings.forEach(t=>w({node:e,...t})),void(e._hasOnUpdate&&e.dispatchEvent(new Event("update",{bubbles:!1})));T.exists(e.tagName)&&!e._componentInitialized&&(Array.from(e.attributes).forEach(n=>{var s;if(n.name.startsWith("$.")){const a=n.name.slice(2);let o=x(n.value);t.thisObj&&o.includes("this.")&&(o=o.replace(/\bthis\./g,"this.parent."));const r=A(o,{thisNode:e},{parent:t.thisObj||e},e._ref||{});let i=e;const l=a.split(".");for(let e=0;ee.removeAttribute("slot-id")),e._componentInitialized=!0,e._thisObj||(e._thisObj=e)),"TEMPLATE"===e.tagName&&(e._children=[...e.content.childNodes],e._renderedNodes||(e._renderedNodes=[]));let n=[];"TEMPLATE"===e.tagName?["$if","$each","st-if","st-each"].forEach(t=>e.hasAttribute(t)&&n.push(e.getAttributeNode(t))):n=Array.from(e.attributes).filter(e=>(e.name.startsWith("$")||e.name.startsWith("st-"))&&!["$if","$each","st-if","st-each"].includes(e.name)||e.name.includes(".")),e._thisObj&&t.thisObj&&e._thisObj!==t.thisObj&&(e._thisObj.parent=t.thisObj),e._thisObj||(e._thisObj=t.thisObj||null),e._ref||(e._ref=t.extendVars||{}),e._states=new Set,n.forEach(n=>{let s=0;n.name.startsWith("$$")||n.name.startsWith("st-st-")?s=2:(n.name.startsWith("$")||n.name.startsWith("st-"))&&(s=1);const a=2===s?n.name.startsWith("$$")?n.name.slice(2):n.name.slice(6):1===s?n.name.startsWith("$")?n.name.slice(1):n.name.slice(3):n.name;let o=n.value;if(e.removeAttribute(n.name),a.startsWith("."))C({node:e,prop:a.split("."),tpl:o,exp:s});else if(a.startsWith("on")){const n=a.slice(2);"update"===n&&(e._hasOnUpdate=!0),"load"!==n||["BODY","IMG","IFRAME"].includes(e.tagName)||(e._hasOnLoad=!0),"unload"!==n||["BODY","IMG","IFRAME"].includes(e.tagName)||(e._hasOnUnload=!0),e.addEventListener(n,n=>y(o,{event:n,thisNode:e,...n.detail||{}},t.thisObj||e,e._ref||{}))}else"bind"===a?e.addEventListener(["textarea","text","password"].includes(e.type||"text")||e.isContentEditable?"input":"change",n=>{let s=e.isContentEditable?n.target.innerHTML:"checkbox"===e.type?n.target.checked:n.target.files||n.target.value||n.detail;c(e),g(!0),"checkbox"===e.type&&e._checkboxMultiMode?y(`!!checked ? (!${o}.includes(val) && ${o}.push(val)) : (index = ${o}.indexOf(val), index > -1 && ${o}.splice(index, 1))`,{val:e.value,checked:s,thisNode:e},t.thisObj||e,e._ref||{}):y(`${o} = val`,{val:s,thisNode:e},t.thisObj||e,e._ref||{}),g(!1),c(null)}):"text"!==a||o||(o=e.textContent,e.textContent=""),o&&(o=x(o),C({node:e,attr:a,tpl:o,exp:s}))}),(e._hasOnLoad||e._componentInitialized)&&Promise.resolve().then(()=>e.dispatchEvent(new Event("load",{bubbles:!1}))),e._hasOnUpdate&&e.dispatchEvent(new Event("update",{bubbles:!1})),e._thisObj&&(t.thisObj=e._thisObj)}(e,{...t});[...e.childNodes||[]].forEach(n=>L(n,{thisObj:t.thisObj,extendVars:{...e._ref}}))},k=e=>{1===e.nodeType&&(e._hasOnUnload&&e.dispatchEvent(new Event("unload",{bubbles:!1})),e._states&&e._states.forEach(t=>{for(const[n,s]of t)for(const t of s)t.node===e&&s.delete(t)}),e.childNodes&&e.childNodes.forEach(e=>k(e)))};if(globalThis.Component=T,globalThis.SetTranslator=j,globalThis.__unsafeRefreshState=L,"undefined"!=typeof document){const e=()=>{globalThis.Component&&globalThis.Component._initPending&&globalThis.Component._initPending();const e=document.documentElement;e.hasAttribute("$data-bs-theme")||e.hasAttribute("data-bs-theme")||e.setAttribute("$data-bs-theme","LocalStorage.darkMode?'dark':'light'"),new MutationObserver(e=>{e.forEach(e=>{e.addedNodes.forEach(e=>{e.isConnected&&L(e)}),e.removedNodes.forEach(e=>k(e))})}).observe(document.documentElement,{childList:!0,subtree:!0}),L(document.documentElement)};"loading"!==document.readyState?e():document.addEventListener("DOMContentLoaded",e,!0)}const P=L;e.$=a,e.$$=o,e.Component=T,e.Hash=f,e.LocalStorage=b,e.NewState=h,e.SetTranslator=j,e.State=m,e.Util=s,e.__unsafeRefreshState=P,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}); +!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).ApigoState=e.ApigoState||{})}(this,function(e){"use strict";var t,n;const s={clone:globalThis.structuredClone||(e=>JSON.parse(JSON.stringify(e))),base64:e=>btoa(String.fromCharCode(...(new TextEncoder).encode(e))),unbase64:e=>(new TextDecoder).decode(Uint8Array.from(atob(e),e=>e.charCodeAt(0))),urlbase64:e=>s.base64(e).replace(/[+/=]/g,e=>({"+":"-","/":"","=":""}[e])),unurlbase64:e=>s.unbase64(e.replace(/[-_.]/g,e=>({"-":"+",_:"/",".":"="}[e])).padEnd(4*Math.ceil(e.length/4),"=")),safeJson:e=>{try{return JSON.parse(e)}catch{return null}},updateDefaults:(e,t)=>{for(const n in t)void 0===e[n]&&(e[n]=t[n])},copyFunction:(e,t,...n)=>{n.forEach(n=>e[n]=t[n].bind(t))},getFunctionBody:e=>{const t=e.toString();return t.slice(t.indexOf("{")+1,t.lastIndexOf("}")).trim()},makeDom:e=>{e.includes(">\n")&&(e=e.replace(/>\s+<").trim());const t=document.createElement("div");return t.innerHTML=e,t.children[0]},newAvg:()=>{let e=0,t=0,n=0;return{add:s=>(e+=s,t++,n=e/t),get:()=>n,clear:()=>{e=0,t=0,n=0}}},newTimeCount:()=>{let e=0,t=0,n=0;return{start:()=>e=(new Date).getTime(),end:()=>{const s=(new Date).getTime(),a=s-e;return e=s,t+=a,n++,a},avg:()=>t/n}}},a=(e,t)=>t?e.querySelector(t):document.querySelector(e),r=(e,t)=>t?e.querySelectorAll(t):document.querySelectorAll(e);globalThis.Util=s,globalThis.$=a,globalThis.$$=r;let o=null,i=null;const l=e=>o=e,c=e=>i=e,d=new Set;function h(e={},t=null,n=null){const s={},a=new Map,r=new Map,l=(e,t)=>(r.has(e)||r.set(e,new Set),t?r.get(e).add(t):r.get(e).clear(),()=>r.get(e).delete(t)),c=(e,t)=>{r.has(e)&&r.set(e,new Set),r.get(e).delete(t)},h=t||(e=>s[e]),u=n||((e,t)=>s[e]=t);return Object.assign(s,e),new Proxy(s,{get:(e,t)=>"__watch"===t?l:"__unwatch"===t?c:"__isProxy"===t||(o&&(a.has(t)||a.set(t,new Set),a.get(t).add(o),o.node._states||(o.node._states=new Set),o.node._states.add(a)),h(t)),set(e,t,n){if(h(t)!==n&&u(t,n),r.has(t)&&r.get(t).forEach(s=>{const a=s(n);void 0!==a&&(n=a,e[t]=n)}),r.has(null)&&r.get(null).forEach(e=>e(n)),a.has(t)){const e=a.get(t);for(const t of e)t.node.isConnected?i!==t.node&&d.forEach(e=>e(t)):e.delete(t)}return!0}})}globalThis.NewState=h;let u=new URLSearchParams("undefined"!=typeof globalThis&&(null==(n=null==(t=globalThis.location)?void 0:t.hash)?void 0:n.substring(1))||"");const f=h({},e=>s.safeJson(u.get(e)),(e,t)=>{const n=u.get(e),s=void 0===t?void 0:JSON.stringify(t);n===s||null===n&&void 0===s||(void 0===t?u.delete(e):u.set(e,s),globalThis.location.hash="#"+u.toString())});"undefined"!=typeof globalThis&&globalThis.addEventListener("hashchange",()=>{var e;const t=new URLSearchParams((null==(e=globalThis.location.hash)?void 0:e.substring(1))||""),n=new Set([...u.keys(),...t.keys()]);u=t,n.forEach(e=>f[e]=f[e])});const b=h({},e=>s.safeJson(localStorage.getItem(e)),(e,t)=>{const n=localStorage.getItem(e),s=void 0===t?void 0:JSON.stringify(t);n===s||null===n&&void 0===s||(void 0===t?localStorage.removeItem(e):localStorage.setItem(e,s))}),m=h({exitBlocks:0});globalThis.Hash=f,globalThis.LocalStorage=b,globalThis.State=m;let p=!1;const g=e=>{p=e},_=new Map;function y(e,t,n,s){const a={...s||{},...t||{}},r=Object.keys(a),o=Object.values(a),i=e+r.join(",");try{let t=_.get(i);return t||(t=new Function("Hash","LocalStorage","State",...r,e),_.set(i,t)),t.apply(n,[globalThis.Hash,globalThis.LocalStorage,globalThis.State,...o])}catch(a){return p||console.error(a,s,[e,s,t,n]),null}}function A(e,t,n,s){return e.includes("${")?y("return `"+e+"`",t,n,s):y("return "+e,t,n,s)}const E=new Map,v=[],T={getTemplate:e=>document.querySelector(`template[component="${e.toUpperCase()}"]`),register:(e,t,n=null,...s)=>{E.set(e.toUpperCase(),t),"loading"!==document.readyState?T._addTemplate(e,n,s):v.push([e,n,s])},exists:e=>E.has(e.toUpperCase()),getSetupFunction:e=>E.get(e.toUpperCase()),_addTemplate:(e,t,n)=>{if(t){const n=document.createElement("TEMPLATE");n.setAttribute("component",e.toUpperCase()),n.content.appendChild(t),document.body.appendChild(n)}n&&n.forEach(e=>document.body.appendChild(e))},_initPending:()=>{v.forEach(([e,t,n])=>T._addTemplate(e,t,n)),v.length=0}};function N(e,t,n,s={}){e.attributes&&Array.from(e.attributes).forEach(e=>{"class"!==e.name&&("style"===e.name?t.hasAttribute("style")?t.setAttribute("style",`${e.value}; ${t.getAttribute("style")}`):t.setAttribute("style",e.value):t.hasAttribute(e.name)||t.setAttribute(e.name,e.value))}),t.classList.add(...e.classList);const a="TEMPLATE"===t.tagName?t.content:t,r="TEMPLATE"===e.tagName?e.content.childNodes:e.childNodes;Array.from(r).forEach(e=>a.appendChild(e)),e.tagName&&T.exists(e.tagName)&&O(e.tagName,t,n,s)}function O(e,t,n,s={}){if(s[e])return;s[e]=!0,n.thisObj&&Array.from(t.attributes).forEach(e=>{(e.name.startsWith("$")||e.name.startsWith("st-"))&&e.value.includes("this.")&&(e.value=e.value.replace(/\bthis\./g,"this.parent."))});const a=T.getSetupFunction(e),o={};Array.from(t.childNodes).forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("slot")&&(o[e.getAttribute("slot")]=e,e.removeAttribute("slot"))}),t.innerHTML="",t.state=h(t.state||{});const i=T.getTemplate(e);if(i){const e=i.content.cloneNode(!0);if(e.childNodes.length){const a=e.children[0];a&&N(a,t,n,s),r(t,"[slot-id]").forEach(e=>{const t=e.getAttribute("slot-id");o[t]&&(e.removeAttribute("slot-id"),e.innerHTML="",N(o[t],e,n,s))})}}a&&a(t)}let S=(e,t)=>e&&"string"==typeof e?e.replace(/\{(.+?)\}/g,(e,n)=>t.hasOwnProperty(n)?t[n]:e):e;const j=e=>S=e,x=e=>e&&"string"==typeof e&&e.includes("{#")?e.replace(/\{#(.+?)#\}/g,(e,t)=>{const n=t.split("||").map(e=>e.trim()),s={};if(n.length>1){const e=n[0].match(/\{(.+?)\}/g);e&&e.forEach((e,t)=>s[e.substring(1,e.length-1)]=n[t+1]||"")}return S(n[0],s)}):e;if("undefined"!=typeof document)try{document.createElement("div").setAttribute("$t","1")}catch(e){const t=Element.prototype.setAttribute;Element.prototype.setAttribute=function(e,n){return e.startsWith("$")?t.call(this,"st-"+e.substring(1),n):t.call(this,e,n)}}var $;function M(e){e._renderedNodes&&e._renderedNodes.forEach(e=>e.forEach(e=>{e.remove(),e._renderedNodes&&M(e)}))}function w(e){const t=e.node;if(!t.isConnected&&"TEMPLATE"!==t.tagName)return;l(e);let n=e.exp?e.tpl?A(e.tpl,{thisNode:t},t._thisObj||t,t._ref||null):null:e.tpl;if(2===e.exp&&"string"==typeof n)try{n=A(n,{thisNode:t},t._thisObj||t,t._ref||null)}catch(e){}if(l(null),e.prop){const s=e.prop;let a=t;for(let e=0;e{t.parentNode.insertBefore(e,t),e._ref={...t._ref},e._thisObj=t._thisObj}),t._renderedNodes=[t._children]):(M(t),t._renderedNodes=[]);else if("each"===s)if(n&&"object"==typeof n){const e=t.getAttribute("as")||"item",s=t.getAttribute("index")||"index",a=t.getAttribute("key");let r,o;if(n instanceof Map)r=Array.from(n.keys()),o=e=>n.get(e);else if("function"==typeof n[Symbol.iterator]){const e=Array.isArray(n)?n:Array.from(n);r=new Array(e.length);for(let t=0;te[t]}else r=Object.keys(n),o=e=>n[e];t._keyedNodes||(t._keyedNodes=new Map);const i=new Map,l=[];r.forEach((n,r)=>{const c=o(n),d=a?c&&"object"==typeof c?c[a]:c:n,h=null==d||i.has(d)?`st_key_${r}`:d;let u=t._keyedNodes.get(h);u?(t._keyedNodes.delete(h),u.forEach(t=>{t._ref[s]=n,t._ref[e]=c,L(t)})):(u=[],t._children.forEach(a=>{const r=a.cloneNode(!0);r._ref={...t._ref,[s]:n,[e]:c},r._thisObj=t._thisObj,t.parentNode.insertBefore(r,t),u.push(r)})),i.set(h,u),l.push(u)}),t._keyedNodes.forEach(e=>e.forEach(e=>{M(e),e.remove()})),t._keyedNodes=i,t._renderedNodes=l}else M(t),t._renderedNodes=[];else if("bind"===s){if(["INPUT","SELECT","TEXTAREA"].includes(t.tagName)&&!t.hasAttribute("autocomplete")&&t.setAttribute("autocomplete","off"),"checkbox"===t.type){"on"===t.value||n||(y(`${e.tpl} = []`,{thisNode:t},t._thisObj||t,t._ref||{}),n=[]),t._checkboxMultiMode=n instanceof Array;const s=n instanceof Array?n.includes(t.value):!!n;t.checked!==s&&(t.checked=s)}else"radio"===t.type?t.checked!==(t.value===String(n??""))&&(t.checked=t.value===String(n??"")):"value"in t&&"file"!==t.type?Promise.resolve().then(()=>{t.value!==String(n??"")&&(t.value=n)}):t.isContentEditable&&t.innerHTML!==String(n??"")&&(t.innerHTML=n);t.dispatchEvent(new CustomEvent("bind",{bubbles:!1,detail:n}))}else["checked","disabled","readonly"].includes(s)&&(n=!!n),"boolean"==typeof n?n?t.setAttribute(s,""):t.removeAttribute(s):void 0!==n&&("string"!=typeof n&&(n=JSON.stringify(n)),"text"===s?t.textContent=n??"":"html"===s?t.innerHTML=n??"":"IMG"===t.tagName&&"src"===s&&n.includes(".svg")?t.setAttribute("_src",n??""):t.setAttribute(s,n??""))}}function C(e){e.node._bindings||(e.node._bindings=[]),e.node._bindings.push({attr:e.attr,prop:e.prop,tpl:e.tpl,exp:e.exp}),w(e)}$=e=>w(e),d.add($);const L=(e,t={})=>{if(3===e.nodeType){if(e._stTranslated)return;const t=x(e.textContent);return t!==e.textContent&&(e.textContent=t),void(e._stTranslated=!0)}if(1!==e.nodeType)return;if(e._stTranslated||(Array.from(e.attributes).forEach(e=>{if(!e.name.startsWith("$")&&!e.name.startsWith("st-")&&!e.name.startsWith(".")){const t=x(e.value);t!==e.value&&(e.value=t)}}),e._stTranslated=!0),"TEMPLATE"!==e.tagName&&(e.hasAttribute("$if")||e.hasAttribute("$each")||e.hasAttribute("st-if")||e.hasAttribute("st-each"))){const n=document.createElement("TEMPLATE");return Array.from(e.attributes).filter(t=>["$if","$each","st-if","st-each"].includes(t.name)||(e.hasAttribute("$each")||e.hasAttribute("st-each"))&&["as","index"].includes(t.name)).forEach(t=>{n.setAttribute(t.name,t.value),e.removeAttribute(t.name)}),e.parentNode.insertBefore(n,e),n.content.appendChild(e),n._ref=e._ref,void L(n,t)}if("TEMPLATE"===e.tagName&&(e.hasAttribute("$if")||e.hasAttribute("st-if"))&&(e.hasAttribute("$each")||e.hasAttribute("st-each"))){const t=document.createElement("TEMPLATE"),n=Array.from(e.attributes).filter(e=>["$if","$each","st-if","st-each"].includes(e.name)),s=n[n.length-1];t.setAttribute(s.name,s.value),e.removeAttribute(s.name),"$each"!==s.name&&"st-each"!==s.name||Array.from(e.attributes).filter(e=>["as","index"].includes(e.name)).forEach(n=>{t.setAttribute(n.name,n.value),e.removeAttribute(n.name)}),Array.from(e.content.childNodes).forEach(e=>t.content.appendChild(e)),e.content.appendChild(t),t._ref=e._ref}if("IMG"===e.tagName&&(e.hasAttribute("src")||e.hasAttribute("_src")||e.hasAttribute("$src"))){const t=e;Promise.resolve().then(()=>{const e=t.getAttribute("_src")||t.getAttribute("src");e&&fetch(e,{cache:"force-cache"}).then(e=>e.text()).then(e=>{const n=(new DOMParser).parseFromString(e,"image/svg+xml").querySelector("svg");n&&(Array.from(t.attributes).forEach(e=>n.setAttribute(e.name,e.value)),t.replaceWith(n))})})}if(void 0!==e._thisObj)t.thisObj=e._thisObj||null;else{let n=e;for(;n&&void 0===n._thisObj;)n=n.parentNode;t.thisObj=n?n._thisObj:null}if(void 0===e._ref){let t=e;for(;t&&void 0===t._ref;)t=t.parentNode;e._ref=t?{...t._ref}:{}}t.extendVars&&Object.assign(e._ref,t.extendVars),function(e,t){if(e._bindings)return e._states=new Set,e._bindings.forEach(t=>w({node:e,...t})),void(e._hasOnUpdate&&e.dispatchEvent(new Event("update",{bubbles:!1})));T.exists(e.tagName)&&!e._componentInitialized&&(Array.from(e.attributes).forEach(n=>{var s;if(n.name.startsWith("$.")){const a=n.name.slice(2);let r=x(n.value);t.thisObj&&r.includes("this.")&&(r=r.replace(/\bthis\./g,"this.parent."));const o=A(r,{thisNode:e},{parent:t.thisObj||e},e._ref||{});let i=e;const l=a.split(".");for(let e=0;ee.removeAttribute("slot-id")),e._componentInitialized=!0,e._thisObj||(e._thisObj=e)),"TEMPLATE"===e.tagName&&(e._children=[...e.content.childNodes],e._renderedNodes||(e._renderedNodes=[]));let n=[];"TEMPLATE"===e.tagName?["$if","$each","st-if","st-each"].forEach(t=>e.hasAttribute(t)&&n.push(e.getAttributeNode(t))):n=Array.from(e.attributes).filter(e=>(e.name.startsWith("$")||e.name.startsWith("st-"))&&!["$if","$each","st-if","st-each"].includes(e.name)||e.name.includes(".")),e._thisObj&&t.thisObj&&e._thisObj!==t.thisObj&&(e._thisObj.parent=t.thisObj),e._thisObj||(e._thisObj=t.thisObj||null),e._ref||(e._ref=t.extendVars||{}),e._states=new Set,n.forEach(n=>{let s=0;n.name.startsWith("$$")||n.name.startsWith("st-st-")?s=2:(n.name.startsWith("$")||n.name.startsWith("st-"))&&(s=1);const a=2===s?n.name.startsWith("$$")?n.name.slice(2):n.name.slice(6):1===s?n.name.startsWith("$")?n.name.slice(1):n.name.slice(3):n.name;let r=n.value;if(e.removeAttribute(n.name),a.startsWith("."))C({node:e,prop:a.split("."),tpl:r,exp:s});else if(a.startsWith("on")){const n=a.slice(2);"update"===n&&(e._hasOnUpdate=!0),"load"!==n||["BODY","IMG","IFRAME"].includes(e.tagName)||(e._hasOnLoad=!0),"unload"!==n||["BODY","IMG","IFRAME"].includes(e.tagName)||(e._hasOnUnload=!0),e.addEventListener(n,n=>y(r,{event:n,thisNode:e,...n.detail||{}},t.thisObj||e,e._ref||{}))}else{if("bind"===a){const n=["INPUT","TEXTAREA"].includes(e.tagName)&&["textarea","text","password","email","number","search","url","tel"].includes(e.type||"text")||e.isContentEditable;e.addEventListener(n?"input":"change",n=>{let s=e.isContentEditable?n.target.innerHTML:"checkbox"===e.type?n.target.checked:n.target.files||n.target.value||n.detail;c(e),g(!0),"checkbox"===e.type&&e._checkboxMultiMode?y(`!!checked ? (!${r}.includes(val) && ${r}.push(val)) : (index = ${r}.indexOf(val), index > -1 && ${r}.splice(index, 1))`,{val:e.value,checked:s,thisNode:e},t.thisObj||e,e._ref||{}):y(`${r} = val`,{val:s,thisNode:e},t.thisObj||e,e._ref||{}),g(!1),c(null)})}else"text"!==a||r||(r=e.textContent,e.textContent="");r&&(r=x(r),C({node:e,attr:a,tpl:r,exp:s}))}}),(e._hasOnLoad||e._componentInitialized)&&Promise.resolve().then(()=>e.dispatchEvent(new Event("load",{bubbles:!1}))),e._hasOnUpdate&&e.dispatchEvent(new Event("update",{bubbles:!1})),e._thisObj&&(t.thisObj=e._thisObj)}(e,{...t});[...e.childNodes||[]].forEach(n=>L(n,{thisObj:t.thisObj,extendVars:{...e._ref}}))},k=e=>{1===e.nodeType&&(e._hasOnUnload&&e.dispatchEvent(new Event("unload",{bubbles:!1})),e._states&&e._states.forEach(t=>{for(const[n,s]of t)for(const t of s)t.node===e&&s.delete(t)}),e.childNodes&&e.childNodes.forEach(e=>k(e)))};if(globalThis.Component=T,globalThis.SetTranslator=j,globalThis.__unsafeRefreshState=L,"undefined"!=typeof document){const e=()=>{globalThis.Component&&globalThis.Component._initPending&&globalThis.Component._initPending();const e=document.documentElement;e.hasAttribute("$data-bs-theme")||e.hasAttribute("data-bs-theme")||e.setAttribute("$data-bs-theme","LocalStorage.darkMode?'dark':'light'"),new MutationObserver(e=>{e.forEach(e=>{e.addedNodes.forEach(e=>{e.isConnected&&L(e)}),e.removedNodes.forEach(e=>k(e))})}).observe(document.documentElement,{childList:!0,subtree:!0}),L(document.documentElement)};"loading"!==document.readyState?e():document.addEventListener("DOMContentLoaded",e,!0)}const P=L;e.$=a,e.$$=r,e.Component=T,e.Hash=f,e.LocalStorage=b,e.NewState=h,e.SetTranslator=j,e.State=m,e.Util=s,e.__unsafeRefreshState=P,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}); diff --git a/package-lock.json b/package-lock.json index 905bdde..79dd4f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@apigo.cc/state", - "version": "1.0.18", + "version": "1.0.19", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@apigo.cc/state", - "version": "1.0.18", + "version": "1.0.19", "devDependencies": { "@playwright/test": "^1.40.0", "@rollup/plugin-terser": "^1.0.0", diff --git a/package.json b/package.json index 4f11441..cfacdac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apigo.cc/state", - "version": "1.0.18", + "version": "1.0.20", "type": "module", "main": "dist/state.js", "module": "dist/state.js", diff --git a/src/engine.js b/src/engine.js index ff03d8b..e304036 100644 --- a/src/engine.js +++ b/src/engine.js @@ -335,7 +335,8 @@ export function _parseNode(node, scanObj) { node.addEventListener(eventName, (e) => _runCode(tpl, { event: e, thisNode: node, ...(e.detail || {}) }, scanObj.thisObj || node, node._ref || {})); } else { if (realAttrName === 'bind') { - node.addEventListener(['textarea', 'text', 'password'].includes(node.type || 'text') || node.isContentEditable ? 'input' : 'change', (e) => { + const isTextInput = (['INPUT', 'TEXTAREA'].includes(node.tagName) && ['textarea', 'text', 'password', 'email', 'number', 'search', 'url', 'tel'].includes(node.type || 'text')) || node.isContentEditable; + node.addEventListener(isTextInput ? 'input' : 'change', (e) => { let newVal = node.isContentEditable ? e.target.innerHTML : (node.type === 'checkbox' ? e.target.checked : e.target.files || e.target.value || e.detail); _setNoWriteBack(node); setDisableRunCodeError(true); if (node.type === 'checkbox' && node._checkboxMultiMode) _runCode(`!!checked ? (!${tpl}.includes(val) && ${tpl}.push(val)) : (index = ${tpl}.indexOf(val), index > -1 && ${tpl}.splice(index, 1))`, { val: node.value, checked: newVal, thisNode: node }, scanObj.thisObj || node, node._ref || {});