Skip to content

Commit

Permalink
Skip default slot if it contains only spaces (sveltejs#4546)
Browse files Browse the repository at this point in the history
  • Loading branch information
j3rem1e committed Oct 31, 2020
1 parent 148b610 commit 1cbbcfe
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/compiler/compile/render_dom/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,10 @@ export default class Block {
this.has_animation;
}

has_only_spaces(): boolean {
return this.wrappers.every(w => w.has_only_spaces());
}

render() {
const key = this.key && this.get_unique_name('key');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ export default class InlineComponentWrapper extends Wrapper {

// removing empty slot
for (const slot of this.slots.keys()) {
if (!this.slots.get(slot).block.has_content()) {
const bl = this.slots.get(slot).block;

if (!bl.has_content() || (slot === 'default' && bl.has_only_spaces())) {
this.renderer.remove_block(this.slots.get(slot).block);
this.slots.delete(slot);
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/compile/render_dom/wrappers/Text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export default class TextWrapper extends Wrapper {
return true;
}

has_only_spaces() {
return !/\S/.test(this.data);
}

render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
if (this.skip) return;
const use_space = this.use_space();
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/compile/render_dom/wrappers/shared/Wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export default class Wrapper {
);
}

has_only_spaces() {
return false;
}

render(_block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
throw Error('Wrapper class is not renderable');
}
Expand Down
12 changes: 10 additions & 2 deletions src/compiler/compile/render_ssr/handlers/InlineComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { get_slot_scope } from './shared/get_slot_scope';
import InlineComponent from '../../nodes/InlineComponent';
import remove_whitespace_children from './utils/remove_whitespace_children';
import { p, x } from 'code-red';
import { TemplateLiteral } from 'estree';


function get_prop_value(attribute) {
if (attribute.is_true) return x`true`;
Expand Down Expand Up @@ -85,7 +87,7 @@ export default function(node: InlineComponent, renderer: Renderer, options: Rend
});

slot_scopes.forEach(({ input, output }, name) => {
if (!is_empty_template_literal(output)) {
if (!is_empty_template_literal(output) && (name !== 'default' || !has_only_spaces(output))) {
slot_fns.push(
p`${name}: (${input}) => ${output}`
);
Expand All @@ -100,10 +102,16 @@ export default function(node: InlineComponent, renderer: Renderer, options: Rend
renderer.add_expression(x`@validate_component(${expression}, "${node.name}").$$render($$result, ${props}, ${bindings}, ${slots})`);
}

function is_empty_template_literal(template_literal) {
function is_empty_template_literal(template_literal: TemplateLiteral) {
return (
template_literal.expressions.length === 0 &&
template_literal.quasis.length === 1 &&
template_literal.quasis[0].value.raw === ''
);
}

function has_only_spaces(template_literal: TemplateLiteral): boolean {
return template_literal.expressions.length === 0 &&
template_literal.quasis.length === 1 &&
!/\S/.test(template_literal.quasis[0].value.raw);
}
1 change: 1 addition & 0 deletions test/runtime/samples/component-slot-warning/main.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
<Nested>
<input slot="slot1">
<input slot="slot2">
unexpected_default
</Nested>
7 changes: 7 additions & 0 deletions test/runtime/samples/slot-spaces-only/Component.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
</script>

<slot name='slotA'/>
<slot name='slotB'/>
<slot>default value</slot>
7 changes: 7 additions & 0 deletions test/runtime/samples/slot-spaces-only/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default {
html: `
<div slot='slotA'>A</div>
<div slot='slotB'>B</div>
default value
`
};
12 changes: 12 additions & 0 deletions test/runtime/samples/slot-spaces-only/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import Component from './Component.svelte';
</script>

<Component>


<div slot='slotA'>A</div>
<div slot='slotB'>B</div>


</Component>

1 comment on commit 1cbbcfe

@jakobrosenberg
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would this commit handle

<Cmp>
  {#if false}
    nothing
  {/if}
</Cmp>

Would a warning still be produced?

Please sign in to comment.