diff --git a/archive/v0.1.4/mithril-tests.js b/archive/v0.1.4/mithril-tests.js index b06b4ce4..06ce9c2d 100644 --- a/archive/v0.1.4/mithril-tests.js +++ b/archive/v0.1.4/mithril-tests.js @@ -32,7 +32,7 @@ new function(window) { } return cell } - function build(parent, data, cached, shouldReattach) { + function build(parent, data, cached, shouldReattach, index) { if (data === null || data === undefined) { if (cached) clear(cached.nodes) return @@ -49,7 +49,7 @@ new function(window) { if (dataType == "[object Array]") { var nodes = [], intact = cached.length === data.length for (var i = 0; i < data.length; i++) { - var item = build(parent, data[i], cached[i], shouldReattach) + var item = build(parent, data[i], cached[i], shouldReattach, i) if (item === undefined) continue if (!item.nodes.intact) intact = false cached[i] = item @@ -70,14 +70,14 @@ new function(window) { if (isNew) { node = window.document.createElement(data.tag) cached = {tag: data.tag, attrs: setAttributes(node, data.attrs, {}), children: build(node, data.children, cached.children, true), nodes: [node]} - parent.appendChild(node) + parent.insertBefore(node, parent.childNodes[index]) } else { node = cached.nodes[0] setAttributes(node, data.attrs, cached.attrs) cached.children = build(node, data.children, cached.children, false) cached.nodes.intact = true - if (shouldReattach === true) parent.appendChild(node) + if (shouldReattach === true) parent.insertBefore(node, parent.childNodes[index]) } if (type.call(data.attrs["config"]) == "[object Function]") data.attrs["config"](node, !isNew) } @@ -91,7 +91,7 @@ new function(window) { } else { node = window.document.createTextNode(data) - parent.appendChild(node) + parent.insertBefore(node, parent.childNodes[index]) } cached = "string number boolean".indexOf(typeof data) > -1 ? new data.constructor(data) : data cached.nodes = [node] @@ -110,7 +110,7 @@ new function(window) { } else { node = cached.nodes[0] - parent.appendChild(node) + parent.insertBefore(node, parent.childNodes[index]) node.nodeValue = data } cached = new data.constructor(data) @@ -466,6 +466,12 @@ mock.window = new function() { appendChild: window.document.appendChild, removeChild: window.document.removeChild, replaceChild: window.document.replaceChild, + insertBefore: function(node, reference) { + node.parentNode = this + var index = this.childNodes.indexOf(reference) + if (index < 0) this.childNodes.push(node) + else this.childNodes.splice(index, 0, node) + }, setAttribute: function(name, value) { this[name] = value.toString() }, @@ -674,13 +680,14 @@ function testMithril(mock) { return root.childNodes[0].childNodes[0].childNodes[0].nodeName === "A" }) test(function() { + //https://github.com/lhorie/mithril.js/issues/43 var root = mock.document.createElement("div") m.render(root, m("a", {config: m.route}, "test")) m.render(root, m("a", {config: m.route}, "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - //see issue #29 + //https://github.com/lhorie/mithril.js/issues/29 var root = mock.document.createElement("div") var list = [false, false] m.render(root, list.reverse().map(function(flag, index) { @@ -699,6 +706,20 @@ function testMithril(mock) { return root.childNodes[0].checked === false && root.childNodes[1].checked === true }) + test(function() { + //https://github.com/lhorie/mithril.js/issues/44 + var root = mock.document.createElement("div") + m.render(root, m("#foo", [null, m("#bar")])) + m.render(root, m("#foo", ["test", m("#bar")])) + return root.childNodes[0].childNodes[0].nodeValue === "test" + }) + test(function() { + //https://github.com/lhorie/mithril.js/issues/44 + var root = mock.document.createElement("div") + m.render(root, m("#foo", [null, m("#bar")])) + m.render(root, m("#foo", [m("div"), m("#bar")])) + return root.childNodes[0].childNodes[0].nodeName === "DIV" + }) //m.redraw test(function() { diff --git a/archive/v0.1.4/mithril.js b/archive/v0.1.4/mithril.js index 28912e30..5b3e6063 100644 --- a/archive/v0.1.4/mithril.js +++ b/archive/v0.1.4/mithril.js @@ -32,7 +32,7 @@ new function(window) { } return cell } - function build(parent, data, cached, shouldReattach) { + function build(parent, data, cached, shouldReattach, index) { if (data === null || data === undefined) { if (cached) clear(cached.nodes) return @@ -49,7 +49,7 @@ new function(window) { if (dataType == "[object Array]") { var nodes = [], intact = cached.length === data.length for (var i = 0; i < data.length; i++) { - var item = build(parent, data[i], cached[i], shouldReattach) + var item = build(parent, data[i], cached[i], shouldReattach, i) if (item === undefined) continue if (!item.nodes.intact) intact = false cached[i] = item @@ -70,14 +70,14 @@ new function(window) { if (isNew) { node = window.document.createElement(data.tag) cached = {tag: data.tag, attrs: setAttributes(node, data.attrs, {}), children: build(node, data.children, cached.children, true), nodes: [node]} - parent.appendChild(node) + parent.insertBefore(node, parent.childNodes[index]) } else { node = cached.nodes[0] setAttributes(node, data.attrs, cached.attrs) cached.children = build(node, data.children, cached.children, false) cached.nodes.intact = true - if (shouldReattach === true) parent.appendChild(node) + if (shouldReattach === true) parent.insertBefore(node, parent.childNodes[index]) } if (type.call(data.attrs["config"]) == "[object Function]") data.attrs["config"](node, !isNew) } @@ -91,7 +91,7 @@ new function(window) { } else { node = window.document.createTextNode(data) - parent.appendChild(node) + parent.insertBefore(node, parent.childNodes[index]) } cached = "string number boolean".indexOf(typeof data) > -1 ? new data.constructor(data) : data cached.nodes = [node] @@ -110,7 +110,7 @@ new function(window) { } else { node = cached.nodes[0] - parent.appendChild(node) + parent.insertBefore(node, parent.childNodes[index]) node.nodeValue = data } cached = new data.constructor(data) diff --git a/archive/v0.1.4/mithril.min.js b/archive/v0.1.4/mithril.min.js index 97ce9252..2ab9844c 100644 --- a/archive/v0.1.4/mithril.min.js +++ b/archive/v0.1.4/mithril.min.js @@ -4,5 +4,5 @@ http://github.com/lhorie/mithril.js (c) Leo Horie License: MIT */ -!new function(a){function b(e,f,g,h){if(null===f||void 0===f)return void(g&&d(g.nodes));if("retain"!==f.subtree){var i=s.call(g),j=s.call(f);if(i!=j&&(null!==g&&void 0!==g&&d(g.nodes),g=new f.constructor,g.nodes=[]),"[object Array]"==j){for(var k=[],l=g.length===f.length,m=0;m-1?new f.constructor(f):f,g.nodes=[o]}else if(g.valueOf()!==f.valueOf()){if(f.$trusted){var r=g.nodes[0],k=[r];if(r){for(;r=r.nextSibling;)k.push(r);d(k);var q=e.lastChild;e.insertAdjacentHTML("beforeend",f),o=q?q.nextSibling:e.firstChild}else e.innerHTML=f}else o=g.nodes[0],e.appendChild(o),o.nodeValue=f;g=new f.constructor(f),g.nodes=[o]}else g.nodes.intact=!0}return g}}function c(b,c,d){for(var e in c){var g=c[e],h=d[e];if(!(e in d)||h!==g||b===a.document.activeElement){if(d[e]=g,"config"===e)continue;if("function"==typeof g&&0==e.indexOf("on"))b[e]=f(g,b);else if("style"===e)for(var i in g)(void 0===h||h[i]!==g[i])&&(b.style[i]=g[i]);else e in b?b[e]=g:b.setAttribute(e,g)}}return d}function d(a){for(var b=0;b16)m.redraw();else{var b=a.cancelAnimationFrame||a.clearTimeout,c=a.requestAnimationFrame||a.setTimeout;b(E),E=c(m.redraw,0)}}function h(a,b,c){J={};for(var d in b){if(d==c)return!void m.module(a,b[d]);var e=new RegExp("^"+d.replace(/:[^\/]+/g,"([^\\/]+)")+"$");if(e.test(c))return!void c.replace(e,function(){for(var c=d.match(/:[^\/]+/g),e=[].slice.call(arguments,1,-2),f=0;f0&&("GET"==a.method?a.url=a.url+(a.url.indexOf("?")<0?"?":"&")+n(b):a.data=c(b)),a}function p(a,b){var c=a.match(/:[a-z]\w+/gi);if(c&&b)for(var d=0;d0&&(f.attrs[d]=h.join(" "))}f=e(f),f.attrs=e(f.attrs),f.children=b?a[2]:a[1];for(var j in c)f.attrs[j]=j==d?(f.attrs[j]||"")+" "+c[j]:c[j];return f};var v,w={insertAdjacentHTML:function(b,c){a.document.write(c),a.document.close()},appendChild:function(b){void 0===v&&(v=a.document.createElement("html")),"HTML"==b.nodeName?v=b:v.appendChild(b),a.document.documentElement!==v&&a.document.replaceChild(v,a.document.documentElement)}},x=[],y={};m.render=function(c,d){var e=x.indexOf(c),f=0>e?x.push(c)-1:e,g=c==a.document||c==a.document.documentElement?w:c;y[f]=b(g,d,y[f],!1)},m.trust=function(a){return a=new String(a),a.$trusted=!0,a};var z,A={view:function(){}},B={},C=0,D=0,E=0;m.module=function(a,b){m.startComputation(),z=a,A=b,B=new b.controller,m.endComputation()},m.redraw=function(){m.render(z,A.view(B)),D=C};var F=0,G=null;m.startComputation=function(){F++},m.endComputation=function(){F=Math.max(F-1,0),0==F&&(g(),G&&(G(),G=null))},m.withAttr=function(a,b){return function(c){b(a in c.currentTarget?c.currentTarget[a]:c.currentTarget.getAttribute(a))}};var H={pathname:"",hash:"#",search:"?"},I=function(){},J={};m.route=function(){if(3==arguments.length){var b=arguments[0],c=arguments[1],d=arguments[2];I=function(a){var e=a.slice(H[m.route.mode].length);h(b,d,e)||m.route(c,!0)};var e="hash"==m.route.mode?"onhashchange":"onpopstate";a[e]=function(){I(a.location[m.route.mode])},G=j,a[e]()}else if(arguments[0].addEventListener){var f=arguments[0],g=arguments[1];g||(f.removeEventListener("click",i),f.addEventListener("click",i))}else if("string"==typeof arguments[0]){var k=arguments[0],l=arguments[1]===!0;a.history.pushState?(G=function(){a.history[l?"replaceState":"pushState"](null,a.document.title,H[m.route.mode]+k),j()},I(H[m.route.mode]+k)):a.location[m.route.mode]=k}},m.route.param=function(a){return J[a]},m.route.mode="search",m.prop=function(a){return function(){return arguments.length&&(a=arguments[0]),a}},m.deferred=function(){var a=[],b=[],c={resolve:function(b){for(var c=0;c-1?new f.constructor(f):f,g.nodes=[p]}else if(g.valueOf()!==f.valueOf()){if(f.$trusted){var t=g.nodes[0],l=[t];if(t){for(;t=t.nextSibling;)l.push(t);d(l);var r=e.lastChild;e.insertAdjacentHTML("beforeend",f),p=r?r.nextSibling:e.firstChild}else e.innerHTML=f}else p=g.nodes[0],e.insertBefore(p,e.childNodes[i]),p.nodeValue=f;g=new f.constructor(f),g.nodes=[p]}else g.nodes.intact=!0}return g}}function c(b,c,d){for(var e in c){var g=c[e],h=d[e];if(!(e in d)||h!==g||b===a.document.activeElement){if(d[e]=g,"config"===e)continue;if("function"==typeof g&&0==e.indexOf("on"))b[e]=f(g,b);else if("style"===e)for(var i in g)(void 0===h||h[i]!==g[i])&&(b.style[i]=g[i]);else e in b?b[e]=g:b.setAttribute(e,g)}}return d}function d(a){for(var b=0;b16)m.redraw();else{var b=a.cancelAnimationFrame||a.clearTimeout,c=a.requestAnimationFrame||a.setTimeout;b(E),E=c(m.redraw,0)}}function h(a,b,c){J={};for(var d in b){if(d==c)return!void m.module(a,b[d]);var e=new RegExp("^"+d.replace(/:[^\/]+/g,"([^\\/]+)")+"$");if(e.test(c))return!void c.replace(e,function(){for(var c=d.match(/:[^\/]+/g),e=[].slice.call(arguments,1,-2),f=0;f0&&("GET"==a.method?a.url=a.url+(a.url.indexOf("?")<0?"?":"&")+n(b):a.data=c(b)),a}function p(a,b){var c=a.match(/:[a-z]\w+/gi);if(c&&b)for(var d=0;d0&&(f.attrs[d]=h.join(" "))}f=e(f),f.attrs=e(f.attrs),f.children=b?a[2]:a[1];for(var j in c)f.attrs[j]=j==d?(f.attrs[j]||"")+" "+c[j]:c[j];return f};var v,w={insertAdjacentHTML:function(b,c){a.document.write(c),a.document.close()},appendChild:function(b){void 0===v&&(v=a.document.createElement("html")),"HTML"==b.nodeName?v=b:v.appendChild(b),a.document.documentElement!==v&&a.document.replaceChild(v,a.document.documentElement)}},x=[],y={};m.render=function(c,d){var e=x.indexOf(c),f=0>e?x.push(c)-1:e,g=c==a.document||c==a.document.documentElement?w:c;y[f]=b(g,d,y[f],!1)},m.trust=function(a){return a=new String(a),a.$trusted=!0,a};var z,A={view:function(){}},B={},C=0,D=0,E=0;m.module=function(a,b){m.startComputation(),z=a,A=b,B=new b.controller,m.endComputation()},m.redraw=function(){m.render(z,A.view(B)),D=C};var F=0,G=null;m.startComputation=function(){F++},m.endComputation=function(){F=Math.max(F-1,0),0==F&&(g(),G&&(G(),G=null))},m.withAttr=function(a,b){return function(c){b(a in c.currentTarget?c.currentTarget[a]:c.currentTarget.getAttribute(a))}};var H={pathname:"",hash:"#",search:"?"},I=function(){},J={};m.route=function(){if(3==arguments.length){var b=arguments[0],c=arguments[1],d=arguments[2];I=function(a){var e=a.slice(H[m.route.mode].length);h(b,d,e)||m.route(c,!0)};var e="hash"==m.route.mode?"onhashchange":"onpopstate";a[e]=function(){I(a.location[m.route.mode])},G=j,a[e]()}else if(arguments[0].addEventListener){var f=arguments[0],g=arguments[1];g||(f.removeEventListener("click",i),f.addEventListener("click",i))}else if("string"==typeof arguments[0]){var k=arguments[0],l=arguments[1]===!0;a.history.pushState?(G=function(){a.history[l?"replaceState":"pushState"](null,a.document.title,H[m.route.mode]+k),j()},I(H[m.route.mode]+k)):a.location[m.route.mode]=k}},m.route.param=function(a){return J[a]},m.route.mode="search",m.prop=function(a){return function(){return arguments.length&&(a=arguments[0]),a}},m.deferred=function(){var a=[],b=[],c={resolve:function(b){for(var c=0;c -1 ? new data.constructor(data) : data cached.nodes = [node] @@ -110,7 +110,7 @@ new function(window) { } else { node = cached.nodes[0] - parent.appendChild(node) + parent.insertBefore(node, parent.childNodes[index]) node.nodeValue = data } cached = new data.constructor(data) diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index ff6adf39..39225477 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -142,13 +142,14 @@ function testMithril(mock) { return root.childNodes[0].childNodes[0].childNodes[0].nodeName === "A" }) test(function() { + //https://github.com/lhorie/mithril.js/issues/43 var root = mock.document.createElement("div") m.render(root, m("a", {config: m.route}, "test")) m.render(root, m("a", {config: m.route}, "test")) return root.childNodes[0].childNodes[0].nodeValue === "test" }) test(function() { - //see issue #29 + //https://github.com/lhorie/mithril.js/issues/29 var root = mock.document.createElement("div") var list = [false, false] m.render(root, list.reverse().map(function(flag, index) { @@ -167,6 +168,20 @@ function testMithril(mock) { return root.childNodes[0].checked === false && root.childNodes[1].checked === true }) + test(function() { + //https://github.com/lhorie/mithril.js/issues/44 + var root = mock.document.createElement("div") + m.render(root, m("#foo", [null, m("#bar")])) + m.render(root, m("#foo", ["test", m("#bar")])) + return root.childNodes[0].childNodes[0].nodeValue === "test" + }) + test(function() { + //https://github.com/lhorie/mithril.js/issues/44 + var root = mock.document.createElement("div") + m.render(root, m("#foo", [null, m("#bar")])) + m.render(root, m("#foo", [m("div"), m("#bar")])) + return root.childNodes[0].childNodes[0].nodeName === "DIV" + }) //m.redraw test(function() { diff --git a/tests/mock.js b/tests/mock.js index dfbe99c1..c8b6c6fd 100644 --- a/tests/mock.js +++ b/tests/mock.js @@ -10,6 +10,12 @@ mock.window = new function() { appendChild: window.document.appendChild, removeChild: window.document.removeChild, replaceChild: window.document.replaceChild, + insertBefore: function(node, reference) { + node.parentNode = this + var index = this.childNodes.indexOf(reference) + if (index < 0) this.childNodes.push(node) + else this.childNodes.splice(index, 0, node) + }, setAttribute: function(name, value) { this[name] = value.toString() },