diff --git a/.changeset/fifty-masks-give.md b/.changeset/fifty-masks-give.md new file mode 100644 index 000000000000..c555a7a34b09 --- /dev/null +++ b/.changeset/fifty-masks-give.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: run render functions for dynamic void elements diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js index bb660209e13b..1972ee4cb78b 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js @@ -40,7 +40,7 @@ function swap_block_dom(effect, from, to) { * @param {Comment} anchor * @param {() => string} get_tag * @param {boolean} is_svg - * @param {undefined | ((element: Element, anchor: Node) => void)} render_fn, + * @param {undefined | ((element: Element, anchor: Node | null) => void)} render_fn, * @param {undefined | (() => string)} get_namespace * @returns {void} */ @@ -115,13 +115,11 @@ export function element(anchor, get_tag, is_svg, render_fn, get_namespace) { ? element.firstChild && hydrate_anchor(/** @type {Comment} */ (element.firstChild)) : element.appendChild(empty()); - if (child_anchor) { - // `child_anchor` can be undefined if this is a void element with children, - // i.e. `...`. This is - // user error, but we warn on it elsewhere (in dev) so here we just - // silently ignore it - render_fn(element, child_anchor); - } + // `child_anchor` is undefined if this is a void element, but we still + // need to call `render_fn` in order to run actions etc. If the element + // contains children, it's a user error (which is warned on elsewhere) + // and the DOM will be silently discarded + render_fn(element, child_anchor); } anchor.before(element); diff --git a/packages/svelte/tests/runtime-runes/samples/action-void-element/_config.js b/packages/svelte/tests/runtime-runes/samples/action-void-element/_config.js new file mode 100644 index 000000000000..3ebd8d126a67 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/action-void-element/_config.js @@ -0,0 +1,11 @@ +import { test } from '../../test'; + +export default test({ + html: ``, + + async test({ assert, target }) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].value, 'set from action'); + assert.equal(inputs[1].value, 'set from action'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/action-void-element/main.svelte b/packages/svelte/tests/runtime-runes/samples/action-void-element/main.svelte new file mode 100644 index 000000000000..e9a833d6ac76 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/action-void-element/main.svelte @@ -0,0 +1,9 @@ + + + +