From 438b836b524a69e59d7e82129414beabaea0ab92 Mon Sep 17 00:00:00 2001 From: cqh963852 Date: Mon, 21 Mar 2022 12:30:11 +0800 Subject: [PATCH] fix: change parent elm, if fragment --- src/init.ts | 8 +++++++- test/unit/core.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/init.ts b/src/init.ts index a53b4ea..8669aef 100644 --- a/src/init.ts +++ b/src/init.ts @@ -379,7 +379,13 @@ export function init( ) { const hook = vnode.data?.hook; hook?.prepatch?.(oldVnode, vnode); - const elm = (vnode.elm = oldVnode.elm)!; + const elm = ( + oldVnode.elm?.nodeType === oldVnode.elm?.DOCUMENT_FRAGMENT_NODE && + oldVnode.children?.length !== 0 + ? (oldVnode.children?.[0] as VNode).elm?.parentNode + : (vnode.elm = oldVnode.elm) + )!; + const oldCh = oldVnode.children as VNode[]; const ch = vnode.children as VNode[]; if (oldVnode === vnode) return; diff --git a/test/unit/core.ts b/test/unit/core.ts index cd7b5db..3f5de8f 100644 --- a/test/unit/core.ts +++ b/test/unit/core.ts @@ -1125,6 +1125,7 @@ describe("snabbdom", function () { assert.strictEqual(elm.nodeType, document.DOCUMENT_FRAGMENT_NODE); assert.strictEqual(elm.textContent, "fragment again"); }); + it("allows a document fragment as a container", function () { const vnode0 = document.createDocumentFragment(); const vnode1 = fragment(["I", "am", "a", h("span", ["fragment"])]); @@ -1136,6 +1137,33 @@ describe("snabbdom", function () { elm = patch(vnode1, vnode2).elm; assert.strictEqual(elm.tagName, "DIV"); }); + + it("update in fragment", function () { + const fnode1 = fragment([h("div")]); + const vnode1 = h("div", [fnode1]); + patch(vnode0, vnode1); + patch(fnode1, fragment([h("p", "1")])); + assert.strictEqual(fnode1.elm?.childNodes.length, 0); + assert.strictEqual(elm.children.length, 1); + }); + + it("insert to fragment", function () { + const fnode1 = fragment([h("p", "1")]); + const vnode1 = h("div", [fnode1]); + patch(vnode0, vnode1); + patch(fnode1, fragment([h("p", "1"), h("p", "2")])); + assert.strictEqual(fnode1.elm?.childNodes.length, 0); + assert.strictEqual(elm.children.length, 2); + }); + + it("remove in fragment", function () { + const fnode1 = fragment([h("p", "1")]); + const vnode1 = h("div", [fnode1]); + patch(vnode0, vnode1); + patch(fnode1, fragment([])); + assert.strictEqual(fnode1.elm?.childNodes.length, 0); + assert.strictEqual(elm.children.length, 0); + }); }); describe("hooks", function () { describe("element hooks", function () {