From c4cd99b0932019ffbcaa850f915a372bb7e31206 Mon Sep 17 00:00:00 2001 From: oleg8sh Date: Thu, 7 Aug 2014 23:32:25 +0400 Subject: [PATCH 1/5] Protection from external 'undefined' --- mithril.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mithril.js b/mithril.js index f36a54bb..22758864 100644 --- a/mithril.js +++ b/mithril.js @@ -1,4 +1,4 @@ -Mithril = m = new function app(window) { +Mithril = m = new function app(window, undefined) { var type = {}.toString var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/ From 459a38e8d9fbae69793f4cb04a3255422719e467 Mon Sep 17 00:00:00 2001 From: oleg8sh Date: Fri, 8 Aug 2014 02:30:39 +0400 Subject: [PATCH 2/5] Don't insert blank text node into every tag (yet another IE8 issue) Actually Mithril calls build() with data undefined for m("tag",{...}) [calls without third argument]. The changing undefined to "" causes build() insert a TextNode into current tag (on line 169). But in IE8 it isn't allowed to insert a TextNode into any tag. For example, m("input",{...}) fails here. With this simple patch undefined is not chaged to "" anymore. (And no empty TextNode's added to every mentioned tag.) --- mithril.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mithril.js b/mithril.js index f36a54bb..bb761a77 100644 --- a/mithril.js +++ b/mithril.js @@ -29,7 +29,8 @@ Mithril = m = new function app(window) { return cell } function build(parentElement, parentTag, parentCache, parentIndex, data, cached, shouldReattach, index, editable, namespace, configs) { - if (data === null || data === undefined) data = "" + if (data === undefined) return undefined + if (data === null) data = "" if (data.subtree === "retain") return cached var cachedType = type.call(cached), dataType = type.call(data) From c0c349ef2018e141ba6ac1cbaf459d910985d9f3 Mon Sep 17 00:00:00 2001 From: oleg8sh Date: Fri, 8 Aug 2014 02:37:06 +0400 Subject: [PATCH 3/5] currentTarget issue in IE8 There is no currentTarget in IE8. So withAttr() fails in it. But 'this' is binded to that already. It's Ok. More info: http://stackoverflow.com/questions/857439/internet-explorer-and-javascript-event-currenttarget http://www.brainjar.com/dhtml/events/default3.asp --- mithril.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mithril.js b/mithril.js index f36a54bb..7f3192b5 100644 --- a/mithril.js +++ b/mithril.js @@ -384,7 +384,8 @@ Mithril = m = new function app(window) { m.withAttr = function(prop, withAttrCallback) { return function(e) { e = e || event - withAttrCallback(prop in e.currentTarget ? e.currentTarget[prop] : e.currentTarget.getAttribute(prop)) + var currentTarget = e.currentTarget || this + withAttrCallback(prop in currentTarget ? currentTarget[prop] : currentTarget.getAttribute(prop)) } } From f643636eb360c261fcf6819b572dcb43189f4cd9 Mon Sep 17 00:00:00 2001 From: oleg8sh Date: Fri, 8 Aug 2014 23:11:45 +0400 Subject: [PATCH 4/5] undefined cached checks. Part of #185. Should fix #162 & #163. --- mithril.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mithril.js b/mithril.js index 7ba2c900..550a4345 100644 --- a/mithril.js +++ b/mithril.js @@ -33,7 +33,7 @@ Mithril = m = new function app(window, undefined) { if (data.subtree === "retain") return cached var cachedType = type.call(cached), dataType = type.call(data) - if (cachedType != dataType) { + if (cached === undefined || cached === null || cachedType != dataType) { if (cached !== null && cached !== undefined) { if (parentCache && parentCache.nodes) { var offset = index - parentIndex From 807c6f415a27d693b69342cdb3df368c82d359f5 Mon Sep 17 00:00:00 2001 From: oleg8sh Date: Sat, 9 Aug 2014 00:03:22 +0400 Subject: [PATCH 5/5] typeof is much faster than {}.toString() Proof: http://jsperf.com/typeof-vs-instanceof-vs-object-prototype-tostring --- mithril.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mithril.js b/mithril.js index 7ba2c900..37afe48f 100644 --- a/mithril.js +++ b/mithril.js @@ -153,7 +153,7 @@ Mithril = m = new function app(window, undefined) { cached.nodes.intact = true if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null) } - if (type.call(data.attrs["config"]) == "[object Function]") { + if (typeof data.attrs["config"] === "function") { configs.push(data.attrs["config"].bind(window, node, !isNew, cached.configContext = cached.configContext || {}, cached)) } }