@polight/lego
Version:
Tiny Web-Components lib for future-proof HTML mentors
2 lines (1 loc) • 7.8 kB
JavaScript
const e={},t=1,n=2,i=4,r=e=>null===e||Array.isArray(e)&&0===e.length,s=e=>Array.isArray(e)&&e.length>0,o=e=>"string"==typeof e||"number"==typeof e,c=e=>e?.vtype===t,l=e=>e?.vtype===n,d=e=>e?.vtype===i,u=e=>"function"==typeof e?.mount;function h(r,s,...o){return s=s??e,function(e,r,s){if(s!=s)throw new Error("Invalid NaN key");const o="string"==typeof e?t:u(e)?i:"function"==typeof e?n:void 0;if(void 0===o)throw new Error("Invalid VNode type");return{vtype:o,type:e,key:s,props:r}}(r,s=o.length>1?Object.assign({},s,{children:o}):1===o.length?Object.assign({},s,{children:o[0]}):s,s.key)}const f=1,p=4,a=8,y="http://www.w3.org/2000/svg";function v(e){return{mount(t,n){t[e]=n},patch(t,n,i){n!==i&&(t[e]=n)},unmount(t,n){t[e]=null}}}const w={selected:v("selected"),checked:v("checked"),value:v("value"),innerHTML:v("innerHTML")},_="http://www.w3.org/1999/xlink",g={show:_,actuate:_,href:_};function m(e){if(e.type===f)return e.node;if(e.type===p)return m(e.children[0]);if(e.type===a)return m(e.childRef);throw new Error("Unkown ref type "+JSON.stringify(e))}function S(e){if(e.type===f)return e.node.parentNode;if(e.type===p)return S(e.children[0]);if(e.type===a)return S(e.childRef);throw new Error("Unkown ref type "+e)}function b(e){if(e.type===f)return e.node.nextSibling;if(e.type===p)return b(e.children[e.children.length-1]);if(e.type===a)return b(e.childRef);throw new Error("Unkown ref type "+JSON.stringify(e))}function k(e,t,n){if(t.type===f)e.insertBefore(t.node,n);else if(t.type===p)t.children.forEach((t=>{k(e,t,n)}));else{if(t.type!==a)throw new Error("Unkown ref type "+JSON.stringify(t));k(e,t.childRef,n)}}function E(e,t){if(t.type===f)e.removeChild(t.node);else if(t.type===p)t.children.forEach((t=>{E(e,t)}));else{if(t.type!==a)throw new Error("Unkown ref type "+t);E(e,t.childRef)}}function A(e,t,n,i){if(!0===n)e.setAttribute(t,"");else if(!1===n)e.removeAttribute(t);else{var r=i?g[t]:void 0;void 0!==r?e.setAttributeNS(r,t,n):e.setAttribute(t,n)}}const N={isSvg:!1,directives:w};class O{constructor(e,t){this.props=e,this._STATE_={env:t,vnode:null,parentDomNode:null,ref:T(null)},this.render=this.render.bind(this)}setProps(e){this.oldProps=this.props,this.props=e}render(e){const t=this._STATE_,n=t.vnode;if(t.vnode=e,null==t.parentDomNode){let n=S(t.ref);if(null==n)return void(t.ref=T(e,t.env));t.parentDomNode=n}t.ref=j(t.parentDomNode,e,n,t.ref,t.env)}}function T(e,t=N){if(r(e))return{type:f,node:document.createComment("NULL")};if(o(e))return{type:f,node:document.createTextNode(e)};if(c(e)){let n,{type:i,props:r}=e;"svg"!==i||t.isSvg||(t=Object.assign({},t,{isSVG:!0})),n=t.isSVG?document.createElementNS(y,i):document.createElement(i),function(e,t,n){for(var i in t)"key"===i||"children"===i||i in n.directives||(i.startsWith("on")?e[i.toLowerCase()]=t[i]:A(e,i,t[i],n.isSVG))}(n,r,t);let s=null==r.children?r.children:T(r.children,t);return null!=s&&k(n,s),function(e,t,n){for(let i in t)i in n.directives&&n.directives[i].mount(e,t[i])}(n,r,t),{type:f,node:n,children:s}}if(s(e))return{type:p,children:e.map((e=>T(e,t)))};if(l(e)){let n=e.type(e.props),i=T(n,t);return{type:a,childRef:i,childState:n}}if(d(e)){let n=new O(e.props,t);return e.type.mount(n),{type:a,childRef:n._STATE_.ref,childState:n}}if(e instanceof Node)return{type:f,node:e};if(void 0===e)throw new Error("mount: vnode is undefined!");throw new Error("mount: Invalid Vnode!")}function C(e,t,n,i,u=N){if(n===t)return i;if(r(t)&&r(n))return i;if(o(t)&&o(n))return i.node.nodeValue=t,i;if(c(t)&&c(n)&&t.type===n.type){"svg"!==t.type||u.isSvg||(u=Object.assign({},u,{isSVG:!0})),function(e,t,n,i){for(var r in t)if("key"!==r&&"children"!==r&&!(r in i.directives)){var s=n[r],o=t[r];s!==o&&(r.startsWith("on")?e[r.toLowerCase()]=o:A(e,r,o,i.isSVG))}for(r in n)"key"===r||"children"===r||r in i.directives||r in t||(r.startsWith("on")?e[r.toLowerCase()]=null:e.removeAttribute(r))}(i.node,t.props,n.props,u);let e=n.props.children,r=t.props.children;return null==e?null!=r&&(i.children=T(r,u),k(i.node,i.children)):null==r?(i.node.textContent="",R(e,i.children,u),i.children=null):i.children=j(i.node,r,e,i.children,u),function(e,t,n,i){for(let r in t)r in i.directives&&i.directives[r].patch(e,t[r],n[r]);for(let r in n)r in i.directives&&!(r in t)&&i.directives[r].unmount(e,n[r])}(i.node,t.props,n.props,u),i}if(s(t)&&s(n))return function(e,t,n,i,r){const s=b(i),o=Array(t.length);let c,l,d,u,h,f=i.children,p=0,a=0,y=t.length-1,v=n.length-1;for(;p<=y&&a<=v;){if(null===f[a]){a++;continue}if(null===f[v]){v--;continue}if(c=n[a],l=t[p],l?.key===c?.key){d=f[a],u=o[p]=j(e,l,c,d,r),p++,a++;continue}if(c=n[v],l=t[y],l?.key===c?.key){d=f[v],u=o[y]=j(e,l,c,d,r),y--,v--;continue}if(null==h){h={};for(let e=a;e<=v;e++)c=n[e],null!=c?.key&&(h[c.key]=e)}l=t[p];const i=null!=l?.key?h[l.key]:null;null!=i?(c=n[i],d=f[i],u=o[p]=C(e,l,c,d,r),k(e,u,m(f[a])),u!==d&&(E(e,d),R(c,d,r)),f[i]=null):(u=o[p]=T(l,r),k(e,u,m(f[a]))),p++}const w=y<t.length-1?m(o[y+1]):s;for(;p<=y;){const n=T(t[p],r);o[p]=n,k(e,n,w),p++}for(;a<=v;)d=f[a],null!=d&&(E(e,d),R(n[a],d,r)),a++;i.children=o}(e,t,n,i,u),i;if(l(t)&&l(n)&&t.type===n.type){let r=t.type;if(null!=r.shouldUpdate?r.shouldUpdate(n.props,t.props):function(e,t){if(e===t)return!1;for(let n in t)if(e[n]!==t[n])return!0;return!1}(n.props,t.props)){let n=r(t.props),s=C(e,n,i.childState,i.childRef,u);return s!==i.childRef?{type:a,childRef:s,childState:n}:(i.childState=n,i)}return i}if(d(t)&&d(n)&&t.type===n.type){const n=i.childState,r=n._STATE_;return r.env=u,r.parentNode=e,n.setProps(t.props),t.type.patch(n),i.childRef!==r.ref?{type:a,childRef:r.ref,childState:n}:i}return t instanceof Node&&n instanceof Node?(i.node=t,i):T(t,u)}function R(e,t,n){c(e)?(!function(e,t,n){for(let i in t)i in n.directives&&n.directives[i].unmount(e,t[i])}(t.node,e.props,n),null!=e.props.children&&R(e.props.children,t.children,n)):s(e)?e.forEach(((e,i)=>R(e,t.children[i],n))):l(e)?R(t.childState,t.childRef,n):d(e)&&e.type.unmount(t.childState)}function j(e,t,n,i,r){const s=C(e,t,n,i,r);return s!==i&&(!function(e,t,n){k(e,t,m(n)),E(e,n)}(e,s,i),R(n,i,r)),s}function U(e,t,n={}){let i=t.$$PETIT_DOM_REF,r=Object.assign({},N);if(Object.assign(r.directives,n.directives),null==i){const n=T(e,r);t.$$PETIT_DOM_REF={ref:n,vnode:e},t.textContent="",k(t,n,null)}else i.ref=j(t,e,i.vnode,i.ref,r),i.vnode=e}function D(e){if(e.includes("-")){const t=e.split("-");e=t[0]+t.splice(1).map((e=>e[0].toUpperCase()+e.substr(1))).join("")}return e}class L extends HTMLElement{constructor(){super(),this.useShadowDOM=!0,this.__isConnected=!1,this.__state={},this.init&&this.init(),this.watchProps=Object.keys(this.__state),this.__attributesToState(),this.document=this.useShadowDOM?this.attachShadow({mode:"open"}):this}__attributesToState(){Object.assign(this.state,Array.from(this.attributes).reduce(((e,t)=>Object.assign(e,{[D(t.name)]:t.value})),{}))}get vdom(){return({state:e})=>""}get vstyle(){return({state:e})=>""}setAttribute(e,t){super.setAttribute(e,t);const n=D(e);this.watchProps.includes(n)&&this.render({[n]:t})}removeAttribute(e){super.removeAttribute(e);const t=D(e);this.watchProps.includes(t)&&t in this.state&&(this.render({[t]:null}),delete this.state[t])}connectedCallback(){this.__isConnected=!0,this.render(),this.connected&&this.connected()}disconnectedCallback(){this.__isConnected=!1,this.setState({}),this.disconnected&&this.disconnected()}setState(e={}){const t=Object.keys(e).reduce(((e,t)=>Object.assign(e,{[t]:this.__state[t]})),{});Object.assign(this.__state,e),this.changed&&this.__isConnected&&this.changed(e,t)}set state(e){this.setState(e)}get state(){return this.__state}render(e){if(this.setState(e),this.__isConnected)return U([this.vdom({state:this.__state}),this.vstyle({state:this.__state})],this.document)}}export{L as Component,h,U as render};