From c063d57f8878d38483973c19615d04aaf06dd77f Mon Sep 17 00:00:00 2001 From: iambumblehead Date: Thu, 18 Jan 2024 09:44:40 -0800 Subject: [PATCH] fix: allow innerHTML to replace non-empty node, credit @tokichie (#1083) Co-authored-by: chris --- src/init.ts | 4 +++- test/unit/core.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/init.ts b/src/init.ts index 418c480..20aa43d 100644 --- a/src/init.ts +++ b/src/init.ts @@ -138,7 +138,9 @@ export function init( return function rmCb() { if (--listeners === 0) { const parent = api.parentNode(childElm) as Node; - api.removeChild(parent, childElm); + if (parent !== null) { + api.removeChild(parent, childElm); + } } }; } diff --git a/test/unit/core.ts b/test/unit/core.ts index 3f6e8fe..ba49dde 100644 --- a/test/unit/core.ts +++ b/test/unit/core.ts @@ -334,6 +334,24 @@ describe("snabbdom", function () { assert(elm.classList.contains("am")); assert(!elm.classList.contains("horse")); }); + it("can replace non-empty node with innerHTML prop", function () { + const h2 = document.createElement("h2"); + h2.textContent = "Hello"; + const prevElm = document.createElement("div"); + prevElm.id = "id"; + prevElm.className = "class"; + prevElm.appendChild(h2); + const html = "Hi"; + const nextVNode = h("div#id.class", { props: { innerHTML: html } }); + elm = patch(toVNode(prevElm), nextVNode).elm; + assert.strictEqual(elm, prevElm); + assert.equal(elm.tagName, "DIV"); + assert.equal(elm.id, "id"); + assert.equal(elm.className, "class"); + assert.strictEqual(elm.childNodes.length, 1); + assert.strictEqual(elm.childNodes[0].tagName, "SPAN"); + assert.strictEqual(elm.childNodes[0].textContent, "Hi"); + }); it("changes an elements props", function () { const vnode1 = h("a", { props: { src: "http://other/" } }); const vnode2 = h("a", { props: { src: "http://localhost/" } });