Skip to content

Commit 5850155

Browse files
committed
prevent to create element if value of this attribute is null / undefined / empty string.
1 parent b437985 commit 5850155

File tree

14 files changed

+77
-21
lines changed

14 files changed

+77
-21
lines changed

src/compiler/compile/render_dom/wrappers/Element/index.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -274,31 +274,36 @@ export default class ElementWrapper extends Wrapper {
274274
block.add_variable(previous_tag, snippet);
275275

276276
block.chunks.init.push(b`
277-
let ${this.var} = ${this.child_dynamic_element_block.name}(#ctx);
277+
let ${this.var} = ${snippet} && ${this.child_dynamic_element_block.name}(#ctx);
278278
`);
279279

280-
block.chunks.create.push(b`${this.var}.c();`);
280+
block.chunks.create.push(b`if (${this.var}) ${this.var}.c();`);
281281

282282
if (this.renderer.options.hydratable) {
283-
block.chunks.claim.push(b`${this.var}.l(${parent_nodes});`);
283+
block.chunks.claim.push(b`if (${this.var}) ${this.var}.l(${parent_nodes});`);
284284
}
285285

286286
block.chunks.mount.push(
287-
b`${this.var}.m(${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});`
287+
b`if (${this.var}) ${this.var}.m(${parent_node || '#target'}, ${parent_node ? 'null' : '#anchor'});`
288288
);
289289

290290
const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes);
291291
const not_equal = this.renderer.component.component_options.immutable ? x`@not_equal` : x`@safe_not_equal`;
292292
const if_statement = x`${not_equal}(${previous_tag}, ${previous_tag} = ${snippet})`;
293293

294294
block.chunks.update.unshift(b`
295-
${this.var}.p(#ctx, #dirty);
296-
if (${if_statement}) {
295+
if (${snippet}) {
296+
if (${this.var}) ${this.var}.p(#ctx, #dirty);
297+
if (${if_statement}) {
298+
if (${this.var}) ${this.var}.d(1);
299+
${this.var} = ${this.child_dynamic_element_block.name}(#ctx);
300+
${this.var}.c();
301+
@transition_in(${this.var});
302+
this.m(${this.get_update_mount_node(anchor)}, ${anchor});
303+
}
304+
} else if (${this.var}) {
297305
${this.var}.d(1);
298-
${this.var} = ${this.child_dynamic_element_block.name}(#ctx);
299-
${this.var}.c();
300-
@transition_in(${this.var});
301-
this.m(${this.get_update_mount_node(anchor)}, ${anchor});
306+
${this.var} = null;
302307
}
303308
`);
304309

@@ -310,7 +315,15 @@ export default class ElementWrapper extends Wrapper {
310315
block.chunks.outro.push(b`@transition_out(${this.var});`);
311316
}
312317

313-
block.chunks.destroy.push(b`${this.var}.d(detaching)`);
318+
block.chunks.destroy.push(b`if (${this.var}) ${this.var}.d(detaching)`);
319+
320+
if (this.renderer.options.dev) {
321+
block.chunks.create.push(b`@validate_dynamic_element(${snippet});`);
322+
if (this.renderer.options.hydratable) {
323+
block.chunks.claim.push(b`@validate_dynamic_element(${snippet});`);
324+
}
325+
block.chunks.update.push(b`@validate_dynamic_element(${snippet});`);
326+
}
314327
}
315328

316329
render_element(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
@@ -442,15 +455,6 @@ export default class ElementWrapper extends Wrapper {
442455
}
443456

444457
block.renderer.dirty(this.node.tag_expr.dynamic_dependencies());
445-
if (block.type === 'child_dynamic_element' && this.node.tag_expr.dependencies.size > 0) {
446-
const snippet = this.node.tag_expr.manipulate(block);
447-
if (this.renderer.options.dev) {
448-
block.chunks.create.push(b`@validate_dynamic_element(${snippet});`);
449-
if (renderer.options.hydratable) {
450-
block.chunks.claim.push(b`@validate_dynamic_element(${snippet});`);
451-
}
452-
}
453-
}
454458
}
455459

456460
can_use_textcontent() {

src/runtime/internal/dev.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export function validate_slots(name, slot, keys) {
108108
}
109109

110110
export function validate_dynamic_element(tag) {
111-
if (tag == null) {
111+
if (!tag) {
112112
console.warn('<svelte:element> expects a non-nullish value in attribute "this"');
113113
}
114114
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default {
2+
compileOptions: {
3+
dev: true
4+
},
5+
6+
warnings: [
7+
'<svelte:element> expects a non-nullish value in attribute "this"'
8+
]
9+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let tag = '';
3+
</script>
4+
5+
<svelte:element this={tag}></svelte:element>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default {
2+
compileOptions: {
3+
dev: true
4+
},
5+
6+
warnings: [
7+
'<svelte:element> expects a non-nullish value in attribute "this"'
8+
]
9+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let tag;
3+
</script>
4+
5+
<svelte:element this={tag}></svelte:element>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
html: ''
3+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let tag = '';
3+
</script>
4+
5+
<svelte:element this={tag}>Foo</svelte:element>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
html: ''
3+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let tag = null;
3+
</script>
4+
5+
<svelte:element this={tag}>Foo</svelte:element>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
html: ''
3+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let tag;
3+
</script>
4+
5+
<svelte:element this={tag}>Foo</svelte:element>

0 commit comments

Comments
 (0)