1 line
8.2 KiB
JavaScript
1 line
8.2 KiB
JavaScript
const isFunc=e=>"function"==typeof e,isObj=e=>e&&"object"==typeof e,isArr=Array.isArray,doc="undefined"!=typeof document?document:null,ensureNode=e=>e?._isRuntime?e.container:e instanceof Node?e:doc.createTextNode(null==e?"":String(e));let activeEffect=null,activeOwner=null,isFlushing=!1;const effectQueue=new Set,MOUNTED_NODES=new WeakMap,dispose=e=>{if(!e||e._disposed)return;e._disposed=!0;const t=[e];for(;t.length;){const e=t.pop();e._cleanups&&(e._cleanups.forEach((e=>e())),e._cleanups.clear()),e._children&&(e._children.forEach((e=>t.push(e))),e._children.clear()),e._deps&&(e._deps.forEach((t=>t.delete(e))),e._deps.clear())}},onUnmount=e=>{activeOwner&&(activeOwner._cleanups||=new Set).add(e)},createEffect=(e,t=!1)=>{const n=()=>{if(n._disposed)return;n._deps&&n._deps.forEach((e=>e.delete(n))),n._cleanups&&(n._cleanups.forEach((e=>e())),n._cleanups.clear());const o=activeEffect,r=activeOwner;activeEffect=activeOwner=n;try{const c=t?e():void e();return t||(n._result=c),c}finally{activeEffect=o,activeOwner=r}};return n._deps=n._cleanups=n._children=null,n._disposed=!1,n._isComputed=t,n._depth=activeEffect?activeEffect._depth+1:0,n._mounts=[],n._parent=activeOwner,activeOwner&&(activeOwner._children||=new Set).add(n),n},flush=()=>{if(isFlushing)return;isFlushing=!0;const e=Array.from(effectQueue).sort(((e,t)=>e._depth-t._depth));effectQueue.clear();for(const t of e)t._disposed||t();isFlushing=!1},trackUpdate=(e,t=!1)=>{if(t||!activeEffect||activeEffect._disposed){if(t){let t=!1;e.forEach((e=>{e===activeEffect||e._disposed||(e._isComputed?(e._dirty=!0,e._subs&&trackUpdate(e._subs,!0)):(effectQueue.add(e),t=!0))})),t&&!isFlushing&&queueMicrotask(flush)}}else e.add(activeEffect),(activeEffect._deps||=new Set).add(e)},untrack=e=>{const t=activeEffect;activeEffect=null;try{return e()}finally{activeEffect=t}},onMount=e=>{activeOwner&&(activeOwner._mounts||=[]).push(e)},$=(e,t=null)=>{const n=new Set;if(isFunc(e)){let t,o=!0;const r=()=>{if(o){const c=activeEffect;activeEffect=r;try{const r=e();Object.is(t,r)||(t=r,o=!1,trackUpdate(n,!0))}finally{activeEffect=c}}return trackUpdate(n),t};return r._isComputed=!0,r._subs=n,r._dirty=!0,r._deps=null,r._disposed=!1,r.markDirty=()=>{o=!0},r.stop=()=>{r._disposed=!0,r._deps&&(r._deps.forEach((e=>e.delete(r))),r._deps.clear()),n.clear()},activeOwner&&onUnmount(r.stop),r}if(t)try{e=JSON.parse(localStorage.getItem(t))??e}catch(e){}return(...o)=>{if(o.length){const r=isFunc(o[0])?o[0](e):o[0];Object.is(e,r)||(e=r,t&&localStorage.setItem(t,JSON.stringify(e)),trackUpdate(n,!0))}return trackUpdate(n),e}},Watch=(e,t)=>{if(void 0===t){const t=createEffect(e);return t(),()=>dispose(t)}const n=createEffect((()=>{const n=Array.isArray(e)?e.map((e=>e())):e();untrack((()=>t(n)))}));return n(),()=>dispose(n)},cleanupNode=e=>{e._cleanups&&(e._cleanups.forEach((e=>e())),e._cleanups.clear()),e._ownerEffect&&dispose(e._ownerEffect),e.childNodes&&e.childNodes.forEach(cleanupNode)},DANGEROUS_PROTOCOL=/^\s*(javascript|data|vbscript):/i,isDangerousAttr=e=>"src"===e||"href"===e||e.startsWith("on"),validateAttr=(e,t)=>{if(null==t||!1===t)return null;if(isDangerousAttr(e)){const e=String(t);if(DANGEROUS_PROTOCOL.test(e))return"#"}return t},Tag=(e,t={},n=[])=>{var o;if((t instanceof Node||isArr(t)||(!(o=t)||"object"!=typeof o))&&(n=t,t={}),isFunc(e)){const o={_mounts:[],_cleanups:new Set},r=createEffect((()=>{const o=e(t,{children:n,emit:(e,...n)=>t[`on${e[0].toUpperCase()}${e.slice(1)}`]?.(...n)});return r._result=o,o}));r(),o._mounts=r._mounts||[],o._cleanups=r._cleanups||new Set;const c=r._result,s=e=>e&&"object"==typeof e&&!e._isRuntime&&(e._mounts=o._mounts,e._cleanups=o._cleanups,e._ownerEffect=r);return isArr(c)?c.forEach(s):s(c),null==c?null:c instanceof Node||isArr(c)&&c.every((e=>e instanceof Node))?c:doc.createTextNode(String(c))}const r=/^(svg|path|circle|rect|line|polyline|polygon|g|defs|text|tspan|use)$/.test(e),c=r?doc.createElementNS("http://www.w3.org/2000/svg",e):doc.createElement(e);c._cleanups=new Set;for(let e in t){if(!t.hasOwnProperty(e))continue;let n=t[e];if("ref"!==e)if(e.startsWith("on")){const t=e.slice(2).toLowerCase();c.addEventListener(t,n);const o=()=>c.removeEventListener(t,n);c._cleanups.add(o),onUnmount(o)}else if(isFunc(n)){const t=createEffect((()=>{const t=validateAttr(e,n());"class"===e?c.className=t||"":null==t?c.removeAttribute(e):e in c&&!r?c[e]=t:c.setAttribute(e,!0===t?"":t)}));if(t(),c._cleanups.add((()=>dispose(t))),onUnmount((()=>dispose(t))),/^(INPUT|TEXTAREA|SELECT)$/.test(c.tagName)&&("value"===e||"checked"===e)){const t="checked"===e?"change":"input";c.addEventListener(t,(t=>n(t.target[e])))}}else{const t=validateAttr(e,n);null!=t&&(e in c&&!r?c[e]=t:c.setAttribute(e,!0===t?"":t))}else isFunc(n)?n(c):n.current=c}const s=e=>{if(isArr(e))return e.forEach(s);if(isFunc(e)){const t=doc.createTextNode("");c.appendChild(t);let n=[];const o=createEffect((()=>{const o=e(),r=(isArr(o)?o:[o]).map(ensureNode);n.forEach((e=>{e._isRuntime?e.destroy():cleanupNode(e),e.parentNode&&e.remove()}));let c=t;for(let e=r.length-1;e>=0;e--){const t=r[e];t.parentNode!==c.parentNode&&c.parentNode?.insertBefore(t,c),t._mounts&&t._mounts.forEach((e=>e())),c=t}n=r}));o(),c._cleanups.add((()=>dispose(o))),onUnmount((()=>dispose(o)))}else{const t=ensureNode(e);c.appendChild(t),t._mounts&&t._mounts.forEach((e=>e()))}};return s(n),c},Render=e=>{const t=new Set,n=[],o=activeOwner,r=doc.createElement("div");r.style.display="contents",r.setAttribute("role","presentation"),activeOwner={_cleanups:t,_mounts:n};const c=e=>{e&&(e._isRuntime?(t.add(e.destroy),r.appendChild(e.container)):isArr(e)?e.forEach(c):r.appendChild(e instanceof Node?e:doc.createTextNode(String(null==e?"":e))))};try{c(e({onCleanup:e=>t.add(e)}))}finally{activeOwner=o}return n.forEach((e=>e())),{_isRuntime:!0,container:r,destroy:()=>{t.forEach((e=>e())),cleanupNode(r),r.remove()}}},If=(e,t,n=null,o=null)=>{const r=doc.createTextNode(""),c=Tag("div",{style:"display:contents"},[r]);let s=null,a=null;return Watch((()=>!!(isFunc(e)?e():e)),(e=>{if(e===a)return;a=e;const i=()=>{s&&(s.destroy(),s=null)};s&&!e&&o?.out?o.out(s.container,i):i();const l=e?t:n;l&&(s=Render((()=>isFunc(l)?l():l)),c.insertBefore(s.container,r),o?.in&&o.in(s.container))})),c},For=(e,t,n)=>{const o=doc.createTextNode(""),r=Tag("div",{style:"display:contents"},[o]);let c=new Map;return Watch((()=>(isFunc(e)?e():e)||[]),(e=>{const s=new Map,a=[],i=e||[];for(let e=0;e<i.length;e++){const o=i[e],r=n?n(o,e):o?.id??e;let l=c.get(r);l?c.delete(r):l=Render((()=>t(o,e))),s.set(r,l),a.push(l)}c.forEach((e=>e.destroy()));let l=o;for(let e=a.length-1;e>=0;e--){const t=a[e].container;t.nextSibling!==l&&r.insertBefore(t,l),l=t}c=s})),r},Router=e=>{const t=()=>window.location.hash.slice(1)||"/",n=$(t()),o=()=>n(t());window.addEventListener("hashchange",o),onUnmount((()=>window.removeEventListener("hashchange",o)));const r=Tag("div",{class:"router-outlet"});let c=null;return Watch([n],(()=>{const t=n(),o=e.find((e=>{const n=e.path.split("/").filter(Boolean),o=t.split("/").filter(Boolean);return n.length===o.length&&n.every(((e,t)=>":"===e[0]||e===o[t]))}))||e.find((e=>"*"===e.path));if(o){c?.destroy();const e={};o.path.split("/").filter(Boolean).forEach(((n,o)=>{":"===n[0]&&(e[n.slice(1)]=t.split("/").filter(Boolean)[o])})),Router.params(e),c=Render((()=>isFunc(o.component)?o.component(e):o.component)),r.replaceChildren(c.container)}})),r};Router.params=$({}),Router.to=e=>window.location.hash=e.replace(/^#?\/?/,"#/"),Router.back=()=>window.history.back(),Router.path=()=>window.location.hash.replace(/^#/,"")||"/";const Mount=(e,t)=>{const n="string"==typeof t?doc.querySelector(t):t;if(!n)return;MOUNTED_NODES.has(n)&&MOUNTED_NODES.get(n).destroy();const o=Render(isFunc(e)?e:()=>e);return n.replaceChildren(o.container),MOUNTED_NODES.set(n,o),o},SigPro=Object.freeze({$:$,Watch:Watch,Tag:Tag,Render:Render,If:If,For:For,Router:Router,Mount:Mount,onMount:onMount,onUnmount:onUnmount});"undefined"!=typeof window&&(Object.assign(window,SigPro),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer ul ol li a em strong pre code form label input textarea select button img svg".split(" ").forEach((e=>window[e[0].toUpperCase()+e.slice(1)]=(t,n)=>SigPro.Tag(e,t,n))));export{$,Watch,Tag,Render,If,For,Router,Mount,onMount,onUnmount};export default SigPro; |