-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpop.min.js
2 lines (2 loc) · 6.3 KB
/
pop.min.js
1
2
// prettier-ignore
const POP={create:(e,t=[],n={})=>{const o=Array.isArray(n)&&n.length?n:t;if(o&&Array.isArray(o)&&o.length&&o.forEach((e,t)=>{e||(o[t]=" ")}),typeof e===constants.createPOPElementTagType)return{tag:e,props:!Array.isArray(t)&&Object.keys(t).length?t:n,children:o}},getState:e=>{if(!e)throw new Error(constants.accessKeyInvalidError);return dom.state[e]?{...dom.state[e]}:{}},use:(e,t=[],n={})=>{const o=Array.isArray(n)&&n.length?n:t,r=Object.keys(t).length&&!Array.isArray(t)?t:n;let s={},a={};const i=dom.getComponentStateKey(e,r.key);dom.stateCheckSet.add(i),r.accessKey&&dom.stateCheckSet.add(r.accessKey);const c=typeof e!==constants.typeofPropsFunctionIdentifier||dom.state[i]?typeof e===constants.typeofPropsFunctionIdentifier?dom.renderStore[i].expandedFn:e:e({props:{...r}});if(dom.state[i]||(dom.state[i]={},dom.renderStore[i]={},dom.renderStore[i].expandedFn=typeof e===constants.typeofPropsFunctionIdentifier?e({props:{...r}}):e,c.set&&(s.set=c.set,c.set({props:{...r},state:dom.state[i]})),a=dom.state[i],dom.state[r.accessKey]=a),c.render){s.componentStateKey=i,a=dom.state[i],dom.state[r.accessKey]=a,delete r.accessKey;const e=c.render({props:{...r},state:a}),t=e.children;return e.tag.render?(s=POP.use(e.tag,o),t.forEach(e=>{s.children.push(e)}),o&&o.length&&o.forEach(e=>{s.children.push(e)})):(s={...s,...e},o&&o.length&&o.forEach(e=>{s.children.push(e)})),s}},refresh:()=>{dom.stateCheckSet.clear();const e=dom.renderFn();e.children=dom.filterValidPopObjects(e),dom.updateElement(dom.root,e,dom.prevTree),dom.prevTree=e,dom.cleanState()},root:(e,t={})=>{const{rootName:n,accessKey:o,popRoutes:r}=t,s=document.createElement(constants.createRootElementTag);s.id=n&&typeof n===constants.createPOPElementTagType?n:constants.createRootElementDefaultId,document.body.appendChild(s),dom.root=s;const a=!(!r||Array.isArray(r)||!Object.keys(r).length);let i;dom.routes=a?r:null;const c=window.location.href.split("#!")[1],d=a?Object.keys(r)[0]:null;!c&&a&&(window.location.href+=`#!${d}`),a&&c&&r[c]?(i=r[c],dom.currPath=c):i=e,dom.init();const p=o||dom.getComponentStateKey(),l=typeof i!==constants.typeofPropsFunctionIdentifier||dom.state[p]?i:i();dom.initializeState(l,p);const m=p?POP.getState(p):{};dom.prevTree=l.render({state:m}),dom.prevTree.children=dom.filterValidPopObjects(dom.prevTree),dom.renderFn=(()=>l.render({state:m})),dom.updateElement(s,dom.prevTree),s.addEventListener(constants.refreshDOMDefaultAction,()=>{POP.refresh()})}},dom={init:()=>{dom.state={},dom.renderStore={},dom.stateCheckSet=new Set,window.addEventListener("hashchange",()=>{const e=window.location.href.split("#!")[1];dom.routes&&dom.currPath!==e&&window.location.reload()})},generateElement:e=>{if(typeof e===constants.createPOPElementTagType)return document.createTextNode(e);const t=e.tag.split(constants.popObjectTagSeparator),n=document.createElement(t[0]);return t[1]&&(t[1].includes(constants.popElementClassIdentifier)?n.className=t[1].split(constants.popElementAttributeSeparator)[1]:t[1].includes(constants.popElementIdIdentifier)&&(n.id=t[1].split(constants.popElementAttributeSeparator)[1])),t[2]&&(t[2].includes(constants.popElementClassIdentifier)?n.className=t[2].split(constants.popElementAttributeSeparator)[1]:t[2].includes(constants.popElementIdIdentifier)&&(n.id=t[2].split(constants.popElementAttributeSeparator)[1])),Object.keys(e.props).forEach(t=>{n[t]=e.props[t]}),Array.isArray(e.children)&&e.children.map(dom.generateElement).forEach(e=>n.appendChild(e)),n},sameProps:(e,t)=>{if(e===t)return!0;if(e.toString()===t.toString())return!0;if(typeof e!==constants.typeofPropsObjectIdentifier||typeof t!==constants.typeofPropsObjectIdentifier||null==e||null==t)return!1;const n=Object.keys(e),o=Object.keys(t);if(n.length!==o.length)return!1;let r=!0;return n.forEach(n=>{o.includes(n)||(r=!1),typeof e[n]!==constants.typeofPropsFunctionIdentifier&&typeof t[n]!==constants.typeofPropsFunctionIdentifier||e[n].toString()!==t[n].toString()&&(r=!1),dom.sameProps(e[n],t[n])||(r=!1)}),r},compareElements:(e,t)=>typeof e!=typeof t||typeof e===constants.createPOPElementTagType&&e!==t||e.tag!==t.tag||e.props&&t.props&&!dom.sameProps(e.props,t.props),updateElement:(e,t,n,o=0)=>{if(n)if(t){if(dom.compareElements(t,n))e.replaceChild(dom.generateElement(t),e.childNodes[o]);else if(t.tag){const r=t.children.length,s=n.children.length;for(let a=0;a<r||a<s;a++)dom.updateElement(e.childNodes[o],t.children[a],n.children[a],a)}}else e.removeChild(e.childNodes[o]);else e.appendChild(dom.generateElement(t))},initializeState:(e,t)=>{e.render&&e.set&&t&&(dom.state[t]||(dom.state[t]={},e.set({state:dom.state[t]})),e.render({props:{},state:{}}).children.forEach(e=>{e&&dom.initializeState(e,e.accessKey)}))},filterValidPopObjects:e=>{if(e.children&&Array.isArray(e.children)){const t=e.children.filter(e=>e&&Object.keys(e).length);return t.forEach(e=>{e&&e.children&&(e.children=dom.filterValidPopObjects(e))}),t}return[]},getComponentStateKey:(e,t)=>{const n=typeof e===constants.typeofPropsFunctionIdentifier?e()&&e().set:e&&e.set,o=new Error,r=t?String(t):null,s=o.stack.split("\n"),a=s.join("").includes(constants.forLoopIdentifier)||s.join("").includes(constants.mapLoopIdentifier);if(n&&a&&!r)throw new Error(constants.popComponentUniqueKeyError);let i;for(let e=s.length-1;e>=0;e--)if(s[e].includes(constants.renderFunctionIdentifer)){i=e;break}return`${s[2].includes(constants.rootFunctionIdentifier)?s.join("").replace(constants.stateKeyFilterString,""):s.slice(0,i+1).join("").replace(constants.stateKeyFilterString,"")}${r||""}`},cleanState:()=>{Object.keys(dom.state).forEach(e=>{dom.stateCheckSet.has(e)||delete dom.state[e]})}},constants={accessKeyInvalidError:"accessKey must be a valid existing key",accessKeyMissingError:"accessKey must be passed inside props argument for a popComponent utilizing state.",createPOPElementTagType:"string",createRootElementDefaultId:"root",createRootElementTag:"div",forLoopIdentifier:"Array.forEach",popComponentUniqueKeyError:'POP components rendered in an array must have a unique "key" prop passed in.',popElementAttributeSeparator:"=",popElementClassIdentifier:"class=",popElementIdIdentifier:"id=",popObjectTagSeparator:"|",mapLoopIdentifier:"Array.map",refreshDOMDefaultAction:"click",renderFunctionIdentifer:"Object.render",rootFunctionIdentifier:"Object.root",stateKeyFilterString:"Error",typeofPropsFunctionIdentifier:"function",typeofPropsObjectIdentifier:"object"};