From 6170573c290e980987cb1b1d9b78631e1b633f83 Mon Sep 17 00:00:00 2001 From: Pat Cavit Date: Thu, 5 Jan 2017 23:07:34 -0800 Subject: [PATCH 1/3] feat: Return empty string node for `false` values Very specifically doing a strict `false` check here to try & avoid coercion perf costs. --- render/vnode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render/vnode.js b/render/vnode.js index 99877e4e..56df8c81 100644 --- a/render/vnode.js +++ b/render/vnode.js @@ -3,7 +3,7 @@ function Vnode(tag, key, attrs, children, text, dom) { } Vnode.normalize = function(node) { if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined) - if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node, undefined, undefined) + if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node === false ? "" : node, undefined, undefined) return node } Vnode.normalizeChildren = function normalizeChildren(children) { From 9f32267259a51db1f3a0dcc8161cf8f219078eec Mon Sep 17 00:00:00 2001 From: Pat Cavit Date: Thu, 5 Jan 2017 23:07:47 -0800 Subject: [PATCH 2/3] tests: Update tests for false -> "" behavior --- render/tests/test-component.js | 6 +++--- render/tests/test-hyperscript.js | 12 +++++++++--- render/tests/test-normalize.js | 4 ++-- render/tests/test-normalizeChildren.js | 6 ++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/render/tests/test-component.js b/render/tests/test-component.js index f4aad629..4bb0a3b6 100644 --- a/render/tests/test-component.js +++ b/render/tests/test-component.js @@ -104,7 +104,7 @@ o.spec("component", function() { visible = false render(root, [{tag: component}]) - o(root.firstChild.nodeValue).equals("false") + o(root.firstChild.nodeValue).equals("") }) o("updates root from null to null", function() { var component = { @@ -232,7 +232,7 @@ o.spec("component", function() { render(root, [{tag: component}]) o(root.firstChild.nodeType).equals(3) - o(root.firstChild.nodeValue).equals("false") + o(root.firstChild.nodeValue).equals("") }) o("can return null", function() { var component = { @@ -668,7 +668,7 @@ o.spec("component", function() { function init(vnode) { o(vnode.state.data).deepEquals(data) o(vnode.state.data).equals(data) - + //inherits state via prototype component.x = 1 o(vnode.state.x).equals(1) diff --git a/render/tests/test-hyperscript.js b/render/tests/test-hyperscript.js index 8237d0ea..32e767d8 100644 --- a/render/tests/test-hyperscript.js +++ b/render/tests/test-hyperscript.js @@ -229,7 +229,7 @@ o.spec("hyperscript", function() { o("handles falsy boolean single child", function() { var vnode = m("div", {}, [false]) - o(vnode.text).equals(false) + o(vnode.text).equals("") }) o("handles null single child", function() { var vnode = m("div", {}, [null]) @@ -261,7 +261,7 @@ o.spec("hyperscript", function() { var vnode = m("div", {}, [false, true]) o(vnode.children[0].tag).equals("#") - o(vnode.children[0].children).equals(false) + o(vnode.children[0].children).equals("") o(vnode.children[1].tag).equals("#") o(vnode.children[1].children).equals(true) }) @@ -353,10 +353,16 @@ o.spec("hyperscript", function() { o(vnode.text).equals(true) }) o("handles attr and single falsy boolean text child", function() { + var vnode = m("div", {a: "b"}, [0]) + + o(vnode.attrs.a).equals("b") + o(vnode.text).equals(0) + }) + o("handles attr and single false boolean text child", function() { var vnode = m("div", {a: "b"}, [false]) o(vnode.attrs.a).equals("b") - o(vnode.text).equals(false) + o(vnode.text).equals("") }) o("handles attr and single text child unwrapped", function() { var vnode = m("div", {a: "b"}, "c") diff --git a/render/tests/test-normalize.js b/render/tests/test-normalize.js index 7a01af31..237612a4 100644 --- a/render/tests/test-normalize.js +++ b/render/tests/test-normalize.js @@ -48,10 +48,10 @@ o.spec("normalize", function() { o(node.tag).equals("#") o(node.children).equals(true) }) - o("normalizes falsy boolean into text node", function() { + o("normalizes falsy boolean into empty text node", function() { var node = Vnode.normalize(false) o(node.tag).equals("#") - o(node.children).equals(false) + o(node.children).equals("") }) }) diff --git a/render/tests/test-normalizeChildren.js b/render/tests/test-normalizeChildren.js index 9ad2cd89..699f0eab 100644 --- a/render/tests/test-normalizeChildren.js +++ b/render/tests/test-normalizeChildren.js @@ -16,4 +16,10 @@ o.spec("normalizeChildren", function() { o(children[0].tag).equals("#") o(children[0].children).equals("a") }) + o("normalizes `false` values into empty string text nodes", function() { + var children = Vnode.normalizeChildren([false]) + + o(children[0].tag).equals("#") + o(children[0].children).equals("") + }) }) From 4b626896fc62f5de0fb352d4dada72242e184044 Mon Sep 17 00:00:00 2001 From: Gandalf-the-Bot Date: Sat, 7 Jan 2017 20:20:45 +0000 Subject: [PATCH 3/3] Bundled output for commit 4fc9368a30b88b3eb485fa7110cf3e2d9c3093db [skip ci] --- README.md | 2 +- mithril.js | 2 +- mithril.min.js | 77 +++++++++++++++++++++++++------------------------- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index b6e99098..bfe22f41 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,6 @@ There are over 4000 assertions in the test suite, and tests cover even difficult ## Modularity -Despite the huge improvements in performance and modularity, the new codebase is smaller than v0.2.x, currently clocking at 7.59 KB min+gzip +Despite the huge improvements in performance and modularity, the new codebase is smaller than v0.2.x, currently clocking at 7.60 KB min+gzip In addition, Mithril is now completely modular: you can import only the modules that you need and easily integrate 3rd party modules if you wish to use a different library for routing, ajax, and even rendering diff --git a/mithril.js b/mithril.js index 522c546d..cbc385e9 100644 --- a/mithril.js +++ b/mithril.js @@ -5,7 +5,7 @@ function Vnode(tag, key, attrs0, children, text, dom) { } Vnode.normalize = function(node) { if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined) - if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node, undefined, undefined) + if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node === false ? "" : node, undefined, undefined) return node } Vnode.normalizeChildren = function normalizeChildren(children) { diff --git a/mithril.min.js b/mithril.min.js index ff483e40..ad515a32 100644 --- a/mithril.min.js +++ b/mithril.min.js @@ -1,41 +1,42 @@ new function(){function w(a,c,k,d,h,m){return{tag:a,key:c,attrs:k,children:d,text:h,dom:m,domSize:void 0,state:{},events:void 0,instance:void 0,skip:!1}}function B(a){if(null==a||"string"!==typeof a&&null==a.view)throw Error("The selector must be either a string or a component.");if("string"===typeof a&&void 0===G[a]){for(var c,k,d=[],h={};c=N.exec(a);){var m=c[1],q=c[2];""===m&&""!==q?k=q:"#"===m?h.id=q:"."===m?d.push(q):"["===c[3][0]&&((m=c[6])&&(m=m.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")), "class"===c[4]?d.push(m):h[c[4]]=m||!0)}0b.indexOf("?")?"?":"&";b+=d+c}return b}function q(a){try{return""!==a?JSON.parse(a):null}catch(r){throw Error(a);}}function l(a){return a.responseText} -function t(a,c){if("function"===typeof a)if(Array.isArray(c))for(var b=0;bn.status||304===n.status)c(t(b.type,a));else{var g=Error(n.responseText),e;for(e in a)g[e]=a[e];d(g)}}catch(f){d(f)}};k&&null!=b.data?n.send(b.data):n.send()}); -return!0===b.background?r:z(r)},jsonp:function(b,l){var q=k();b=d(b,l);var z=new c(function(c,d){var k=b.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+p++,l=a.document.createElement("script");a[k]=function(d){l.parentNode.removeChild(l);c(t(b.type,d));delete a[k]};l.onerror=function(){l.parentNode.removeChild(l);d(Error("JSONP request failed"));delete a[k]};null==b.data&&(b.data={});b.url=h(b.url,b.data);b.data[b.callbackKey||"callback"]=k;l.src=m(b.url,b.data);a.document.documentElement.appendChild(l)}); -return!0===b.background?z:q(z)},setCompletionCallback:function(a){z=a}}}(window,x),M=function(a){function c(g,e,a,b,c,d,h){for(;a=u&&r>=n;){var y=e[u],v=a[n];if(y!==v||f)if(null==y)u++;else if(null==v)n++;else if(y.key===v.key)u++,n++,m(g,y,v,b,l(e,u,d),f,h),f&&y.tag===v.tag&&t(g,q(y),d);else if(y=e[p],y!==v||f)if(null==y)p--;else if(null==v)n++;else if(y.key===v.key)m(g,y,v,b,l(e,p+1,d),f,h),(f||n=u&&r>=n;){y=e[p];v=a[r];if(y!==v||f)if(null==y)p--;else{if(null!=v)if(y.key===v.key)m(g,y,v,b,l(e,p+1,d),f,h),f&&y.tag===v.tag&&t(g,q(y),d),null!=y.dom&&(d=y.dom),p--;else{if(!A){A=e;var y=p,C={},w;for(w=0;wb.indexOf("?")?"?":"&";b+=d+c}return b}function q(a){try{return""!==a?JSON.parse(a):null}catch(r){throw Error(a); +}}function l(a){return a.responseText}function t(a,c){if("function"===typeof a)if(Array.isArray(c))for(var b=0;bn.status||304===n.status)c(t(b.type,a));else{var g=Error(n.responseText),e;for(e in a)g[e]=a[e]; +d(g)}}catch(f){d(f)}};k&&null!=b.data?n.send(b.data):n.send()});return!0===b.background?r:z(r)},jsonp:function(b,l){var q=k();b=d(b,l);var z=new c(function(c,d){var k=b.callbackName||"_mithril_"+Math.round(1E16*Math.random())+"_"+p++,l=a.document.createElement("script");a[k]=function(d){l.parentNode.removeChild(l);c(t(b.type,d));delete a[k]};l.onerror=function(){l.parentNode.removeChild(l);d(Error("JSONP request failed"));delete a[k]};null==b.data&&(b.data={});b.url=h(b.url,b.data);b.data[b.callbackKey|| +"callback"]=k;l.src=m(b.url,b.data);a.document.documentElement.appendChild(l)});return!0===b.background?z:q(z)},setCompletionCallback:function(a){z=a}}}(window,x),M=function(a){function c(g,e,a,b,c,d,h){for(;a=u&&r>=n;){var y=e[u],v=a[n];if(y!==v||f)if(null==y)u++;else if(null==v)n++;else if(y.key===v.key)u++,n++,m(g,y,v,b,l(e,u,d),f,h),f&&y.tag===v.tag&&t(g,q(y),d);else if(y=e[p],y!==v||f)if(null==y)p--;else if(null==v)n++;else if(y.key===v.key)m(g,y,v,b,l(e, +p+1,d),f,h),(f||n=u&&r>=n;){y=e[p];v=a[r];if(y!==v||f)if(null==y)p--;else{if(null!=v)if(y.key===v.key)m(g,y,v,b,l(e,p+1,d),f,h),f&&y.tag===v.tag&&t(g,q(y),d),null!=y.dom&&(d=y.dom),p--;else{if(!A){A=e;var y=p,C={},w;for(w=0;w