diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 80939ecf53..d0028d1dd6 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -121,6 +121,7 @@ export default class ElementWrapper extends Wrapper { select_binding_dependencies?: Set; var: any; + void: boolean; constructor( renderer: Renderer, @@ -136,6 +137,8 @@ export default class ElementWrapper extends Wrapper { name: node.name.replace(/[^a-zA-Z0-9_$]/g, '_') }; + this.void = is_void(node.name); + this.class_dependencies = []; this.attributes = this.node.attributes.map(attribute => { @@ -258,6 +261,7 @@ export default class ElementWrapper extends Wrapper { const node = this.var; const nodes = parent_nodes && block.get_unique_name(`${this.var.name}_nodes`); // if we're in unclaimable territory, i.e. , parent_nodes is null + const children = x`@children(${this.node.name === 'template' ? x`${node}.content` : node})`; block.add_variable(node); const render_statement = this.get_render_statement(); @@ -269,8 +273,13 @@ export default class ElementWrapper extends Wrapper { if (parent_nodes) { block.chunks.claim.push(b` ${node} = ${this.get_claim_statement(parent_nodes)}; - var ${nodes} = @children(${this.node.name === 'template' ? x`${node}.content` : node}); `); + + if (!this.void && this.node.children.length > 0) { + block.chunks.claim.push(b` + var ${nodes} = ${children}; + `); + } } else { block.chunks.claim.push( b`${node} = ${render_statement};` @@ -351,9 +360,9 @@ export default class ElementWrapper extends Wrapper { this.add_classes(block); this.add_manual_style_scoping(block); - if (nodes && this.renderer.options.hydratable) { + if (nodes && this.renderer.options.hydratable && !this.void) { block.chunks.claim.push( - b`${nodes}.forEach(@detach);` + b`${this.node.children.length > 0 ? nodes : children}.forEach(@detach);` ); } @@ -915,7 +924,7 @@ function to_html(wrappers: Array, blo state.quasi.value.raw += '>'; - if (!is_void(wrapper.node.name)) { + if (!(wrapper as ElementWrapper).void) { to_html((wrapper as ElementWrapper).fragment.nodes as Array, block, literal, state); state.quasi.value.raw += ``; diff --git a/test/js/samples/hydrated-void-element/_config.js b/test/js/samples/hydrated-void-element/_config.js new file mode 100644 index 0000000000..84c0d733ef --- /dev/null +++ b/test/js/samples/hydrated-void-element/_config.js @@ -0,0 +1,5 @@ +export default { + options: { + hydratable: true + } +}; \ No newline at end of file diff --git a/test/js/samples/hydrated-void-element/expected.js b/test/js/samples/hydrated-void-element/expected.js new file mode 100644 index 0000000000..992b90dd14 --- /dev/null +++ b/test/js/samples/hydrated-void-element/expected.js @@ -0,0 +1,63 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + attr, + children, + claim_element, + claim_space, + detach, + element, + init, + insert, + noop, + safe_not_equal, + space +} from "svelte/internal"; + +function create_fragment(ctx) { + let img; + let t; + let div; + + return { + c() { + img = element("img"); + t = space(); + div = element("div"); + this.h(); + }, + l(nodes) { + img = claim_element(nodes, "IMG", { src: true, alt: true }); + t = claim_space(nodes); + div = claim_element(nodes, "DIV", {}); + children(div).forEach(detach); + this.h(); + }, + h() { + attr(img, "src", "donuts.jpg"); + attr(img, "alt", "donuts"); + }, + m(target, anchor) { + insert(target, img, anchor); + insert(target, t, anchor); + insert(target, div, anchor); + }, + p: noop, + i: noop, + o: noop, + d(detaching) { + if (detaching) detach(img); + if (detaching) detach(t); + if (detaching) detach(div); + } + }; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, null, create_fragment, safe_not_equal, {}); + } +} + +export default Component; \ No newline at end of file diff --git a/test/js/samples/hydrated-void-element/input.svelte b/test/js/samples/hydrated-void-element/input.svelte new file mode 100644 index 0000000000..d70b3eaf12 --- /dev/null +++ b/test/js/samples/hydrated-void-element/input.svelte @@ -0,0 +1,2 @@ +donuts +
\ No newline at end of file