fix m.trust diffing

This commit is contained in:
Leo Horie 2014-06-18 06:42:48 -04:00
parent bc50514731
commit 4aad8619c5
3 changed files with 35 additions and 18 deletions

View file

@ -10,6 +10,9 @@
- fix nested array removal edge cases [#120](https://github.com/lhorie/mithril.js/issues/120) - fix nested array removal edge cases [#120](https://github.com/lhorie/mithril.js/issues/120)
- ignore redraw calls when controller is not ready [#127](https://github.com/lhorie/mithril.js/issues/127) - ignore redraw calls when controller is not ready [#127](https://github.com/lhorie/mithril.js/issues/127)
- fix null reference exception in nested array edge case [#129](https://github.com/lhorie/mithril.js/issues/129) - fix null reference exception in nested array edge case [#129](https://github.com/lhorie/mithril.js/issues/129)
- fix a contenteditable null reference error [#134](https://github.com/lhorie/mithril.js/issues/134)
- fix textarea value diffing when value is a node inside an array [#136](https://github.com/lhorie/mithril.js/issues/136)
- fix diff bug with trusted strings [#138](https://github.com/lhorie/mithril.js/issues/138)
### Breaking changes: ### Breaking changes:

View file

@ -147,41 +147,40 @@ Mithril = m = new function app(window) {
} }
} }
else { else {
var node var nodes
if (cached.nodes.length === 0) { if (cached.nodes.length === 0) {
if (data.$trusted) { if (data.$trusted) {
node = injectHTML(parentElement, index, data) nodes = injectHTML(parentElement, index, data)
} }
else { else {
node = window.document.createTextNode(data) nodes = [window.document.createTextNode(data)]
parentElement.insertBefore(node, parentElement.childNodes[index] || null) parentElement.insertBefore(nodes[0], parentElement.childNodes[index] || null)
} }
cached = "string number boolean".indexOf(typeof data) > -1 ? new data.constructor(data) : data cached = "string number boolean".indexOf(typeof data) > -1 ? new data.constructor(data) : data
cached.nodes = [node] cached.nodes = nodes
} }
else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) { else if (cached.valueOf() !== data.valueOf() || shouldReattach === true) {
node = cached.nodes[0] nodes = cached.nodes
if (!editable || editable !== window.document.activeElement) { if (!editable || editable !== window.document.activeElement) {
if (data.$trusted) { if (data.$trusted) {
var current = cached.nodes[0], nodes = [current] clear(nodes)
if (current) { nodes = injectHTML(parentElement, index, data)
while (current = current.nextSibling) nodes.push(current)
clear(nodes)
node = injectHTML(parentElement, index, data)
}
else parentElement.innerHTML = data
} }
else { else {
if (parentTag === "textarea") parentElement.value = data if (parentTag === "textarea") parentElement.value = data
else if (editable) editable.innerHTML = data else if (editable) editable.innerHTML = data
else { else {
parentElement.insertBefore(node, parentElement.childNodes[index] || null) if (nodes[0].nodeType == 1 || nodes.length > 1) { //was a trusted string
node.nodeValue = data clear(cached.nodes)
nodes = [window.document.createTextNode(data)]
}
parentElement.insertBefore(nodes[0], parentElement.childNodes[index] || null)
nodes[0].nodeValue = data
} }
} }
} }
cached = new data.constructor(data) cached = new data.constructor(data)
cached.nodes = [node] cached.nodes = nodes
} }
else cached.nodes.intact = true else cached.nodes.intact = true
} }
@ -228,9 +227,23 @@ Mithril = m = new function app(window) {
} }
function injectHTML(parentElement, index, data) { function injectHTML(parentElement, index, data) {
var nextSibling = parentElement.childNodes[index] var nextSibling = parentElement.childNodes[index]
if (nextSibling) nextSibling.insertAdjacentHTML("beforebegin", data) if (nextSibling) {
var isElement = nextSibling.nodeType != 1
var placeholder = window.document.createElement("span")
if (isElement) {
parentElement.insertBefore(placeholder, nextSibling)
placeholder.insertAdjacentHTML("beforebegin", data)
parentElement.removeChild(placeholder)
}
else nextSibling.insertAdjacentHTML("beforebegin", data)
}
else parentElement.insertAdjacentHTML("beforeend", data) else parentElement.insertAdjacentHTML("beforeend", data)
return nextSibling ? nextSibling.previousSibling : parentElement.firstChild var nodes = []
while (parentElement.childNodes[index] !== nextSibling) {
nodes.push(parentElement.childNodes[index])
index++
}
return nodes
} }
function clone(object) { function clone(object) {
var result = {} var result = {}

View file

@ -7,6 +7,7 @@ mock.window = new function() {
return { return {
style: {}, style: {},
childNodes: [], childNodes: [],
nodeType: 1,
nodeName: tag.toUpperCase(), nodeName: tag.toUpperCase(),
appendChild: window.document.appendChild, appendChild: window.document.appendChild,
removeChild: window.document.removeChild, removeChild: window.document.removeChild,