diff --git a/mithril.js b/mithril.js index 5a4eb7ae..f5812eef 100644 --- a/mithril.js +++ b/mithril.js @@ -23,7 +23,7 @@ Mithril = m = new function app(window, undefined) { */ function m() { var args = [].slice.call(arguments) - var hasAttrs = args[1] != null && isObj(args[1]) && !("tag" in args[1]) && !("subtree" in args[1]) + var hasAttrs = isObj(args[1]) && !("tag" in args[1]) && !("subtree" in args[1]) var attrs = hasAttrs ? args[1] : {} var classAttrName = "class" in attrs ? "class" : "className" var cell = {tag: "div", attrs: {}} @@ -143,20 +143,20 @@ Mithril = m = new function app(window, undefined) { if (change.action == INSERTION) { var dummy = window.document.createElement("div") dummy.key = data[change.index].attrs.key - parentElement.insertBefore(dummy, parentElement.childNodes[change.index]) + parentElement.insertBefore(dummy, parentElement.childNodes[change.index] || null) newCached.splice(change.index, 0, {attrs: {key: data[change.index].attrs.key}, nodes: [dummy]}) } if (change.action == MOVE) { if (parentElement.childNodes[change.index] !== change.element && change.element !== null) { - parentElement.insertBefore(change.element, parentElement.childNodes[change.index]) + parentElement.insertBefore(change.element, parentElement.childNodes[change.index] || null) } newCached[change.index] = cached[change.from] } } for (var i = 0; i < unkeyed.length; i++) { var change = unkeyed[i] - parentElement.insertBefore(change.element, parentElement.childNodes[change.index]) + parentElement.insertBefore(change.element, parentElement.childNodes[change.index] || null) newCached[change.index] = cached[change.index] } cached = newCached @@ -352,7 +352,7 @@ Mithril = m = new function app(window, undefined) { var isElement = nextSibling.nodeType != 1 var placeholder = window.document.createElement("span") if (isElement) { - parentElement.insertBefore(placeholder, nextSibling) + parentElement.insertBefore(placeholder, nextSibling || null) placeholder.insertAdjacentHTML("beforebegin", data) parentElement.removeChild(placeholder) } @@ -810,8 +810,8 @@ Mithril = m = new function app(window, undefined) { if (options.dataType && options.dataType.toLowerCase() === "jsonp") { var callbackKey = "mithril_callback_" + new Date().getTime() + "_" + (Math.round(Math.random() * 1e16)).toString(36) var script = window.document.createElement("script") - - window[callbackKey] = function(resp){ + + window[callbackKey] = function(resp) { window.document.body.removeChild(script) options.onload({ type: "load", @@ -819,11 +819,10 @@ Mithril = m = new function app(window, undefined) { responseText: resp } }) - delete window[callbackKey] + window[callbackKey] = undefined } script.onerror = function(e) { - delete window[callbackKey] window.document.body.removeChild(script) options.onerror({ @@ -833,6 +832,7 @@ Mithril = m = new function app(window, undefined) { responseText: JSON.stringify({error: "Error making jsonp request"}) } }) + window[callbackKey] = undefined return false } diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 75443038..e3e6bd3e 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -1,6 +1,6 @@ function testMithril(mock) { m.deps(mock) - + //m test(function() {return m("div").tag === "div"}) test(function() {return m(".foo").tag === "div"}) @@ -1664,136 +1664,91 @@ function testMithril(mock) { // m.request over jsonp test(function(){ // script tags cannot be appended directly on the document + var body = mock.document.createElement("body") + mock.document.body = body + mock.document.appendChild(body) + + var error = m.prop("no error") + var data + var req = m.request({url: "/test", dataType: "jsonp"}).then(function(received) {data = received}, error) + var callbackKey = Object.keys(mock).filter(function(globalKey){ + return globalKey.indexOf("mithril_callback") > -1 + }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() + mock[callbackKey]({foo: "bar"}) + mock.document.removeChild(body) + return scriptTag.src.indexOf("/test?callback=mithril_callback") > -1 && data.foo == "bar" + }) + test(function(){ + // script tags cannot be appended directly on the document + var body = mock.document.createElement("body") + mock.document.body = body + mock.document.appendChild(body) + + var error = m.prop("no error") + var data + var req = m.request({url: "/test", dataType: "jsonp", callbackKey: "jsonpCallback"}).then(function(received) {data = received}, error); + var callbackKey = Object.keys(mock).filter(function(globalKey){ + return globalKey.indexOf("mithril_callback") > -1 + }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop() + mock[callbackKey]({foo: "bar1"}) + mock.document.removeChild(body) + return scriptTag.src.indexOf("/test?jsonpCallback=mithril_callback") > -1 && data.foo == "bar1" + }) + test(function(){ + var body = mock.document.createElement("body") + mock.document.body = body + mock.document.appendChild(body) + + var req = m.request({url: "/test", dataType: "jsonp"}) + var callbackKey = Object.keys(mock).filter(function(globalKey){ + return globalKey.indexOf("mithril_callback") > -1 + }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop(); + mock[callbackKey]({foo: "bar1"}) + var out = {foo: "bar1"} + mock.document.removeChild(body) + return JSON.stringify(out) === JSON.stringify(req()) + }) + test(function(){ + var body = mock.document.createElement("body") + mock.document.body = body + mock.document.appendChild(body) + + var req = m.request({url: "/test", dataType: "jsonp", data: {foo: "bar"}}) + var callbackKey = Object.keys(mock).filter(function(globalKey){ + return globalKey.indexOf("mithril_callback") > -1 + }).pop() + var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ + return script.src.indexOf(callbackKey) > -1 + }).pop(); + mock[callbackKey]({foo: "bar"}) + return scriptTag.src.indexOf("foo=bar") > -1 + }) + test(function(){ var body = mock.document.createElement("body"); mock.document.body = body; mock.document.appendChild(body); - var error = m.prop("no error"); - var data - var req = m.request({url: "/test", dataType: "jsonp"}).then(function(received) {data = received}, error); + var _window = mock; + var error = m.prop(false); + var req = m.request({url: "/test", dataType: "jsonp", method: "GET", data: {foo: "bar"}}); var callbackKey = Object.keys(mock).filter(function(globalKey){ return globalKey.indexOf("mithril_callback") > -1 - }).pop(); + }).pop() var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ return script.src.indexOf(callbackKey) > -1 }).pop(); mock[callbackKey]({foo: "bar"}) mock.document.removeChild(body); - return scriptTag.src.indexOf("/test?callback=mithril_callback") > -1 && data.foo == "bar"; - }) - test(function(){ - // script tags cannot be appended directly on the document - var body = mock.document.createElement("body"); - mock.document.body = body; - mock.document.appendChild(body); - - var error = m.prop("no error"); - var data - var req = m.request({url: "/test", dataType: "jsonp", callbackKey: "jsonpCallback"}).then(function(received) {data = received}, error); - var callbackKey = Object.keys(mock).filter(function(globalKey){ - return globalKey.indexOf("mithril_callback") > -1 - }).pop(); - var scriptTag = [].slice.call(mock.document.getElementsByTagName("script")).filter(function(script){ - return script.src.indexOf(callbackKey) > -1 - }).pop(); - mock[callbackKey]({foo: "bar1"})//fixme ie - mock.document.removeChild(body); - return scriptTag.src.indexOf("/test?jsonpCallback=mithril_callback") > -1 && data.foo == "bar1"; - }) - test(function(){ - var body = mock.document.createElement("body"); - mock.document.body = body; - mock.document.appendChild(body); - - var _window = mock; - var req = m.request({ - url: "/test", - dataType: "jsonp", - background: true - }); - var callbackKeys = []; - Object.keys(_window).forEach(function(globalKey){ - if(globalKey.indexOf("mithril_callback") > -1) - callbackKeys.push(globalKey); - }); - var scriptTag = null; - mock.document.getElementsByTagName("script").forEach(function(script){ - if(!scriptTag && script.src.indexOf(callbackKeys[0]) > -1) - scriptTag = script; - }); - var out = { foo: "bar" }; - if(scriptTag && callbackKeys.length > 0){ - _window[callbackKeys[0]](out); - mock.document.body.removeChild(scriptTag); - delete _window[callbackKeys[0]]; - } - mock.document.removeChild(body); - return JSON.stringify(out) === JSON.stringify(req()); - }) - test(function(){ - var body = mock.document.createElement("body"); - mock.document.body = body; - mock.document.appendChild(body); - - var _window = mock; - var error = m.prop(false); - var req = m.request({ - url: "/test", - dataType: "jsonp", - data: { foo: "bar" }, - background: true - }); - var callbackKeys = []; - Object.keys(_window).forEach(function(globalKey){ - if(globalKey.indexOf("mithril_callback") > -1) - callbackKeys.push(globalKey); - }); - var scriptTag = null; - mock.document.getElementsByTagName("script").forEach(function(script){ - if(!scriptTag && script.src.indexOf(callbackKeys[0]) > -1) - scriptTag = script; - }); - var correctData = false; - if(scriptTag){ - correctData = scriptTag.src.indexOf("foo=bar") > -1; - mock.document.body.removeChild(scriptTag); - delete _window[callbackKeys[0]]; - } - mock.document.removeChild(body); - return correctData; - }) - test(function(){ - var body = mock.document.createElement("body"); - mock.document.body = body; - mock.document.appendChild(body); - - var _window = mock; - var error = m.prop(false); - var req = m.request({ - url: "/test", - dataType: "jsonp", - method: "GET", - data: { foo: "bar" }, - background: true - }); - var callbackKeys = []; - Object.keys(_window).forEach(function(globalKey){ - if(globalKey.indexOf("mithril_callback") > -1) - callbackKeys.push(globalKey); - }); - var scriptTag = null; - mock.document.getElementsByTagName("script").forEach(function(script){ - if(!scriptTag && script.src.indexOf(callbackKeys[0]) > -1) - scriptTag = script; - }); - var correctData = false; - if(scriptTag){ - correctData = scriptTag.src.match(/foo=bar/g).length == 1; - mock.document.body.removeChild(scriptTag); - delete _window[callbackKeys[0]]; - } - mock.document.removeChild(body); - return correctData; + return scriptTag.src.match(/foo=bar/g).length == 1; }) //m.deferred @@ -2000,10 +1955,9 @@ function testMithril(mock) { test(function() { mock.requestAnimationFrame.$resolve() - var controller var root = mock.document.createElement("div") - m.module(root, { - controller: function() {controller = this}, + var controller = m.module(root, { + controller: function() {}, view: function(ctrl) {return ctrl.value} }) @@ -2013,7 +1967,6 @@ function testMithril(mock) { controller.value = "foo" m.endComputation() mock.requestAnimationFrame.$resolve() - return root.childNodes[0].nodeValue === "foo" })