diff --git a/docs/change-log.md b/docs/change-log.md
index 3d5d786e..3577ea6d 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -17,7 +17,8 @@
### Upcoming...
-- Fix `ospec require` with relative paths
+- Fix double-rendering of trusted content within `contenteditable` elements ([#2516](https://github.com/MithrilJS/mithril.js/pull/2516) [@isiahmeadows](https://github.com/isiahmeadows))
+- Fix error on `m.trust` updating ([#2516](https://github.com/MithrilJS/mithril.js/pull/2516) [@isiahmeadows](https://github.com/isiahmeadows))
-->
diff --git a/ospec/change-log.md b/ospec/change-log.md
index 943f02f8..63e1b7c8 100644
--- a/ospec/change-log.md
+++ b/ospec/change-log.md
@@ -12,6 +12,7 @@
- [1.3 and earlier](#13-and-earlier)
### Upcoming...
+- Fix `require` with relative paths
### 4.0.0
- Pull ESM support out
diff --git a/render/render.js b/render/render.js
index 5d93c41e..d7de912d 100644
--- a/render/render.js
+++ b/render/render.js
@@ -434,7 +434,11 @@ module.exports = function($window) {
removeHTML(parent, old)
createHTML(parent, vnode, ns, nextSibling)
}
- else vnode.dom = old.dom, vnode.domSize = old.domSize
+ else {
+ vnode.dom = old.dom
+ vnode.domSize = old.domSize
+ vnode.instance = old.instance
+ }
}
function updateFragment(parent, old, vnode, hooks, nextSibling, ns) {
updateNodes(parent, old.children, vnode.children, hooks, nextSibling, ns)
@@ -608,13 +612,14 @@ module.exports = function($window) {
if (vnode.attrs == null || (
vnode.attrs.contenteditable == null && // attribute
vnode.attrs.contentEditable == null // property
- )) return
+ )) return false
var children = vnode.children
if (children != null && children.length === 1 && children[0].tag === "<") {
var content = children[0].children
if (vnode.dom.innerHTML !== content) vnode.dom.innerHTML = content
}
else if (vnode.text != null || children != null && children.length !== 0) throw new Error("Child node of a contenteditable must be trusted")
+ return true
}
//remove
diff --git a/render/tests/test-createHTML.js b/render/tests/test-createHTML.js
index bf3055b2..291f8f04 100644
--- a/render/tests/test-createHTML.js
+++ b/render/tests/test-createHTML.js
@@ -81,4 +81,14 @@ o.spec("createHTML", function() {
o(vnode.dom.nextSibling.nodeName).equals("text")
o(vnode.dom.nextSibling.namespaceURI).equals("http://www.w3.org/2000/svg")
})
+ o("creates the dom correctly with a contenteditable parent", function() {
+ var div = {tag: "div", attrs: {contenteditable: true}, children: [{tag: "<", children: ""}]}
+
+ render(root, div)
+ var tags = []
+ for (var i = 0; i < div.dom.childNodes.length; i++) {
+ tags.push(div.dom.childNodes[i].nodeName)
+ }
+ o(tags).deepEquals(["A"])
+ })
})
diff --git a/render/tests/test-updateHTML.js b/render/tests/test-updateHTML.js
index 294456e9..b95fc9b1 100644
--- a/render/tests/test-updateHTML.js
+++ b/render/tests/test-updateHTML.js
@@ -47,4 +47,68 @@ o.spec("updateHTML", function() {
o(updated.domSize).equals(0)
o(root.childNodes.length).equals(0)
})
+ function childKeysOf(elem, key) {
+ var keys = key.split(".")
+ var result = []
+ for (var i = 0; i < elem.childNodes.length; i++) {
+ var child = elem.childNodes[i]
+ for (var j = 0; j < keys.length; j++) child = child[keys[j]]
+ result.push(child)
+ }
+ return result
+ }
+ o("updates the dom correctly with a contenteditable parent", function() {
+ var div = {tag: "div", attrs: {contenteditable: true}, children: [{tag: "<", children: ""}]}
+
+ render(root, div)
+ o(childKeysOf(div.dom, "nodeName")).deepEquals(["A"])
+ })
+ o("updates dom with multiple text children", function() {
+ var vnode = [{tag: "#", children: "a"}, {tag: "<", children: ""}, {tag: "<", children: ""}]
+ var replacement = [{tag: "#", children: "a"}, {tag: "<", children: ""}, {tag: "<", children: ""}]
+
+ render(root, vnode)
+ render(root, replacement)
+
+ o(childKeysOf(root, "nodeName")).deepEquals(["#text", "C", "D"])
+ })
+ o("updates dom with multiple text children in other parents", function() {
+ var vnode = [
+ {tag: "div", attrs: {}, children: [{tag: "#", children: "a"}, {tag: "<", children: ""}]},
+ {tag: "div", attrs: {}, children: [{tag: "#", children: "b"}, {tag: "<", children: ""}]},
+ ]
+ var replacement = [
+ {tag: "div", attrs: {}, children: [{tag: "#", children: "c"}, {tag: "<", children: ""}]},
+ {tag: "div", attrs: {}, children: [{tag: "#", children: "d"}, {tag: "<", children: ""}]},
+ ]
+
+ render(root, vnode)
+ render(root, replacement)
+
+ o(childKeysOf(root, "nodeName")).deepEquals(["DIV", "DIV"])
+ o(childKeysOf(root.childNodes[0], "nodeName")).deepEquals(["#text", "C"])
+ o(root.childNodes[0].firstChild.nodeValue).equals("c")
+ o(childKeysOf(root.childNodes[1], "nodeName")).deepEquals(["#text", "D"])
+ o(root.childNodes[1].firstChild.nodeValue).equals("d")
+ })
+ o("correctly diffs if followed by another trusted vnode", function() {
+ render(root, [
+ {tag: "<", children: "A"},
+ {tag: "<", children: "A"},
+ ])
+ o(childKeysOf(root, "nodeName")).deepEquals(["SPAN", "SPAN"])
+ o(childKeysOf(root, "firstChild.nodeValue")).deepEquals(["A", "A"])
+ render(root, [
+ {tag: "<", children: "B"},
+ {tag: "<", children: "A"},
+ ])
+ o(childKeysOf(root, "nodeName")).deepEquals(["SPAN", "SPAN"])
+ o(childKeysOf(root, "firstChild.nodeValue")).deepEquals(["B", "A"])
+ render(root, [
+ {tag: "<", children: "B"},
+ {tag: "<", children: "B"},
+ ])
+ o(childKeysOf(root, "nodeName")).deepEquals(["SPAN", "SPAN"])
+ o(childKeysOf(root, "firstChild.nodeValue")).deepEquals(["B", "B"])
+ })
})