diff --git a/src/plugins/fragment/index.js b/src/plugins/fragment/index.js index d6f44e0..3c52991 100644 --- a/src/plugins/fragment/index.js +++ b/src/plugins/fragment/index.js @@ -1,14 +1,14 @@ import { anchor_block } from "@/utilities/anchor_block"; import { is_template, warn } from "@/utilities/utils"; -function plugin({ addScopeToNode, directive, initTree, mutateDom }) { +function plugin({ addScopeToNode, directive, destroyTree, initTree, mutateDom }) { directive("fragment", (el, {}, { cleanup }) => { if (!is_template(el)) { warn("x-fragment can only be used on a 'template' tag"); return; } - anchor_block(el, el, { addScopeToNode, cleanup, initTree, mutateDom }); + anchor_block(el, el, { addScopeToNode, cleanup, destroyTree, initTree, mutateDom }); }); } diff --git a/src/plugins/match/index.js b/src/plugins/match/index.js index 16dc92e..43af1bf 100644 --- a/src/plugins/match/index.js +++ b/src/plugins/match/index.js @@ -2,7 +2,7 @@ import { anchor_block } from "@/utilities/anchor_block"; import { create_getter } from "@/utilities/evaluator"; import { is_template, warn } from "@/utilities/utils"; -function plugin({ addScopeToNode, directive, initTree, mutateDom }) { +function plugin({ addScopeToNode, directive, destroyTree, initTree, mutateDom }) { directive("match", (el, { }, { cleanup, effect, evaluateLater }) => { if (!is_template(el)) { warn("x-match can only be used on a 'template' tag"); @@ -33,6 +33,7 @@ function plugin({ addScopeToNode, directive, initTree, mutateDom }) { anchor_block(el, branch.el, { addScopeToNode, cleanup, + destroyTree, initTree, mutateDom }); diff --git a/src/plugins/when/index.js b/src/plugins/when/index.js index f02f7a2..85dd890 100644 --- a/src/plugins/when/index.js +++ b/src/plugins/when/index.js @@ -2,14 +2,14 @@ import { anchor_block } from "@/utilities/anchor_block"; import { create_getter } from "@/utilities/evaluator"; import { is_template, warn } from "@/utilities/utils"; -function plugin({ addScopeToNode, directive, initTree, mutateDom }) { +function plugin({ addScopeToNode, directive, destroyTree, initTree, mutateDom }) { directive("when", (el, { expression }, { cleanup, effect, evaluateLater }) => { if (!is_template(el)) { warn("x-when can only be used on a 'template' tag"); return; } - const activate = () => anchor_block(el, el, { addScopeToNode, cleanup, initTree, mutateDom }); + const activate = () => anchor_block(el, el, { addScopeToNode, cleanup, destroyTree, initTree, mutateDom }); const clear = () => el._r_block?.delete(); const get = create_getter(evaluateLater, expression); diff --git a/src/utilities/anchor_block.js b/src/utilities/anchor_block.js index 493c0a8..a194a7b 100644 --- a/src/utilities/anchor_block.js +++ b/src/utilities/anchor_block.js @@ -1,6 +1,6 @@ import { is_element, is_template } from "@/utilities/utils"; -export function anchor_block(el, template, { addScopeToNode, cleanup, initTree, mutateDom, scope = {} }) { +export function anchor_block(el, template, { addScopeToNode, cleanup, destroyTree, initTree, mutateDom, scope = {} }) { if (el._r_block) { return; } @@ -30,9 +30,12 @@ export function anchor_block(el, template, { addScopeToNode, cleanup, initTree, }, delete() { el._r_block = null; - for (let node of nodes ?? []) { - node.remove(); - } + mutateDom(() => { + for (let node of nodes ?? []) { + is_element(node) && destroyTree(node); + node.remove(); + } + }); nodes = null; } } diff --git a/tests/playwright/anchor-block.spec.js b/tests/playwright/anchor-block.spec.js new file mode 100644 index 0000000..28d5f88 --- /dev/null +++ b/tests/playwright/anchor-block.spec.js @@ -0,0 +1,80 @@ +import { expect, test } from "@playwright/test"; +import { set_html } from "./assets/utils"; + +for (const directive of ["fragment", "when", "match"]) { + test(`anchor block: nested cleanup (${directive})`, async ({ page }) => { + const errors = []; + page.on("pageerror", e => errors.push(e.message)); + + const content = ` + Before +