diff --git a/.size-snapshot.json b/.size-snapshot.json index 9333499..da1f923 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -1,7 +1,7 @@ { "dist/valyrian.min.js": { - "bundled": 11171, - "minified": 4634, - "gzipped": 1945 + "bundled": 11244, + "minified": 4652, + "gzipped": 1949 } } diff --git a/dist/valyrian.min.js b/dist/valyrian.min.js index 54c68e6..e828a5e 100644 --- a/dist/valyrian.min.js +++ b/dist/valyrian.min.js @@ -1 +1 @@ -!function(){"use strict";let e,o,n,t=void 0;function d(e,o,n){this.props=o||{},this.children=n,this.name=e}function r(e){this.dom=e}r.prototype={props:{},children:[]};let i=new r;function l(e,o){return o?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}function s(e,o,...n){return new d(e,o,n)}s.isNode="undefined"==typeof window,s.dom2vnode=e=>{if(3===e.nodeType)return new r(e);if(1===e.nodeType){let o={};[].forEach.call(e.attributes,e=>o[e.nodeName]=e.nodeValue);let n=new d(e.nodeName,o,[]);n.dom=e;for(let o=0,t=e.childNodes.length;o{let o=l("div");return o.innerHTML=e.trim(),[].map.call(o.childNodes,e=>s.dom2vnode(e))};let p=new Map;s.usePlugin=(e,o)=>!p.has(e)&&p.set(e,!0)&&e(s,o),s.reservedWords={key:!0,"v-list":!0,"v-noop":!0,oncreate:!0,onbeforeupdate:!0,onupdate:!0,onremove:!0};let c={};function m(e){let o=e.target,n=`__on${e.type}`;for(;o;){if(o[n])return o[n](e),void(e.defaultPrevented||s.update());o=o.parentNode}}function a(e,o,n){if(e instanceof d){if("onremove"===o)for(let o=0,n=e.children.length;o{let t=o.props[e];s.reservedWords[e]?"function"==typeof s.reservedWords[e]&&s.reservedWords[e](t,o,n):"function"==typeof t?(c[e=`__${e}`]||(document.addEventListener(e.slice(4),m),c[e]=!0),o.dom[e]=t):e in o.dom&&!o.isSVG?o.dom[e]!==t&&(o.dom[e]=t):t!==n.props[e]&&o.dom.setAttribute(e,t)};let N=e=>e.map(e=>e instanceof d?e.props.key:"");function y(e,o,n,t){n.dom?v(o,n,e,t):h(o,e,t)}let w=[];s.onCleanup=e=>{let o=s.current.parentVnode;o.onCleanup||(o.onCleanup=[]),o.onCleanup.push(e),-1===w.indexOf(o)&&w.push(o)},s.current={parentVnode:t,oldParentVnode:t,component:t};let V=Array.isArray;function C(e,o){let n=V(e.children)?e.children:[e.children],l=o.children;s.current.parentVnode=e,s.current.oldParentVnode=o;for(let o=0;o=o.length?t:s;-1!==n?(l[n].processed=!0,y(e.dom,c,l[n],d)):y(e.dom,c,i,d)}}let s=l.length;for(;s--;)l[s].processed||g(l[s])}else{let o=l.length,t=n.length;for(;o-- >t;)g(l[o]);for(o=0;o{if(e)return n&&(!function(){for(let e=w.length;e--;)for(let o of w[e].onCleanup)o();w=[]}(),o=e,e=new d(e.name,e.props,s(n,t,...r)),e.dom=o.dom,e.isSVG="svg"===e.name,C(e,o),s.isMounted=!0),s.isNode&&e.dom.innerHTML},s.mount=(o,t,d,...r)=>{let i=s.isNode?l("div"):"string"==typeof o?document.querySelectorAll(o)[0]:o;return e=s.dom2vnode(i),n=t,s.update(d,...r)},s.unmount=()=>{n=()=>"";let e=s.update();return n=t,s.isMounted=!1,e},s.directive=(e,o)=>!s.reservedWords[e]&&(s.reservedWords[e]=o),s.directive("v-for",(e,o)=>o.children=e.map(o.children[0]));let S=e=>(o,n,t)=>{if(e?o:!o){let e=document.createTextNode("");t.dom&&t.dom.parentNode&&(a(t,"onremove"),t.dom.parentNode.replaceChild(e,t.dom)),n.name="",n.children=[],n.props={},n.dom=e}};s.directive("v-if",S(!1)),s.directive("v-unless",S(!0)),s.directive("v-show",(e,o)=>o.dom.style.display=e?"":"none"),s.directive("v-class",(e,o)=>{for(let n in e)o.dom.classList.toggle(n,e[n])}),(s.isNode?global:window).v=s}();//# sourceMappingURL=valyrian.min.js.map +!function(){"use strict";let e,o,n,t=void 0;function d(e,o,n){this.props=o||{},this.children=n,this.name=e}function r(e){this.dom=e}r.prototype={props:{},children:[]};let i=new r;function l(e,o){return o?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}function s(e,o,...n){return new d(e,o,n)}s.isNode="undefined"==typeof window,s.dom2vnode=e=>{if(3===e.nodeType)return new r(e);if(1===e.nodeType){let o={};[].forEach.call(e.attributes,e=>o[e.nodeName]=e.nodeValue);let n=new d(e.nodeName,o,[]);n.dom=e;for(let o=0,t=e.childNodes.length;o{let o=l("div");return o.innerHTML=e.trim(),[].map.call(o.childNodes,e=>s.dom2vnode(e))};let p=new Map;s.usePlugin=(e,o)=>!p.has(e)&&p.set(e,!0)&&e(s,o),s.reservedWords={key:!0,"v-list":!0,"v-noop":!0,oncreate:!0,onbeforeupdate:!0,onupdate:!0,onremove:!0};let c={};function m(e){let o=e.target,n=`__on${e.type}`;for(;o;){if(o[n])return o[n](e),void(e.defaultPrevented||s.update());o=o.parentNode}}function a(e,o,n){if(e instanceof d){if("onremove"===o)for(let o=0,n=e.children.length;o{if(e in o.props){let t=o.props[e];s.reservedWords[e]?"function"==typeof s.reservedWords[e]&&s.reservedWords[e](t,o,n):"function"==typeof t?(c[e=`__${e}`]||(document.addEventListener(e.slice(4),m),c[e]=!0),o.dom[e]=t):e in o.dom&&!o.isSVG?o.dom[e]!==t&&(o.dom[e]=t):t!==n.props[e]&&o.dom.setAttribute(e,t)}};let N=e=>e.map(e=>e instanceof d?e.props.key:"");function y(e,o,n,t){n.dom?v(o,n,e,t):h(o,e,t)}let w=[];s.onCleanup=e=>{let o=s.current.parentVnode;o.onCleanup||(o.onCleanup=[]),o.onCleanup.push(e),-1===w.indexOf(o)&&w.push(o)},s.current={parentVnode:t,oldParentVnode:t,component:t};let V=Array.isArray;function C(e,o){let n=V(e.children)?e.children:[e.children],l=o.children;s.current.parentVnode=e,s.current.oldParentVnode=o;for(let o=0;o=o.length?t:s;-1!==n?(l[n].processed=!0,y(e.dom,c,l[n],d)):y(e.dom,c,i,d)}}let s=l.length;for(;s--;)l[s].processed||g(l[s])}else{let o=l.length,t=n.length;for(;o-- >t;)g(l[o]);for(o=0;o{if(e)return n&&(!function(){for(let e=w.length;e--;)for(let o of w[e].onCleanup)o();w=[]}(),o=e,e=new d(e.name,e.props,s(n,t,...r)),e.dom=o.dom,e.isSVG="svg"===e.name,C(e,o),s.isMounted=!0),s.isNode&&e.dom.innerHTML},s.mount=(o,t,d,...r)=>{let i=s.isNode?l("div"):"string"==typeof o?document.querySelectorAll(o)[0]:o;return e=s.dom2vnode(i),n=t,s.update(d,...r)},s.unmount=()=>{n=()=>"";let e=s.update();return n=t,s.isMounted=!1,e},s.directive=(e,o)=>!s.reservedWords[e]&&(s.reservedWords[e]=o),s.directive("v-for",(e,o)=>o.children=e.map(o.children[0]));let S=e=>(o,n,t)=>{if(e?o:!o){let e=document.createTextNode("");t.dom&&t.dom.parentNode&&(a(t,"onremove"),t.dom.parentNode.replaceChild(e,t.dom)),n.name="",n.children=[],n.props={},n.dom=e}};s.directive("v-if",S(!1)),s.directive("v-unless",S(!0)),s.directive("v-show",(e,o)=>o.dom.style.display=e?"":"none"),s.directive("v-class",(e,o)=>{for(let n in e)o.dom.classList.toggle(n,e[n])}),(s.isNode?global:window).v=s}();//# sourceMappingURL=valyrian.min.js.map diff --git a/dist/valyrian.min.js.map b/dist/valyrian.min.js.map index 5fbd320..c07a5b0 100644 --- a/dist/valyrian.min.js.map +++ b/dist/valyrian.min.js.map @@ -1 +1 @@ -{"version":3,"file":"valyrian.min.js","sources":["../lib/index.js"],"sourcesContent":["let UND = void 0;\nlet oncreate = 'oncreate';\nlet onupdate = 'onupdate';\nlet onremove = 'onremove';\nlet onbeforeupdate = 'onbeforeupdate';\nlet functionstr = 'function';\nlet list = 'v-list';\nlet noop = 'v-noop';\nlet mainNode;\nlet oldMainNode;\nlet mountedComponent;\n\nfunction Vnode(name, props, children) {\n this.props = props || {};\n this.children = children;\n this.name = name;\n};\n\nfunction TextVnode(dom) {\n this.dom = dom;\n}\nTextVnode.prototype = {\n props: {},\n children: []\n};\n\nlet emptyNode = new TextVnode();\n\nfunction createElement(tag, isSVG) {\n return isSVG ?\n document.createElementNS('http://www.w3.org/2000/svg', tag) :\n document.createElement(tag);\n}\n\nfunction v(tagOrComponent, props, ...children) {\n return new Vnode(tagOrComponent, props, children);\n};\n\nv.isNode = typeof window === 'undefined';\n\n// Hydrates the current dom before mount\nv.dom2vnode = dom => {\n if (dom.nodeType === 3) {\n return new TextVnode(dom);\n }\n\n if (dom.nodeType === 1) {\n let props = {};\n [].forEach.call(dom.attributes, (prop) => props[prop.nodeName] = prop.nodeValue);\n\n let vnode = new Vnode(\n dom.nodeName,\n props,\n []\n );\n vnode.dom = dom;\n\n for (let i = 0, l = dom.childNodes.length; i < l; i++) {\n let childVnode = v.dom2vnode(dom.childNodes[i]);\n childVnode && vnode.children.push(childVnode);\n }\n return vnode;\n }\n};\n\nv.trust = (htmlString) => {\n let div = createElement('div');\n div.innerHTML = htmlString.trim();\n\n return [].map.call(div.childNodes, (item) => v.dom2vnode(item));\n};\n\n// Plugin system\nlet plugins = new Map();\nv.usePlugin = (plugin, options) => !plugins.has(plugin) && plugins.set(plugin, true) && plugin(v, options);\n\nv.reservedWords = {\n key: true,\n [list]: true,\n [noop]: true,\n [oncreate]: true,\n [onbeforeupdate]: true,\n [onupdate]: true,\n [onremove]: true\n};\n\nlet attachedListeners = {};\nfunction eventListener(e) {\n let dom = e.target;\n let name = `__on${e.type}`;\n while (dom) {\n if (dom[name]) {\n dom[name](e);\n if (!e.defaultPrevented) {\n v.update();\n }\n return;\n }\n dom = dom.parentNode;\n }\n};\n\nfunction lifecycleCall(vnode, methodName, oldNode) {\n if (vnode instanceof Vnode) {\n if (methodName === onremove) {\n for (let i = 0, l = vnode.children.length; i < l; i++) {\n lifecycleCall(vnode.children[i], onremove);\n }\n }\n\n if (vnode.props[methodName]) {\n return vnode.props[methodName](vnode, oldNode);\n }\n }\n}\n\nv.updateProperty = (name, newNode, oldNode) => {\n let value = newNode.props[name];\n if (v.reservedWords[name]) {\n if (typeof v.reservedWords[name] === functionstr) {\n v.reservedWords[name](value, newNode, oldNode);\n }\n } else if (typeof value === functionstr) {\n name = `__${name}`;\n if (!attachedListeners[name]) {\n document.addEventListener(name.slice(4), eventListener);\n attachedListeners[name] = true;\n };\n newNode.dom[name] = value;\n } else if (name in newNode.dom && !newNode.isSVG) {\n if (newNode.dom[name] !== value) {\n newNode.dom[name] = value;\n }\n } else if (value !== oldNode.props[name]) {\n newNode.dom.setAttribute(name, value);\n }\n};\n\nfunction updateProps(newNode, oldNode) {\n for (let name in newNode.props) {\n v.updateProperty(name, newNode, oldNode);\n }\n}\n\nfunction moveDom(dom, $parent, newIndex) {\n if (dom !== $parent.childNodes[newIndex]) {\n $parent.childNodes[newIndex] ?\n $parent.replaceChild(dom, $parent.childNodes[newIndex]) :\n $parent.appendChild(dom);\n }\n}\n\nfunction createNode(newNode, $parent, newIndex) {\n newNode.dom = createElement(newNode.name, newNode.isSVG);\n updateProps(newNode, emptyNode);\n moveDom(newNode.dom, $parent, newIndex);\n lifecycleCall(newNode, oncreate);\n patch(newNode, emptyNode);\n}\n\nfunction updateNode(newNode, oldNode, $parent, newIndex) {\n newNode.dom = oldNode.dom;\n if (newNode.props[noop] || lifecycleCall(newNode, onbeforeupdate, oldNode) === false) {\n newNode.children = oldNode.children;\n moveDom(newNode.dom, $parent, newIndex);\n } else {\n for (let name in oldNode.props) {\n if (!v.reservedWords[name] && name in newNode.props === false && typeof oldNode.props[name] !== functionstr) {\n if (name in newNode.dom) {\n newNode.dom[name] = UND;\n } else {\n newNode.dom.removeAttribute(name);\n }\n }\n }\n updateProps(newNode, oldNode);\n moveDom(newNode.dom, $parent, newIndex);\n lifecycleCall(newNode, v.isMounted ? onupdate : oncreate, oldNode);\n patch(newNode, oldNode);\n }\n}\n\nfunction removeVnode(vnode) {\n if (vnode && vnode.dom) {\n lifecycleCall(vnode, onremove);\n vnode.dom.parentNode && vnode.dom.parentNode.removeChild(vnode.dom);\n }\n}\n\n\nlet getVnodeKeys = tree => tree.map(vnode => vnode instanceof Vnode ? vnode.props.key : '');\n\nfunction updateKeyedNode($parent, newNode, compareNode, newIndex) {\n // Moved or updated\n compareNode.dom ?\n updateNode(newNode, compareNode, $parent, newIndex) :\n createNode(newNode, $parent, newIndex);\n}\n\nlet vnodesToCleanup = [];\n\nv.onCleanup = callback => {\n let parentVnode = v.current.parentVnode;\n if (!parentVnode.onCleanup) {\n parentVnode.onCleanup = [];\n }\n\n parentVnode.onCleanup.push(callback);\n\n if (vnodesToCleanup.indexOf(parentVnode) === -1) {\n vnodesToCleanup.push(parentVnode);\n }\n};\n\nfunction cleanupVnodes() {\n for (let l = vnodesToCleanup.length; l--;) {\n for (let callback of vnodesToCleanup[l].onCleanup) {\n callback();\n }\n }\n vnodesToCleanup = [];\n}\n\nv.current = {\n parentVnode: UND,\n oldParentVnode: UND,\n component: UND\n};\n\nlet isArray = Array.isArray;\n\n// eslint-disable-next-line complexity,sonarjs/cognitive-complexity\nfunction patch(parentNode, oldParentNode) {\n let newTree = isArray(parentNode.children) ? parentNode.children : [parentNode.children];\n let oldTree = oldParentNode.children;\n v.current.parentVnode = parentNode;\n v.current.oldParentVnode = oldParentNode;\n\n // Flatten children\n for (let i = 0; i < newTree.length; i++) {\n let childVnode = newTree[i];\n\n if (isArray(childVnode)) {\n newTree.splice(i--, 1, ...childVnode);\n } else if (childVnode instanceof Vnode) {\n if (typeof childVnode.name !== 'string') {\n v.current.component = childVnode;\n let viewMethod = childVnode.name.view || childVnode.name;\n newTree.splice(i--, 1, ...[viewMethod.call(childVnode.name, childVnode.props, ...childVnode.children)]);\n } else {\n childVnode.isSVG = parentNode.isSVG || childVnode.name === 'svg';\n }\n }\n }\n\n // Is keyed list\n if (oldTree.length && parentNode.props[list]) {\n let oldKeys = getVnodeKeys(oldTree);\n let newKeys = getVnodeKeys(newTree);\n\n for (let i = 0, l = newKeys.length; i < l; i++) {\n let key = newKeys[i];\n let newNode = newTree[i];\n\n // We will not handle other than Vnodes\n if (newNode instanceof Vnode) {\n // Updated: Same key\n if (key === oldKeys[i]) {\n oldTree[i].processed = true;\n updateKeyedNode(parentNode.dom, newNode, oldTree[i], i);\n } else {\n let oldIndex = oldKeys.indexOf(key);\n let newIndex = i >= oldKeys.length ? UND : i;\n\n // Moved: Key exists in old keys\n if (oldIndex !== -1) {\n oldTree[oldIndex].processed = true;\n updateKeyedNode(parentNode.dom, newNode, oldTree[oldIndex], newIndex);\n // Added: Key does not exists in old keys\n } else {\n updateKeyedNode(parentNode.dom, newNode, emptyNode, newIndex);\n }\n }\n }\n }\n\n // Delete unprocessed old keys\n let l = oldTree.length;\n\n while (l--) {\n if (!oldTree[l].processed) {\n removeVnode(oldTree[l]);\n }\n }\n\n // Not keyed list or first render so use the simple algorithm\n } else {\n let i = oldTree.length;\n let l = newTree.length;\n\n // Remove deleted nodes\n while (i-- > l) {\n removeVnode(oldTree[i]);\n }\n\n for (i = 0; i < l; i++) {\n let newNode = newTree[i];\n let oldNode = oldTree[i];\n // Is vnode\n if (newNode instanceof Vnode) {\n if (!oldNode) {\n createNode(newNode, parentNode.dom, i);\n } else {\n if (newNode.name === oldNode.name) {\n updateNode(newNode, oldNode, parentNode.dom, i);\n } else {\n lifecycleCall(oldNode, onremove);\n createNode(newNode, parentNode.dom, i);\n }\n }\n\n } else {\n let dom;\n\n // If we are getting a TextVnode could be from the dom2Vnode method\n let value = String(newNode instanceof TextVnode ?\n newNode.dom.nodeValue :\n newNode);\n\n if (oldNode instanceof TextVnode) {\n dom = oldNode.dom;\n if (value !== dom.nodeValue) {\n dom.nodeValue = value;\n }\n } else {\n dom = document.createTextNode(value);\n if (!oldNode) {\n parentNode.dom.appendChild(dom);\n } else {\n lifecycleCall(oldNode, onremove);\n parentNode.dom.replaceChild(dom, oldNode.dom);\n }\n }\n newTree[i] = new TextVnode(dom);\n }\n }\n }\n\n parentNode.children = newTree;\n};\n\nv.update = (props, ...children) => {\n if (mainNode) {\n if (mountedComponent) {\n cleanupVnodes();\n oldMainNode = mainNode;\n mainNode = new Vnode(mainNode.name, mainNode.props, v(mountedComponent, props, ...children));\n mainNode.dom = oldMainNode.dom;\n mainNode.isSVG = mainNode.name === 'svg';\n patch(mainNode, oldMainNode);\n v.isMounted = true;\n }\n\n return v.isNode && mainNode.dom.innerHTML;\n }\n};\n\nv.mount = (container, component, props, ...children) => {\n let mainContainer = v.isNode\n ? createElement('div')\n : typeof container === 'string'\n ? document.querySelectorAll(container)[0]\n : container;\n\n mainNode = v.dom2vnode(mainContainer);\n mountedComponent = component;\n\n return v.update(props, ...children);\n};\n\nv.unmount = () => {\n mountedComponent = () => '';\n let result = v.update();\n mountedComponent = UND;\n v.isMounted = false;\n return result;\n};\n\nv.directive = (directive, handler) => !v.reservedWords[directive] && (v.reservedWords[directive] = handler);\nv.directive('v-for', (set, vnode) => vnode.children = set.map(vnode.children[0]));\n\nlet hideDirective = (test) => (bool, vnode, oldnode) => {\n let value = test ? bool : !bool;\n if (value) {\n let newdom = document.createTextNode('');\n if (oldnode.dom && oldnode.dom.parentNode) {\n lifecycleCall(oldnode, onremove);\n oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom);\n }\n vnode.name = '';\n vnode.children = [];\n vnode.props = {};\n vnode.dom = newdom;\n }\n};\n\nv.directive('v-if', hideDirective(false));\nv.directive('v-unless', hideDirective(true));\nv.directive('v-show', (bool, vnode) => vnode.dom.style.display = bool ? '' : 'none');\nv.directive('v-class', (classes, vnode) => {\n for (let name in classes) {\n vnode.dom.classList.toggle(name, classes[name]);\n }\n});\n\n(v.isNode ? global : window).v = v;\n"],"names":["mainNode","oldMainNode","mountedComponent","UND","Vnode","name","props","children","this","TextVnode","dom","prototype","emptyNode","createElement","tag","isSVG","document","createElementNS","v","tagOrComponent","isNode","window","dom2vnode","nodeType","forEach","call","attributes","prop","nodeName","nodeValue","vnode","i","l","childNodes","length","childVnode","push","trust","htmlString","div","innerHTML","trim","map","item","plugins","Map","usePlugin","plugin","options","has","set","reservedWords","key","v-list","v-noop","oncreate","onbeforeupdate","onupdate","onremove","attachedListeners","eventListener","e","target","type","defaultPrevented","update","parentNode","lifecycleCall","methodName","oldNode","updateProps","newNode","updateProperty","moveDom","$parent","newIndex","replaceChild","appendChild","createNode","patch","updateNode","removeAttribute","isMounted","removeVnode","removeChild","value","addEventListener","slice","setAttribute","getVnodeKeys","tree","updateKeyedNode","compareNode","vnodesToCleanup","onCleanup","callback","parentVnode","current","indexOf","oldParentVnode","component","isArray","Array","oldParentNode","newTree","oldTree","splice","viewMethod","view","oldKeys","newKeys","processed","oldIndex","String","createTextNode","cleanupVnodes","mount","container","mainContainer","querySelectorAll","unmount","result","directive","handler","hideDirective","test","bool","oldnode","newdom","style","display","classes","classList","toggle","global"],"mappings":"yBAAA,IAQIA,EACAC,EACAC,EAVAC,OAAM,EAYV,SAASC,EAAMC,EAAMC,EAAOC,GAC1BC,KAAKF,MAAQA,GAAS,GACtBE,KAAKD,SAAWA,EAChBC,KAAKH,KAAOA,EAGd,SAASI,EAAUC,GACjBF,KAAKE,IAAMA,EAEbD,EAAUE,UAAY,CACpBL,MAAO,GACPC,SAAU,IAGZ,IAAIK,EAAY,IAAIH,EAEpB,SAASI,EAAcC,EAAKC,GAC1B,OAAOA,EACLC,SAASC,gBAAgB,6BAA8BH,GACvDE,SAASH,cAAcC,GAG3B,SAASI,EAAEC,EAAgBb,KAAUC,GACnC,OAAO,IAAIH,EAAMe,EAAgBb,EAAOC,GAG1CW,EAAEE,OAA2B,oBAAXC,OAGlBH,EAAEI,UAAYZ,IACZ,GAAqB,IAAjBA,EAAIa,SACN,OAAO,IAAId,EAAUC,GAGvB,GAAqB,IAAjBA,EAAIa,SAAgB,CACtB,IAAIjB,EAAQ,GACZ,GAAGkB,QAAQC,KAAKf,EAAIgB,WAAaC,GAASrB,EAAMqB,EAAKC,UAAYD,EAAKE,WAEtE,IAAIC,EAAQ,IAAI1B,EACdM,EAAIkB,SACJtB,EACA,IAEFwB,EAAMpB,IAAMA,EAEZ,IAAK,IAAIqB,EAAI,EAAGC,EAAItB,EAAIuB,WAAWC,OAAQH,EAAIC,EAAGD,IAAK,CACrD,IAAII,EAAajB,EAAEI,UAAUZ,EAAIuB,WAAWF,IAC5CI,GAAcL,EAAMvB,SAAS6B,KAAKD,GAEpC,OAAOL,IAIXZ,EAAEmB,MAASC,IACT,IAAIC,EAAM1B,EAAc,OAGxB,OAFA0B,EAAIC,UAAYF,EAAWG,OAEpB,GAAGC,IAAIjB,KAAKc,EAAIN,WAAaU,GAASzB,EAAEI,UAAUqB,KAI3D,IAAIC,EAAU,IAAIC,IAClB3B,EAAE4B,UAAY,CAACC,EAAQC,KAAaJ,EAAQK,IAAIF,IAAWH,EAAQM,IAAIH,GAAQ,IAASA,EAAO7B,EAAG8B,GAElG9B,EAAEiC,cAAgB,CAChBC,KAAK,EACLC,UAAQ,EACRC,UAAQ,EACRC,UAAY,EACZC,gBAAkB,EAClBC,UAAY,EACZC,UAAY,GAGd,IAAIC,EAAoB,GACxB,SAASC,EAAcC,GACrB,IAAInD,EAAMmD,EAAEC,OACRzD,EAAO,OAAOwD,EAAEE,OACpB,KAAOrD,GAAK,CACV,GAAIA,EAAIL,GAKN,OAJAK,EAAIL,GAAMwD,QACLA,EAAEG,kBACL9C,EAAE+C,UAINvD,EAAMA,EAAIwD,YAId,SAASC,EAAcrC,EAAOsC,EAAYC,GACxC,GAAIvC,aAAiB1B,EAAO,CAC1B,GArGW,aAqGPgE,EACF,IAAK,IAAIrC,EAAI,EAAGC,EAAIF,EAAMvB,SAAS2B,OAAQH,EAAIC,EAAGD,IAChDoC,EAAcrC,EAAMvB,SAASwB,GAvGtB,YA2GX,GAAID,EAAMxB,MAAM8D,GACd,OAAOtC,EAAMxB,MAAM8D,GAAYtC,EAAOuC,IA2B5C,SAASC,EAAYC,EAASF,GAC5B,IAAK,IAAIhE,KAAQkE,EAAQjE,MACvBY,EAAEsD,eAAenE,EAAMkE,EAASF,GAIpC,SAASI,EAAQ/D,EAAKgE,EAASC,GACzBjE,IAAQgE,EAAQzC,WAAW0C,KAC7BD,EAAQzC,WAAW0C,GACjBD,EAAQE,aAAalE,EAAKgE,EAAQzC,WAAW0C,IAC7CD,EAAQG,YAAYnE,IAI1B,SAASoE,EAAWP,EAASG,EAASC,GACpCJ,EAAQ7D,IAAMG,EAAc0D,EAAQlE,KAAMkE,EAAQxD,OAClDuD,EAAYC,EAAS3D,GACrB6D,EAAQF,EAAQ7D,IAAKgE,EAASC,GAC9BR,EAAcI,EA3JD,YA4JbQ,EAAMR,EAAS3D,GAGjB,SAASoE,EAAWT,EAASF,EAASK,EAASC,GAE7C,GADAJ,EAAQ7D,IAAM2D,EAAQ3D,IAClB6D,EAAQjE,MA3JH,YA2JsE,IAApD6D,EAAcI,EA9JtB,iBA8J+CF,GAChEE,EAAQhE,SAAW8D,EAAQ9D,SAC3BkE,EAAQF,EAAQ7D,IAAKgE,EAASC,OACzB,CACL,IAAK,IAAItE,KAAQgE,EAAQ/D,MAClBY,EAAEiC,cAAc9C,IAASA,KAAQkE,EAAQjE,QAAU,GAlK5C,mBAkK4D+D,EAAQ/D,MAAMD,KAChFA,KAAQkE,EAAQ7D,IAClB6D,EAAQ7D,IAAIL,GAAQF,EAEpBoE,EAAQ7D,IAAIuE,gBAAgB5E,IAIlCiE,EAAYC,EAASF,GACrBI,EAAQF,EAAQ7D,IAAKgE,EAASC,GAC9BR,EAAcI,EAASrD,EAAEgE,UA/Kd,WADA,WAgL+Cb,GAC1DU,EAAMR,EAASF,IAInB,SAASc,EAAYrD,GACfA,GAASA,EAAMpB,MACjByD,EAAcrC,EArLH,YAsLXA,EAAMpB,IAAIwD,YAAcpC,EAAMpB,IAAIwD,WAAWkB,YAAYtD,EAAMpB,MArEnEQ,EAAEsD,eAAiB,CAACnE,EAAMkE,EAASF,KACjC,IAAIgB,EAAQd,EAAQjE,MAAMD,GACtBa,EAAEiC,cAAc9C,GAjHJ,mBAkHHa,EAAEiC,cAAc9C,IACzBa,EAAEiC,cAAc9C,GAAMgF,EAAOd,EAASF,GAnH1B,mBAqHEgB,GAEX1B,EADLtD,EAAO,KAAKA,OAEVW,SAASsE,iBAAiBjF,EAAKkF,MAAM,GAAI3B,GACzCD,EAAkBtD,IAAQ,GAE5BkE,EAAQ7D,IAAIL,GAAQgF,GACXhF,KAAQkE,EAAQ7D,MAAQ6D,EAAQxD,MACrCwD,EAAQ7D,IAAIL,KAAUgF,IACxBd,EAAQ7D,IAAIL,GAAQgF,GAEbA,IAAUhB,EAAQ/D,MAAMD,IACjCkE,EAAQ7D,IAAI8E,aAAanF,EAAMgF,IAwDnC,IAAII,EAAeC,GAAQA,EAAKhD,IAAIZ,GAASA,aAAiB1B,EAAQ0B,EAAMxB,MAAM8C,IAAM,IAExF,SAASuC,EAAgBjB,EAASH,EAASqB,EAAajB,GAEtDiB,EAAYlF,IACVsE,EAAWT,EAASqB,EAAalB,EAASC,GAC1CG,EAAWP,EAASG,EAASC,GAGjC,IAAIkB,EAAkB,GAEtB3E,EAAE4E,UAAYC,IACZ,IAAIC,EAAc9E,EAAE+E,QAAQD,YACvBA,EAAYF,YACfE,EAAYF,UAAY,IAG1BE,EAAYF,UAAU1D,KAAK2D,IAEmB,IAA1CF,EAAgBK,QAAQF,IAC1BH,EAAgBzD,KAAK4D,IAazB9E,EAAE+E,QAAU,CACVD,YAAa7F,EACbgG,eAAgBhG,EAChBiG,UAAWjG,GAGb,IAAIkG,EAAUC,MAAMD,QAGpB,SAAStB,EAAMb,EAAYqC,GACzB,IAAIC,EAAUH,EAAQnC,EAAW3D,UAAY2D,EAAW3D,SAAW,CAAC2D,EAAW3D,UAC3EkG,EAAUF,EAAchG,SAC5BW,EAAE+E,QAAQD,YAAc9B,EACxBhD,EAAE+E,QAAQE,eAAiBI,EAG3B,IAAK,IAAIxE,EAAI,EAAGA,EAAIyE,EAAQtE,OAAQH,IAAK,CACvC,IAAII,EAAaqE,EAAQzE,GAEzB,GAAIsE,EAAQlE,GACVqE,EAAQE,OAAO3E,IAAK,KAAMI,QACrB,GAAIA,aAAsB/B,EAC/B,GAA+B,iBAApB+B,EAAW9B,KAAmB,CACvCa,EAAE+E,QAAQG,UAAYjE,EACtB,IAAIwE,EAAaxE,EAAW9B,KAAKuG,MAAQzE,EAAW9B,KACpDmG,EAAQE,OAAO3E,IAAK,EAAO4E,EAAWlF,KAAKU,EAAW9B,KAAM8B,EAAW7B,SAAU6B,EAAW5B,gBAE5F4B,EAAWpB,MAAQmD,EAAWnD,OAA6B,QAApBoB,EAAW9B,KAMxD,GAAIoG,EAAQvE,QAAUgC,EAAW5D,MA1PxB,UA0PqC,CAC5C,IAAIuG,EAAUpB,EAAagB,GACvBK,EAAUrB,EAAae,GAE3B,IAAK,IAAIzE,EAAI,EAAGC,EAAI8E,EAAQ5E,OAAQH,EAAIC,EAAGD,IAAK,CAC9C,IAAIqB,EAAM0D,EAAQ/E,GACdwC,EAAUiC,EAAQzE,GAGtB,GAAIwC,aAAmBnE,EAErB,GAAIgD,IAAQyD,EAAQ9E,GAClB0E,EAAQ1E,GAAGgF,WAAY,EACvBpB,EAAgBzB,EAAWxD,IAAK6D,EAASkC,EAAQ1E,GAAIA,OAChD,CACL,IAAIiF,EAAWH,EAAQX,QAAQ9C,GAC3BuB,EAAW5C,GAAK8E,EAAQ3E,OAAS/B,EAAM4B,GAGzB,IAAdiF,GACFP,EAAQO,GAAUD,WAAY,EAC9BpB,EAAgBzB,EAAWxD,IAAK6D,EAASkC,EAAQO,GAAWrC,IAG5DgB,EAAgBzB,EAAWxD,IAAK6D,EAAS3D,EAAW+D,IAO5D,IAAI3C,EAAIyE,EAAQvE,OAEhB,KAAOF,KACAyE,EAAQzE,GAAG+E,WACd5B,EAAYsB,EAAQzE,QAKnB,CACL,IAAID,EAAI0E,EAAQvE,OACZF,EAAIwE,EAAQtE,OAGhB,KAAOH,KAAMC,GACXmD,EAAYsB,EAAQ1E,IAGtB,IAAKA,EAAI,EAAGA,EAAIC,EAAGD,IAAK,CACtB,IAAIwC,EAAUiC,EAAQzE,GAClBsC,EAAUoC,EAAQ1E,GAEtB,GAAIwC,aAAmBnE,EAChBiE,EAGCE,EAAQlE,OAASgE,EAAQhE,KAC3B2E,EAAWT,EAASF,EAASH,EAAWxD,IAAKqB,IAE7CoC,EAAcE,EAzTX,YA0THS,EAAWP,EAASL,EAAWxD,IAAKqB,IANtC+C,EAAWP,EAASL,EAAWxD,IAAKqB,OAUjC,CACL,IAAIrB,EAGA2E,EAAQ4B,OAAO1C,aAAmB9D,EACpC8D,EAAQ7D,IAAImB,UACZ0C,GAEEF,aAAmB5D,GACrBC,EAAM2D,EAAQ3D,IACV2E,IAAU3E,EAAImB,YAChBnB,EAAImB,UAAYwD,KAGlB3E,EAAMM,SAASkG,eAAe7B,GACzBhB,GAGHF,EAAcE,EAhVX,YAiVHH,EAAWxD,IAAIkE,aAAalE,EAAK2D,EAAQ3D,MAHzCwD,EAAWxD,IAAImE,YAAYnE,IAM/B8F,EAAQzE,GAAK,IAAItB,EAAUC,KAKjCwD,EAAW3D,SAAWiG,EAGxBtF,EAAE+C,OAAS,CAAC3D,KAAUC,KACpB,GAAIP,EAWF,OAVIE,KA3IR,WACE,IAAK,IAAI8B,EAAI6D,EAAgB3D,OAAQF,KACnC,IAAK,IAAI+D,KAAYF,EAAgB7D,GAAG8D,UACtCC,IAGJF,EAAkB,GAsIdsB,GACAlH,EAAcD,EACdA,EAAW,IAAII,EAAMJ,EAASK,KAAML,EAASM,MAAOY,EAAEhB,EAAkBI,KAAUC,IAClFP,EAASU,IAAMT,EAAYS,IAC3BV,EAASe,MAA0B,QAAlBf,EAASK,KAC1B0E,EAAM/E,EAAUC,GAChBiB,EAAEgE,WAAY,GAGThE,EAAEE,QAAUpB,EAASU,IAAI8B,WAIpCtB,EAAEkG,MAAQ,CAACC,EAAWjB,EAAW9F,KAAUC,KACzC,IAAI+G,EAAgBpG,EAAEE,OAClBP,EAAc,OACO,iBAAdwG,EACLrG,SAASuG,iBAAiBF,GAAW,GACrCA,EAKN,OAHArH,EAAWkB,EAAEI,UAAUgG,GACvBpH,EAAmBkG,EAEZlF,EAAE+C,OAAO3D,KAAUC,IAG5BW,EAAEsG,QAAU,KACVtH,EAAmB,IAAM,GACzB,IAAIuH,EAASvG,EAAE+C,SAGf,OAFA/D,EAAmBC,EACnBe,EAAEgE,WAAY,EACPuC,GAGTvG,EAAEwG,UAAY,CAACA,EAAWC,KAAazG,EAAEiC,cAAcuE,KAAexG,EAAEiC,cAAcuE,GAAaC,GACnGzG,EAAEwG,UAAU,QAAS,CAACxE,EAAKpB,IAAUA,EAAMvB,SAAW2C,EAAIR,IAAIZ,EAAMvB,SAAS,KAE7E,IAAIqH,EAAiBC,GAAS,CAACC,EAAMhG,EAAOiG,KAE1C,GADYF,EAAOC,GAAQA,EAChB,CACT,IAAIE,EAAShH,SAASkG,eAAe,IACjCa,EAAQrH,KAAOqH,EAAQrH,IAAIwD,aAC7BC,EAAc4D,EAzYL,YA0YTA,EAAQrH,IAAIwD,WAAWU,aAAaoD,EAAQD,EAAQrH,MAEtDoB,EAAMzB,KAAO,GACbyB,EAAMvB,SAAW,GACjBuB,EAAMxB,MAAQ,GACdwB,EAAMpB,IAAMsH,IAIhB9G,EAAEwG,UAAU,OAAQE,GAAc,IAClC1G,EAAEwG,UAAU,WAAYE,GAAc,IACtC1G,EAAEwG,UAAU,SAAU,CAACI,EAAMhG,IAAUA,EAAMpB,IAAIuH,MAAMC,QAAUJ,EAAO,GAAK,QAC7E5G,EAAEwG,UAAU,UAAW,CAACS,EAASrG,KAC/B,IAAK,IAAIzB,KAAQ8H,EACfrG,EAAMpB,IAAI0H,UAAUC,OAAOhI,EAAM8H,EAAQ9H,OAI5Ca,EAAEE,OAASkH,OAASjH,QAAQH,EAAIA"} \ No newline at end of file +{"version":3,"file":"valyrian.min.js","sources":["../lib/index.js"],"sourcesContent":["let UND = void 0;\nlet oncreate = 'oncreate';\nlet onupdate = 'onupdate';\nlet onremove = 'onremove';\nlet onbeforeupdate = 'onbeforeupdate';\nlet functionstr = 'function';\nlet list = 'v-list';\nlet noop = 'v-noop';\nlet mainNode;\nlet oldMainNode;\nlet mountedComponent;\n\nfunction Vnode(name, props, children) {\n this.props = props || {};\n this.children = children;\n this.name = name;\n};\n\nfunction TextVnode(dom) {\n this.dom = dom;\n}\nTextVnode.prototype = {\n props: {},\n children: []\n};\n\nlet emptyNode = new TextVnode();\n\nfunction createElement(tag, isSVG) {\n return isSVG ?\n document.createElementNS('http://www.w3.org/2000/svg', tag) :\n document.createElement(tag);\n}\n\nfunction v(tagOrComponent, props, ...children) {\n return new Vnode(tagOrComponent, props, children);\n};\n\nv.isNode = typeof window === 'undefined';\n\n// Hydrates the current dom before mount\nv.dom2vnode = dom => {\n if (dom.nodeType === 3) {\n return new TextVnode(dom);\n }\n\n if (dom.nodeType === 1) {\n let props = {};\n [].forEach.call(dom.attributes, (prop) => props[prop.nodeName] = prop.nodeValue);\n\n let vnode = new Vnode(\n dom.nodeName,\n props,\n []\n );\n vnode.dom = dom;\n\n for (let i = 0, l = dom.childNodes.length; i < l; i++) {\n let childVnode = v.dom2vnode(dom.childNodes[i]);\n childVnode && vnode.children.push(childVnode);\n }\n return vnode;\n }\n};\n\nv.trust = (htmlString) => {\n let div = createElement('div');\n div.innerHTML = htmlString.trim();\n\n return [].map.call(div.childNodes, (item) => v.dom2vnode(item));\n};\n\n// Plugin system\nlet plugins = new Map();\nv.usePlugin = (plugin, options) => !plugins.has(plugin) && plugins.set(plugin, true) && plugin(v, options);\n\nv.reservedWords = {\n key: true,\n [list]: true,\n [noop]: true,\n [oncreate]: true,\n [onbeforeupdate]: true,\n [onupdate]: true,\n [onremove]: true\n};\n\nlet attachedListeners = {};\nfunction eventListener(e) {\n let dom = e.target;\n let name = `__on${e.type}`;\n while (dom) {\n if (dom[name]) {\n dom[name](e);\n if (!e.defaultPrevented) {\n v.update();\n }\n return;\n }\n dom = dom.parentNode;\n }\n};\n\nfunction lifecycleCall(vnode, methodName, oldNode) {\n if (vnode instanceof Vnode) {\n if (methodName === onremove) {\n for (let i = 0, l = vnode.children.length; i < l; i++) {\n lifecycleCall(vnode.children[i], onremove);\n }\n }\n\n if (vnode.props[methodName]) {\n return vnode.props[methodName](vnode, oldNode);\n }\n }\n}\n\nv.updateProperty = (name, newNode, oldNode) => {\n if (name in newNode.props) {\n let value = newNode.props[name];\n if (v.reservedWords[name]) {\n if (typeof v.reservedWords[name] === functionstr) {\n v.reservedWords[name](value, newNode, oldNode);\n }\n } else if (typeof value === functionstr) {\n name = `__${name}`;\n if (!attachedListeners[name]) {\n document.addEventListener(name.slice(4), eventListener);\n attachedListeners[name] = true;\n };\n newNode.dom[name] = value;\n } else if (name in newNode.dom && !newNode.isSVG) {\n if (newNode.dom[name] !== value) {\n newNode.dom[name] = value;\n }\n } else if (value !== oldNode.props[name]) {\n newNode.dom.setAttribute(name, value);\n }\n }\n};\n\nfunction updateProps(newNode, oldNode) {\n for (let name in newNode.props) {\n v.updateProperty(name, newNode, oldNode);\n }\n}\n\nfunction moveDom(dom, $parent, newIndex) {\n if (dom !== $parent.childNodes[newIndex]) {\n $parent.childNodes[newIndex] ?\n $parent.replaceChild(dom, $parent.childNodes[newIndex]) :\n $parent.appendChild(dom);\n }\n}\n\nfunction createNode(newNode, $parent, newIndex) {\n newNode.dom = createElement(newNode.name, newNode.isSVG);\n updateProps(newNode, emptyNode);\n moveDom(newNode.dom, $parent, newIndex);\n lifecycleCall(newNode, oncreate);\n patch(newNode, emptyNode);\n}\n\nfunction updateNode(newNode, oldNode, $parent, newIndex) {\n newNode.dom = oldNode.dom;\n if (newNode.props[noop] || lifecycleCall(newNode, onbeforeupdate, oldNode) === false) {\n newNode.children = oldNode.children;\n moveDom(newNode.dom, $parent, newIndex);\n } else {\n for (let name in oldNode.props) {\n if (!v.reservedWords[name] && name in newNode.props === false && typeof oldNode.props[name] !== functionstr) {\n if (name in newNode.dom) {\n newNode.dom[name] = UND;\n } else {\n newNode.dom.removeAttribute(name);\n }\n }\n }\n updateProps(newNode, oldNode);\n moveDom(newNode.dom, $parent, newIndex);\n lifecycleCall(newNode, v.isMounted ? onupdate : oncreate, oldNode);\n patch(newNode, oldNode);\n }\n}\n\nfunction removeVnode(vnode) {\n if (vnode && vnode.dom) {\n lifecycleCall(vnode, onremove);\n vnode.dom.parentNode && vnode.dom.parentNode.removeChild(vnode.dom);\n }\n}\n\n\nlet getVnodeKeys = tree => tree.map(vnode => vnode instanceof Vnode ? vnode.props.key : '');\n\nfunction updateKeyedNode($parent, newNode, compareNode, newIndex) {\n // Moved or updated\n compareNode.dom ?\n updateNode(newNode, compareNode, $parent, newIndex) :\n createNode(newNode, $parent, newIndex);\n}\n\nlet vnodesToCleanup = [];\n\nv.onCleanup = callback => {\n let parentVnode = v.current.parentVnode;\n if (!parentVnode.onCleanup) {\n parentVnode.onCleanup = [];\n }\n\n parentVnode.onCleanup.push(callback);\n\n if (vnodesToCleanup.indexOf(parentVnode) === -1) {\n vnodesToCleanup.push(parentVnode);\n }\n};\n\nfunction cleanupVnodes() {\n for (let l = vnodesToCleanup.length; l--;) {\n for (let callback of vnodesToCleanup[l].onCleanup) {\n callback();\n }\n }\n vnodesToCleanup = [];\n}\n\nv.current = {\n parentVnode: UND,\n oldParentVnode: UND,\n component: UND\n};\n\nlet isArray = Array.isArray;\n\n// eslint-disable-next-line complexity,sonarjs/cognitive-complexity\nfunction patch(parentNode, oldParentNode) {\n let newTree = isArray(parentNode.children) ? parentNode.children : [parentNode.children];\n let oldTree = oldParentNode.children;\n v.current.parentVnode = parentNode;\n v.current.oldParentVnode = oldParentNode;\n\n // Flatten children\n for (let i = 0; i < newTree.length; i++) {\n let childVnode = newTree[i];\n\n if (isArray(childVnode)) {\n newTree.splice(i--, 1, ...childVnode);\n } else if (childVnode instanceof Vnode) {\n if (typeof childVnode.name !== 'string') {\n v.current.component = childVnode;\n let viewMethod = childVnode.name.view || childVnode.name;\n newTree.splice(i--, 1, ...[viewMethod.call(childVnode.name, childVnode.props, ...childVnode.children)]);\n } else {\n childVnode.isSVG = parentNode.isSVG || childVnode.name === 'svg';\n }\n }\n }\n\n // Is keyed list\n if (oldTree.length && parentNode.props[list]) {\n let oldKeys = getVnodeKeys(oldTree);\n let newKeys = getVnodeKeys(newTree);\n\n for (let i = 0, l = newKeys.length; i < l; i++) {\n let key = newKeys[i];\n let newNode = newTree[i];\n\n // We will not handle other than Vnodes\n if (newNode instanceof Vnode) {\n // Updated: Same key\n if (key === oldKeys[i]) {\n oldTree[i].processed = true;\n updateKeyedNode(parentNode.dom, newNode, oldTree[i], i);\n } else {\n let oldIndex = oldKeys.indexOf(key);\n let newIndex = i >= oldKeys.length ? UND : i;\n\n // Moved: Key exists in old keys\n if (oldIndex !== -1) {\n oldTree[oldIndex].processed = true;\n updateKeyedNode(parentNode.dom, newNode, oldTree[oldIndex], newIndex);\n // Added: Key does not exists in old keys\n } else {\n updateKeyedNode(parentNode.dom, newNode, emptyNode, newIndex);\n }\n }\n }\n }\n\n // Delete unprocessed old keys\n let l = oldTree.length;\n\n while (l--) {\n if (!oldTree[l].processed) {\n removeVnode(oldTree[l]);\n }\n }\n\n // Not keyed list or first render so use the simple algorithm\n } else {\n let i = oldTree.length;\n let l = newTree.length;\n\n // Remove deleted nodes\n while (i-- > l) {\n removeVnode(oldTree[i]);\n }\n\n for (i = 0; i < l; i++) {\n let newNode = newTree[i];\n let oldNode = oldTree[i];\n // Is vnode\n if (newNode instanceof Vnode) {\n if (!oldNode) {\n createNode(newNode, parentNode.dom, i);\n } else {\n if (newNode.name === oldNode.name) {\n updateNode(newNode, oldNode, parentNode.dom, i);\n } else {\n lifecycleCall(oldNode, onremove);\n createNode(newNode, parentNode.dom, i);\n }\n }\n\n } else {\n let dom;\n\n // If we are getting a TextVnode could be from the dom2Vnode method\n let value = String(newNode instanceof TextVnode ?\n newNode.dom.nodeValue :\n newNode);\n\n if (oldNode instanceof TextVnode) {\n dom = oldNode.dom;\n if (value !== dom.nodeValue) {\n dom.nodeValue = value;\n }\n } else {\n dom = document.createTextNode(value);\n if (!oldNode) {\n parentNode.dom.appendChild(dom);\n } else {\n lifecycleCall(oldNode, onremove);\n parentNode.dom.replaceChild(dom, oldNode.dom);\n }\n }\n newTree[i] = new TextVnode(dom);\n }\n }\n }\n\n parentNode.children = newTree;\n};\n\nv.update = (props, ...children) => {\n if (mainNode) {\n if (mountedComponent) {\n cleanupVnodes();\n oldMainNode = mainNode;\n mainNode = new Vnode(mainNode.name, mainNode.props, v(mountedComponent, props, ...children));\n mainNode.dom = oldMainNode.dom;\n mainNode.isSVG = mainNode.name === 'svg';\n patch(mainNode, oldMainNode);\n v.isMounted = true;\n }\n\n return v.isNode && mainNode.dom.innerHTML;\n }\n};\n\nv.mount = (container, component, props, ...children) => {\n let mainContainer = v.isNode\n ? createElement('div')\n : typeof container === 'string'\n ? document.querySelectorAll(container)[0]\n : container;\n\n mainNode = v.dom2vnode(mainContainer);\n mountedComponent = component;\n\n return v.update(props, ...children);\n};\n\nv.unmount = () => {\n mountedComponent = () => '';\n let result = v.update();\n mountedComponent = UND;\n v.isMounted = false;\n return result;\n};\n\nv.directive = (directive, handler) => !v.reservedWords[directive] && (v.reservedWords[directive] = handler);\nv.directive('v-for', (set, vnode) => vnode.children = set.map(vnode.children[0]));\n\nlet hideDirective = (test) => (bool, vnode, oldnode) => {\n let value = test ? bool : !bool;\n if (value) {\n let newdom = document.createTextNode('');\n if (oldnode.dom && oldnode.dom.parentNode) {\n lifecycleCall(oldnode, onremove);\n oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom);\n }\n vnode.name = '';\n vnode.children = [];\n vnode.props = {};\n vnode.dom = newdom;\n }\n};\n\nv.directive('v-if', hideDirective(false));\nv.directive('v-unless', hideDirective(true));\nv.directive('v-show', (bool, vnode) => vnode.dom.style.display = bool ? '' : 'none');\nv.directive('v-class', (classes, vnode) => {\n for (let name in classes) {\n vnode.dom.classList.toggle(name, classes[name]);\n }\n});\n\n(v.isNode ? global : window).v = v;\n"],"names":["mainNode","oldMainNode","mountedComponent","UND","Vnode","name","props","children","this","TextVnode","dom","prototype","emptyNode","createElement","tag","isSVG","document","createElementNS","v","tagOrComponent","isNode","window","dom2vnode","nodeType","forEach","call","attributes","prop","nodeName","nodeValue","vnode","i","l","childNodes","length","childVnode","push","trust","htmlString","div","innerHTML","trim","map","item","plugins","Map","usePlugin","plugin","options","has","set","reservedWords","key","v-list","v-noop","oncreate","onbeforeupdate","onupdate","onremove","attachedListeners","eventListener","e","target","type","defaultPrevented","update","parentNode","lifecycleCall","methodName","oldNode","updateProps","newNode","updateProperty","moveDom","$parent","newIndex","replaceChild","appendChild","createNode","patch","updateNode","removeAttribute","isMounted","removeVnode","removeChild","value","addEventListener","slice","setAttribute","getVnodeKeys","tree","updateKeyedNode","compareNode","vnodesToCleanup","onCleanup","callback","parentVnode","current","indexOf","oldParentVnode","component","isArray","Array","oldParentNode","newTree","oldTree","splice","viewMethod","view","oldKeys","newKeys","processed","oldIndex","String","createTextNode","cleanupVnodes","mount","container","mainContainer","querySelectorAll","unmount","result","directive","handler","hideDirective","test","bool","oldnode","newdom","style","display","classes","classList","toggle","global"],"mappings":"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"} \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index 6890d2e..af7a39b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -115,24 +115,26 @@ function lifecycleCall(vnode, methodName, oldNode) { } v.updateProperty = (name, newNode, oldNode) => { - let value = newNode.props[name]; - if (v.reservedWords[name]) { - if (typeof v.reservedWords[name] === functionstr) { - v.reservedWords[name](value, newNode, oldNode); - } - } else if (typeof value === functionstr) { - name = `__${name}`; - if (!attachedListeners[name]) { - document.addEventListener(name.slice(4), eventListener); - attachedListeners[name] = true; - }; - newNode.dom[name] = value; - } else if (name in newNode.dom && !newNode.isSVG) { - if (newNode.dom[name] !== value) { + if (name in newNode.props) { + let value = newNode.props[name]; + if (v.reservedWords[name]) { + if (typeof v.reservedWords[name] === functionstr) { + v.reservedWords[name](value, newNode, oldNode); + } + } else if (typeof value === functionstr) { + name = `__${name}`; + if (!attachedListeners[name]) { + document.addEventListener(name.slice(4), eventListener); + attachedListeners[name] = true; + }; newNode.dom[name] = value; + } else if (name in newNode.dom && !newNode.isSVG) { + if (newNode.dom[name] !== value) { + newNode.dom[name] = value; + } + } else if (value !== oldNode.props[name]) { + newNode.dom.setAttribute(name, value); } - } else if (value !== oldNode.props[name]) { - newNode.dom.setAttribute(name, value); } }; diff --git a/test/directives_test.js b/test/directives_test.js index e68be7d..64dd1b1 100644 --- a/test/directives_test.js +++ b/test/directives_test.js @@ -287,56 +287,76 @@ describe('Directives', () => { * It needs a set of arrays as children of the form [{case}, vnodes] * This is not added to the base library but it shows the capabilities of valyrian directives */ - describe('v-switch', () => { - v.directive('v-switch', (value, vnode) => { - for (let i = 0, l = vnode.children.length; i < l; i++) { - let [test, handler] = vnode.children[i]; - let result = false; - result = typeof test === 'function' ? - test(value) : - value === test; - - if (result) { - vnode.children = typeof handler === 'function' ? handler(value) : handler; - return; + describe('v-switch example', () => { + it('v-switch', () => { + v.directive('v-switch', (value, vnode) => { + for (let i = 0, l = vnode.children.length; i < l; i++) { + let [test, handler] = vnode.children[i]; + let result = false; + result = typeof test === 'function' ? + test(value) : + value === test; + + if (result) { + vnode.children = typeof handler === 'function' ? handler(value) : handler; + return; + } } - } - vnode.children = value; + vnode.children = value; + }); + + let name; + let component = () =>
+ {['John', Hello John]} + {[(val) => val === 'John Doe', Hello John Doe]} + {['Jane', (val) => Hello {val} Doe]} +
; + + let expected; + let result; + + // Direct equality + expected = '
Hello John
'; + name = 'John'; + result = v.mount('div', component); + expect(result).toEqual(expected); + + // Comparison method + expected = '
Hello John Doe
'; + name = 'John Doe'; + result = v.mount('div', component); + expect(result).toEqual(expected); + + // Result method + expected = '
Hello Jane Doe
'; + name = 'Jane'; + result = v.mount('div', component); + expect(result).toEqual(expected); + + // If no case return the value as children + expected = '
Hello Anonymous
'; + name = 'Hello Anonymous'; + result = v.mount('div', component); + expect(result).toEqual(expected); }); - let name; - let component = () =>
- {['John', Hello John]} - {[(val) => val === 'John Doe', Hello John Doe]} - {['Jane', (val) => Hello {val} Doe]} -
; + }); - let expected; - let result; + // if the v-if directive resolve to false, we should not execute any other directive or attribute update like v-for + describe('use v-if with v-for', () => { + it('should use v-if with v-for directives', () => { + let arr = [1, 2, 3, 4]; + let show = true; + let component = () =>
{i => {i}}
; - // Direct equality - expected = '
Hello John
'; - name = 'John'; - result = v.mount('div', component); - expect(result).toEqual(expected); - - // Comparison method - expected = '
Hello John Doe
'; - name = 'John Doe'; - result = v.mount('div', component); - expect(result).toEqual(expected); - - // Result method - expected = '
Hello Jane Doe
'; - name = 'Jane'; - result = v.mount('div', component); - expect(result).toEqual(expected); - - // If no case return the value as children - expected = '
Hello Anonymous
'; - name = 'Hello Anonymous'; - result = v.mount('div', component); - expect(result).toEqual(expected); + let result = v.mount('body', component); + expect(result).toEqual('
1234
'); + + show = false; + let result2 = v.update(); + expect(result2).toEqual(''); + }); }); }); +