diff --git a/mithril.js b/mithril.js index 96dc3db9..91348bb4 100644 --- a/mithril.js +++ b/mithril.js @@ -1,10 +1,6 @@ Mithril = m = new function app(window, undefined) { - var sObj = "[object Object]", sArr = "[object Array]", sStr = "[object String]" - function type(obj) {return {}.toString.call(obj)} - function isObj(obj) {return obj != null && type(obj) == sObj} - function isArr(obj) {return type(obj) == sArr} - function isFn(obj) {return typeof obj == "function"} - function isStr(obj){ return type(obj) == sStr} + var sObj = "[object Object]", sArr = "[object Array]", sStr = "[object String]", sFn = "function" + var type = {}.toString var parser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:=("|'|)(.*?)\2)?\]/ var voidElements = /AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR/ @@ -23,7 +19,7 @@ Mithril = m = new function app(window, undefined) { */ function m() { var args = [].slice.call(arguments) - var hasAttrs = isObj(args[1]) && !("tag" in args[1]) && !("subtree" in args[1]) + var hasAttrs = args[1] != null && type.call(args[1]) == sObj && !("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: {}} @@ -41,7 +37,7 @@ Mithril = m = new function app(window, undefined) { var children = hasAttrs ? args[2] : args[1] - if (isArr(children)) { + if (type.call(children) == sArr) { cell.children = children } else { @@ -82,7 +78,7 @@ Mithril = m = new function app(window, undefined) { //- it simplifies diffing code if (data == null) data = "" if (data.subtree === "retain") return cached - var cachedType = type(cached), dataType = type(data) + var cachedType = type.call(cached), dataType = type.call(data) if (cached == null || cachedType != dataType) { if (cached != null) { if (parentCache && parentCache.nodes) { @@ -176,7 +172,7 @@ Mithril = m = new function app(window, undefined) { //the second clause (after the pipe) matches text nodes subArrayCount += (item.match(/<[^\/]|\>\s*[^<]/g) || []).length } - else subArrayCount += isArr(item) ? item.length : 1 + else subArrayCount += type.call(item) == sArr ? item.length : 1 cached[cacheCount++] = item } if (!intact) { @@ -202,12 +198,14 @@ Mithril = m = new function app(window, undefined) { else if (data != null && dataType == sObj) { if (!data.attrs) data.attrs = {} if (!cached.attrs) cached.attrs = {} + + var dataAttrKeys = Object.keys(data.attrs) //if an element is different enough from the one in cache, recreate it - if (data.tag != cached.tag || Object.keys(data.attrs).join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id) { - clear(cached.nodes) - if (cached.configContext && isFn(cached.configContext.onunload)) cached.configContext.onunload() + if (data.tag != cached.tag || dataAttrKeys.join() != Object.keys(cached.attrs).join() || data.attrs.id != cached.attrs.id) { + if (cached.nodes.length) clear(cached.nodes) + if (cached.configContext && typeof cached.configContext.onunload == sFn) cached.configContext.onunload() } - if (!isStr(data.tag)) return + if (type.call(data.tag) != sStr) return var node, isNew = cached.nodes.length === 0 if (data.attrs.xmlns) namespace = data.attrs.xmlns @@ -218,23 +216,26 @@ Mithril = m = new function app(window, undefined) { cached = { tag: data.tag, //set attributes first, then create children - attrs: setAttributes(node, data.tag, data.attrs, {}, namespace), - children: build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace, configs), + attrs: dataAttrKeys.length ? setAttributes(node, data.tag, data.attrs, {}, namespace) : {}, + children: data.children != null && data.children.length > 0 ? + build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace, configs) : + data.children, nodes: [node] } + if (cached.children && !cached.children.nodes) cached.children.nodes = [] //edge case: setting value on