diff --git a/src/compiler/compile/nodes/InlineComponent.ts b/src/compiler/compile/nodes/InlineComponent.ts index 8871c5f306..0b8c77049b 100644 --- a/src/compiler/compile/nodes/InlineComponent.ts +++ b/src/compiler/compile/nodes/InlineComponent.ts @@ -5,7 +5,6 @@ import Binding from './Binding'; import EventHandler from './EventHandler'; import Expression from './shared/Expression'; import Component from '../Component'; -import Let from './Let'; import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; import { TemplateNode } from '../../interfaces'; @@ -18,7 +17,6 @@ export default class InlineComponent extends Node { attributes: Attribute[] = []; bindings: Binding[] = []; handlers: EventHandler[] = []; - lets: Let[] = []; css_custom_properties: Attribute[] = []; children: INode[]; scope: TemplateScope; @@ -40,6 +38,7 @@ export default class InlineComponent extends Node { ? new Expression(component, this, scope, info.expression) : null; + const let_attributes = []; info.attributes.forEach(node => { /* eslint-disable no-fallthrough */ switch (node.type) { @@ -68,7 +67,7 @@ export default class InlineComponent extends Node { break; case 'Let': - this.lets.push(new Let(component, this, scope, node)); + let_attributes.push(node); break; case 'Transition': @@ -83,19 +82,7 @@ export default class InlineComponent extends Node { /* eslint-enable no-fallthrough */ }); - if (this.lets.length > 0) { - this.scope = scope.child(); - - this.lets.forEach(l => { - const dependencies = new Set([l.name.name]); - - l.names.forEach(name => { - this.scope.add(name, dependencies, this); - }); - }); - } else { - this.scope = scope; - } + this.scope = scope; this.handlers.forEach(handler => { handler.modifiers.forEach(modifier => { @@ -156,6 +143,24 @@ export default class InlineComponent extends Node { }); } + if (let_attributes.length) { + let warned = false; + // copy let: attribute from to + // as they are for `slot="default"` only + children.forEach(child => { + const slot = child.attributes.find(attribute => attribute.name === 'slot'); + if (!slot || slot.value[0].data === 'default') { + child.attributes.push(...let_attributes); + } else if (!warned) { + component.warn(info, { + code: 'let-on-component', + message: 'let: bindings on Component are meant for default slot template only, it is better to define them on instead.' + }); + warned = true; + } + }); + } + this.children = map_children(component, this, this.scope, children); } diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 37aaf2e7b2..4f25548353 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -14,7 +14,6 @@ import is_dynamic from '../shared/is_dynamic'; import bind_this from '../shared/bind_this'; import { Node, Identifier, ObjectExpression } from 'estree'; import EventHandler from '../Element/EventHandler'; -import { extract_names } from 'periscopic'; import mark_each_block_bindings from '../shared/mark_each_block_bindings'; import { string_to_member_expression } from '../../../utils/string_to_member_expression'; import SlotTemplate from '../../../nodes/SlotTemplate'; @@ -80,12 +79,6 @@ export default class InlineComponentWrapper extends Wrapper { }; if (this.node.children.length) { - this.node.lets.forEach(l => { - extract_names(l.value || l.name).forEach(name => { - renderer.add_to_context(name, true); - }); - }); - this.children = this.node.children.map(child => new SlotTemplateWrapper(renderer, block, this, child as SlotTemplate, strip_whitespace, next_sibling)); } diff --git a/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts b/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts index a50f74fc04..1e040f0c51 100644 --- a/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts +++ b/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts @@ -47,11 +47,6 @@ export default class SlotTemplateWrapper extends Wrapper { }); this.renderer.blocks.push(this.block); - const seen = new Set(lets.map(l => l.name.name)); - this.parent.node.lets.forEach(l => { - if (!seen.has(l.name.name)) lets.push(l); - }); - this.parent.set_slot( slot_template_name, get_slot_definition(this.block, scope, lets) diff --git a/src/compiler/compile/render_ssr/handlers/SlotTemplate.ts b/src/compiler/compile/render_ssr/handlers/SlotTemplate.ts index 09f3293301..7d63fa27fd 100644 --- a/src/compiler/compile/render_ssr/handlers/SlotTemplate.ts +++ b/src/compiler/compile/render_ssr/handlers/SlotTemplate.ts @@ -14,12 +14,6 @@ export default function(node: SlotTemplate, renderer: Renderer, options: RenderO renderer.push(); renderer.render(children, options); - const lets = node.lets; - const seen = new Set(lets.map(l => l.name.name)); - parent_inline_component.lets.forEach(l => { - if (!seen.has(l.name.name)) lets.push(l); - }); - const slot_fragment_content = renderer.pop(); if (!is_empty_template_literal(slot_fragment_content)) { if (options.slot_scopes.has(node.slot_template_name)) { diff --git a/test/runtime/samples/component-slot-named-inherits-default-lets/_config.js b/test/runtime/samples/component-slot-named-inherits-default-lets/_config.js index dbfa8270af..80a67bfae1 100644 --- a/test/runtime/samples/component-slot-named-inherits-default-lets/_config.js +++ b/test/runtime/samples/component-slot-named-inherits-default-lets/_config.js @@ -3,7 +3,7 @@ export default {

count in default slot: 0

count in foo slot: 0

-

count in bar slot: undefined

+

count in bar slot: 42

`, @@ -17,7 +17,7 @@ export default {

count in default slot: 1

count in foo slot: 1

-

count in bar slot: undefined

+

count in bar slot: 42

`); diff --git a/test/runtime/samples/component-slot-named-inherits-default-lets/main.svelte b/test/runtime/samples/component-slot-named-inherits-default-lets/main.svelte index 51dd28b855..5e7d3def54 100644 --- a/test/runtime/samples/component-slot-named-inherits-default-lets/main.svelte +++ b/test/runtime/samples/component-slot-named-inherits-default-lets/main.svelte @@ -1,5 +1,6 @@ diff --git a/test/validator/samples/lets-on-component/input.svelte b/test/validator/samples/lets-on-component/input.svelte new file mode 100644 index 0000000000..b72ee8c074 --- /dev/null +++ b/test/validator/samples/lets-on-component/input.svelte @@ -0,0 +1,27 @@ + + + +

+ count in default slot: {count} +

+

+ count in bar slot: {count} +

+
+ + +

+ count in default slot: {count} +

+

+ count in bar slot: {count} +

+
+ + +

+ count in bar slot: {count} +

+
diff --git a/test/validator/samples/lets-on-component/warnings.json b/test/validator/samples/lets-on-component/warnings.json new file mode 100644 index 0000000000..54debf49c6 --- /dev/null +++ b/test/validator/samples/lets-on-component/warnings.json @@ -0,0 +1,62 @@ +[ + { + "code": "let-on-component", + "message": "let: bindings on Component are meant for default slot template only, it is better to define them on instead.", + "pos": 59, + "start": { + "character": 59, + "column": 0, + "line": 5 + }, + "end": { + "character": 182, + "column": 9, + "line": 12 + } + }, + { + "code": "missing-declaration", + "message": "'count' is not defined", + "pos": 160, + "start": { + "character": 160, + "column": 22, + "line": 10 + }, + "end": { + "character": 165, + "column": 27, + "line": 10 + } + }, + { + "code": "let-on-component", + "message": "let: bindings on Component are meant for default slot template only, it is better to define them on instead.", + "pos": 298, + "start": { + "character": 298, + "column": 0, + "line": 23 + }, + "end": { + "character": 377, + "column": 9, + "line": 27 + } + }, + { + "code": "missing-declaration", + "message": "'count' is not defined", + "pos": 355, + "start": { + "character": 355, + "column": 22, + "line": 25 + }, + "end": { + "character": 360, + "column": 27, + "line": 25 + } + } +]