From 30ad45caa1bce92f9f67436d7a8960cbef01312f Mon Sep 17 00:00:00 2001 From: Isiah Meadows Date: Sat, 17 Aug 2019 14:38:10 -0400 Subject: [PATCH] Unbreak `m.trust` (#2516) * Actually return the check from `maybeSetContentEditable` Lots of code paths relied on it being a boolean. When I created the abstraction, I apparently forgot to make sure it returned the result. * Don't forget to copy instance state over * Update changelog [skip ci] * Fix changelog issue [skip ci] --- docs/change-log.md | 3 +- ospec/change-log.md | 1 + render/render.js | 9 +++-- render/tests/test-createHTML.js | 10 ++++++ render/tests/test-updateHTML.js | 64 +++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 3 deletions(-) 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"]) + }) })