diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 7bfe95ac3e..ee8c95423e 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -274,17 +274,17 @@ export default class ElementWrapper extends Wrapper { block.add_variable(previous_tag, snippet); block.chunks.init.push(b` - let ${this.var} = ${this.child_dynamic_element_block.name}(#ctx); + let ${this.var} = ${snippet} && ${this.child_dynamic_element_block.name}(#ctx); `); - block.chunks.create.push(b`${this.var}.c();`); + block.chunks.create.push(b`if (${this.var}) ${this.var}.c();`); if (this.renderer.options.hydratable) { - block.chunks.claim.push(b`${this.var}.l(${parent_nodes});`); + block.chunks.claim.push(b`if (${this.var}) ${this.var}.l(${parent_nodes});`); } block.chunks.mount.push( - b`${this.var}.m(${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});` + b`if (${this.var}) ${this.var}.m(${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});` ); const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); @@ -292,13 +292,18 @@ export default class ElementWrapper extends Wrapper { const if_statement = x`${not_equal}(${previous_tag}, ${previous_tag} = ${snippet})`; block.chunks.update.unshift(b` - ${this.var}.p(#ctx, #dirty); - if (${if_statement}) { + if (${snippet}) { + if (${this.var}) ${this.var}.p(#ctx, #dirty); + if (${if_statement}) { + if (${this.var}) ${this.var}.d(1); + ${this.var} = ${this.child_dynamic_element_block.name}(#ctx); + ${this.var}.c(); + @transition_in(${this.var}); + this.m(${this.get_update_mount_node(anchor)}, ${anchor}); + } + } else if (${this.var}) { ${this.var}.d(1); - ${this.var} = ${this.child_dynamic_element_block.name}(#ctx); - ${this.var}.c(); - @transition_in(${this.var}); - this.m(${this.get_update_mount_node(anchor)}, ${anchor}); + ${this.var} = null; } `); @@ -310,7 +315,15 @@ export default class ElementWrapper extends Wrapper { block.chunks.outro.push(b`@transition_out(${this.var});`); } - block.chunks.destroy.push(b`${this.var}.d(detaching)`); + block.chunks.destroy.push(b`if (${this.var}) ${this.var}.d(detaching)`); + + if (this.renderer.options.dev) { + block.chunks.create.push(b`@validate_dynamic_element(${snippet});`); + if (this.renderer.options.hydratable) { + block.chunks.claim.push(b`@validate_dynamic_element(${snippet});`); + } + block.chunks.update.push(b`@validate_dynamic_element(${snippet});`); + } } render_element(block: Block, parent_node: Identifier, parent_nodes: Identifier) { @@ -442,15 +455,6 @@ export default class ElementWrapper extends Wrapper { } block.renderer.dirty(this.node.tag_expr.dynamic_dependencies()); - if (block.type === 'child_dynamic_element' && this.node.tag_expr.dependencies.size > 0) { - const snippet = this.node.tag_expr.manipulate(block); - if (this.renderer.options.dev) { - block.chunks.create.push(b`@validate_dynamic_element(${snippet});`); - if (renderer.options.hydratable) { - block.chunks.claim.push(b`@validate_dynamic_element(${snippet});`); - } - } - } } can_use_textcontent() { diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts index 5a459aefd7..ee40fb0456 100644 --- a/src/runtime/internal/dev.ts +++ b/src/runtime/internal/dev.ts @@ -108,7 +108,7 @@ export function validate_slots(name, slot, keys) { } export function validate_dynamic_element(tag) { - if (tag == null) { + if (!tag) { console.warn(' expects a non-nullish value in attribute "this"'); } } diff --git a/test/runtime/samples/dev-warning-dynamic-element-nullish-tag/_config.js b/test/runtime/samples/dev-warning-dynamic-element-empty-tag/_config.js similarity index 100% rename from test/runtime/samples/dev-warning-dynamic-element-nullish-tag/_config.js rename to test/runtime/samples/dev-warning-dynamic-element-empty-tag/_config.js diff --git a/test/runtime/samples/dev-warning-dynamic-element-nullish-tag/main.svelte b/test/runtime/samples/dev-warning-dynamic-element-empty-tag/main.svelte similarity index 100% rename from test/runtime/samples/dev-warning-dynamic-element-nullish-tag/main.svelte rename to test/runtime/samples/dev-warning-dynamic-element-empty-tag/main.svelte diff --git a/test/runtime/samples/dev-warning-dynamic-element-null-tag/_config.js b/test/runtime/samples/dev-warning-dynamic-element-null-tag/_config.js new file mode 100644 index 0000000000..a010e9365a --- /dev/null +++ b/test/runtime/samples/dev-warning-dynamic-element-null-tag/_config.js @@ -0,0 +1,9 @@ +export default { + compileOptions: { + dev: true + }, + + warnings: [ + ' expects a non-nullish value in attribute "this"' + ] +}; diff --git a/test/runtime/samples/dev-warning-dynamic-element-null-tag/main.svelte b/test/runtime/samples/dev-warning-dynamic-element-null-tag/main.svelte new file mode 100644 index 0000000000..e094a54fac --- /dev/null +++ b/test/runtime/samples/dev-warning-dynamic-element-null-tag/main.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/runtime/samples/dev-warning-dynamic-element-undefined-tag/_config.js b/test/runtime/samples/dev-warning-dynamic-element-undefined-tag/_config.js new file mode 100644 index 0000000000..a010e9365a --- /dev/null +++ b/test/runtime/samples/dev-warning-dynamic-element-undefined-tag/_config.js @@ -0,0 +1,9 @@ +export default { + compileOptions: { + dev: true + }, + + warnings: [ + ' expects a non-nullish value in attribute "this"' + ] +}; diff --git a/test/runtime/samples/dev-warning-dynamic-element-undefined-tag/main.svelte b/test/runtime/samples/dev-warning-dynamic-element-undefined-tag/main.svelte new file mode 100644 index 0000000000..6e5934d581 --- /dev/null +++ b/test/runtime/samples/dev-warning-dynamic-element-undefined-tag/main.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/runtime/samples/dynamic-element-empty-tag/_config.js b/test/runtime/samples/dynamic-element-empty-tag/_config.js new file mode 100644 index 0000000000..22dc25b41e --- /dev/null +++ b/test/runtime/samples/dynamic-element-empty-tag/_config.js @@ -0,0 +1,3 @@ +export default { + html: '' +}; diff --git a/test/runtime/samples/dynamic-element-empty-tag/main.svelte b/test/runtime/samples/dynamic-element-empty-tag/main.svelte new file mode 100644 index 0000000000..e3889ce0f5 --- /dev/null +++ b/test/runtime/samples/dynamic-element-empty-tag/main.svelte @@ -0,0 +1,5 @@ + + +Foo diff --git a/test/runtime/samples/dynamic-element-null-tag/_config.js b/test/runtime/samples/dynamic-element-null-tag/_config.js new file mode 100644 index 0000000000..22dc25b41e --- /dev/null +++ b/test/runtime/samples/dynamic-element-null-tag/_config.js @@ -0,0 +1,3 @@ +export default { + html: '' +}; diff --git a/test/runtime/samples/dynamic-element-null-tag/main.svelte b/test/runtime/samples/dynamic-element-null-tag/main.svelte new file mode 100644 index 0000000000..58dc96ff2a --- /dev/null +++ b/test/runtime/samples/dynamic-element-null-tag/main.svelte @@ -0,0 +1,5 @@ + + +Foo diff --git a/test/runtime/samples/dynamic-element-undefined-tag/_config.js b/test/runtime/samples/dynamic-element-undefined-tag/_config.js new file mode 100644 index 0000000000..22dc25b41e --- /dev/null +++ b/test/runtime/samples/dynamic-element-undefined-tag/_config.js @@ -0,0 +1,3 @@ +export default { + html: '' +}; diff --git a/test/runtime/samples/dynamic-element-undefined-tag/main.svelte b/test/runtime/samples/dynamic-element-undefined-tag/main.svelte new file mode 100644 index 0000000000..785ab58073 --- /dev/null +++ b/test/runtime/samples/dynamic-element-undefined-tag/main.svelte @@ -0,0 +1,5 @@ + + +Foo