fix diff on nested arrays
This commit is contained in:
parent
ec69af4660
commit
4d04ce034d
3 changed files with 71 additions and 7 deletions
|
|
@ -5,6 +5,8 @@
|
||||||
### Bug Fixes:
|
### Bug Fixes:
|
||||||
|
|
||||||
- prevent route change when only hash changes in non-hash mode [#107](https://github.com/lhorie/mithril.js/issues/107)
|
- prevent route change when only hash changes in non-hash mode [#107](https://github.com/lhorie/mithril.js/issues/107)
|
||||||
|
- fix null reference exception with Browserify [#110](https://github.com/lhorie/mithril.js/issues/110)
|
||||||
|
- fix nested array removal edge cases [#120](https://github.com/lhorie/mithril.js/issues/120)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
18
mithril.js
18
mithril.js
|
|
@ -32,13 +32,19 @@ Mithril = m = new function app(window) {
|
||||||
}
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
function build(parentElement, parentTag, data, cached, shouldReattach, index, editable, namespace) {
|
function build(parentElement, parentTag, parentCache, parentIndex, data, cached, shouldReattach, index, editable, namespace) {
|
||||||
if (data === null || data === undefined) data = ""
|
if (data === null || data === undefined) data = ""
|
||||||
if (data.subtree === "retain") return
|
if (data.subtree === "retain") return
|
||||||
|
|
||||||
var cachedType = type.call(cached), dataType = type.call(data)
|
var cachedType = type.call(cached), dataType = type.call(data)
|
||||||
if (cachedType != dataType) {
|
if (cachedType != dataType) {
|
||||||
if (cached !== null && cached !== undefined) clear(cached.nodes)
|
if (cached !== null && cached !== undefined) {
|
||||||
|
if (parentCache && parentCache.nodes) {
|
||||||
|
var offset = index - parentIndex
|
||||||
|
clear(parentCache.nodes.slice(offset, offset + (dataType == "[object Array]" ? data : cached.nodes).length))
|
||||||
|
}
|
||||||
|
else clear(cached.nodes)
|
||||||
|
}
|
||||||
cached = new data.constructor
|
cached = new data.constructor
|
||||||
cached.nodes = []
|
cached.nodes = []
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +52,7 @@ Mithril = m = new function app(window) {
|
||||||
if (dataType == "[object Array]") {
|
if (dataType == "[object Array]") {
|
||||||
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
var nodes = [], intact = cached.length === data.length, subArrayCount = 0
|
||||||
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
for (var i = 0, cacheCount = 0; i < data.length; i++) {
|
||||||
var item = build(parentElement, null, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace)
|
var item = build(parentElement, null, cached, index, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace)
|
||||||
if (item === undefined) continue
|
if (item === undefined) continue
|
||||||
if (!item.nodes.intact) intact = false
|
if (!item.nodes.intact) intact = false
|
||||||
subArrayCount += item instanceof Array ? item.length : 1
|
subArrayCount += item instanceof Array ? item.length : 1
|
||||||
|
|
@ -78,7 +84,7 @@ Mithril = m = new function app(window) {
|
||||||
cached = {
|
cached = {
|
||||||
tag: data.tag,
|
tag: data.tag,
|
||||||
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
attrs: setAttributes(node, data.tag, data.attrs, {}, namespace),
|
||||||
children: data.children !== undefined ? build(node, data.tag, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace) : undefined,
|
children: data.children !== undefined ? build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace) : undefined,
|
||||||
nodes: [node]
|
nodes: [node]
|
||||||
}
|
}
|
||||||
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
|
|
@ -86,7 +92,7 @@ Mithril = m = new function app(window) {
|
||||||
else {
|
else {
|
||||||
node = cached.nodes[0]
|
node = cached.nodes[0]
|
||||||
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
setAttributes(node, data.tag, data.attrs, cached.attrs, namespace)
|
||||||
cached.children = build(node, data.tag, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace)
|
cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace)
|
||||||
cached.nodes.intact = true
|
cached.nodes.intact = true
|
||||||
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
if (shouldReattach === true) parentElement.insertBefore(node, parentElement.childNodes[index] || null)
|
||||||
}
|
}
|
||||||
|
|
@ -217,7 +223,7 @@ Mithril = m = new function app(window) {
|
||||||
var index = nodeCache.indexOf(root)
|
var index = nodeCache.indexOf(root)
|
||||||
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
var id = index < 0 ? nodeCache.push(root) - 1 : index
|
||||||
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
var node = root == window.document || root == window.document.documentElement ? documentNode : root
|
||||||
cellCache[id] = build(node, null, cell, cellCache[id], false, 0, null, undefined)
|
cellCache[id] = build(node, null, undefined, undefined, cell, cellCache[id], false, 0, null, undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.trust = function(value) {
|
m.trust = function(value) {
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ function testMithril(mock) {
|
||||||
var root = mock.document.createElement("div")
|
var root = mock.document.createElement("div")
|
||||||
m.render(root, m("ul", [m("li"), m("li")]))
|
m.render(root, m("ul", [m("li"), m("li")]))
|
||||||
m.render(root, m("ul", [m("li"), undefined]))
|
m.render(root, m("ul", [m("li"), undefined]))
|
||||||
return root.childNodes[0].childNodes[1].nodeValue === ""
|
return root.childNodes[0].childNodes.length == 2 && root.childNodes[0].childNodes[1].nodeValue === ""
|
||||||
})
|
})
|
||||||
test(function() {
|
test(function() {
|
||||||
var root = mock.document.createElement("div")
|
var root = mock.document.createElement("div")
|
||||||
|
|
@ -398,6 +398,62 @@ function testMithril(mock) {
|
||||||
m.render(root, m("div", [m("a")]))
|
m.render(root, m("div", [m("a")]))
|
||||||
return root.childNodes[0].childNodes.length == 1 && root.childNodes[0].childNodes[0].nodeName == "A"
|
return root.childNodes[0].childNodes.length == 1 && root.childNodes[0].childNodes[0].nodeName == "A"
|
||||||
})
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", "b", "c", "d"]))
|
||||||
|
m.render(root, m("div", [["d", "e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", [["a", "b", "c", "d"]]))
|
||||||
|
m.render(root, m("div", ["d", "e"]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["x", [["a"], "b", "c", "d"]]))
|
||||||
|
m.render(root, m("div", ["d", ["e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["b"]))
|
||||||
|
m.render(root, m("div", [["e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 1 && children[0].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", ["b"]]))
|
||||||
|
m.render(root, m("div", ["d", [["e"]]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", [["b"]]]))
|
||||||
|
m.render(root, m("div", ["d", ["e"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 2 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
|
test(function() {
|
||||||
|
//https://github.com/lhorie/mithril.js/issues/120
|
||||||
|
var root = mock.document.createElement("div")
|
||||||
|
m.render(root, m("div", ["a", [["b"], "c"]]))
|
||||||
|
m.render(root, m("div", ["d", [[["e"]], "x"]]))
|
||||||
|
var children = root.childNodes[0].childNodes
|
||||||
|
return children.length == 3 && children[0].nodeValue == "d" && children[1].nodeValue == "e"
|
||||||
|
})
|
||||||
//end m.render
|
//end m.render
|
||||||
|
|
||||||
//m.redraw
|
//m.redraw
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue