diff --git a/src/compiler/compile/nodes/ConstTag.ts b/src/compiler/compile/nodes/ConstTag.ts
index 44a50aa005..4c6a040f88 100644
--- a/src/compiler/compile/nodes/ConstTag.ts
+++ b/src/compiler/compile/nodes/ConstTag.ts
@@ -12,7 +12,7 @@ import get_object from '../utils/get_object';
import compiler_errors from '../compiler_errors';
import { Node as ESTreeNode } from 'estree';
-const allowed_parents = new Set(['EachBlock', 'CatchBlock', 'ThenBlock', 'InlineComponent', 'SlotTemplate', 'IfBlock', 'ElseBlock']);
+const allowed_parents = new Set(['EachBlock', 'CatchBlock', 'ThenBlock', 'InlineComponent', 'SlotTemplate', 'IfBlock', 'ElseBlock', 'SlotTemplateIfBlock', 'SlotTemplateElseBlock']);
export default class ConstTag extends Node {
type: 'ConstTag';
diff --git a/src/compiler/compile/nodes/InlineComponent.ts b/src/compiler/compile/nodes/InlineComponent.ts
index 41ffce83ec..2f39b6faff 100644
--- a/src/compiler/compile/nodes/InlineComponent.ts
+++ b/src/compiler/compile/nodes/InlineComponent.ts
@@ -12,6 +12,7 @@ import { TemplateNode } from '../../interfaces';
import compiler_errors from '../compiler_errors';
import { regex_only_whitespaces } from '../../utils/patterns';
import { validate_get_slot_names } from './SlotTemplateIfBlock';
+import { BaseNode } from 'estree-walker';
export default class InlineComponent extends Node {
type: 'InlineComponent';
@@ -147,7 +148,7 @@ export default class InlineComponent extends Node {
} else if (child.type === 'Comment' && children.length > 0) {
children[children.length - 1].children.unshift(child);
info.children.splice(i, 1);
- } else if (child.type === 'IfBlock' && child.children.some(if_child => if_child.type === 'SlotTemplate')) {
+ } else if (child.type === 'IfBlock' && if_block_contains_slot_template(child)) {
children.push({
...child,
type: 'SlotTemplateIfBlock'
@@ -193,3 +194,11 @@ function get_namespace(parent: Node, explicit_namespace: string) {
return parent_element.namespace;
}
+
+function if_block_contains_slot_template(node: TemplateNode) {
+ for (const child of node.children) {
+ if (child.type === 'SlotTemplate') return true;
+ if (child.type === 'IfBlock' && if_block_contains_slot_template(child)) return true;
+ }
+ return false;
+}
\ No newline at end of file
diff --git a/src/compiler/compile/nodes/SlotTemplate.ts b/src/compiler/compile/nodes/SlotTemplate.ts
index 7b28afb47d..2dd024da78 100644
--- a/src/compiler/compile/nodes/SlotTemplate.ts
+++ b/src/compiler/compile/nodes/SlotTemplate.ts
@@ -69,6 +69,7 @@ export default class SlotTemplate extends Node {
let parent = this.parent;
while (parent.type === 'SlotTemplateIfBlock' || parent.type === 'SlotTemplateElseBlock') parent = parent.parent;
if (parent.type === 'IfBlock' || parent.type === 'ElseBlock') {
+ console.log({ parent });
return this.component.error(this, compiler_errors.invalid_mix_element_and_conditional_slot);
}
if (parent.type !== 'InlineComponent') {
diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts
index caaf0ac7d3..0522721359 100644
--- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts
+++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts
@@ -173,7 +173,7 @@ export default class InlineComponentWrapper extends Wrapper {
: this.children.length > 0
? [
p`$$slots: {
- ${this.children.map((slot: SlotTemplateWrapper) => p`${slot.slot_template_name}: ${slot.slot_definition}`)}
+ ${this.children.filter((slot: SlotTemplateWrapper) => slot.slot_definition).map((slot: SlotTemplateWrapper) => p`${slot.slot_template_name}: ${slot.slot_definition}`)}
}`,
p`$$scope: { ctx: #ctx }`
]
diff --git a/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts b/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts
index dd832f0f42..4f59ca34d4 100644
--- a/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts
+++ b/src/compiler/compile/render_dom/wrappers/SlotTemplate.ts
@@ -13,6 +13,7 @@ import SlotTemplate from '../../nodes/SlotTemplate';
import { add_const_tags, add_const_tags_context } from './shared/add_const_tags';
import TemplateScope from '../../nodes/shared/TemplateScope';
import SlotTemplateIfBlockWrapper from './SlotTemplateIfBlock';
+import { INode } from '../../nodes/interfaces';
export default class SlotTemplateWrapper extends Wrapper {
node: SlotTemplate;
@@ -83,7 +84,7 @@ export default class SlotTemplateWrapper extends Wrapper {
this.render_get_context();
}
- if (!this.block.has_content()) {
+ if (this.slot_template_name === 'default' && !this.block.has_content()) {
this.renderer.remove_block(this.block);
this.slot_definition = null;
}
@@ -100,10 +101,23 @@ export default class SlotTemplateWrapper extends Wrapper {
}
render_get_context() {
+ const if_const_tags = [];
+ let parent = this.node.parent;
+ while (parent.type === 'SlotTemplateIfBlock' || parent.type === 'SlotTemplateElseBlock') {
+ if_const_tags.push(parent.const_tags);
+ if (parent.type === 'SlotTemplateElseBlock') parent = parent.parent;
+ parent = parent.parent;
+ }
+ const const_tags = [];
+ for (let i = if_const_tags.length - 1; i >= 0; i--) {
+ const_tags.push(...if_const_tags[i]);
+ }
+ const_tags.push(...this.node.const_tags);
+
const get_context = this.block.renderer.component.get_unique_name('get_context');
this.block.renderer.blocks.push(b`
function ${get_context}(#ctx) {
- ${add_const_tags(this.block, this.node.const_tags, '#ctx')}
+ ${add_const_tags(this.block, const_tags, '#ctx')}
}
`);
this.block.chunks.declarations.push(b`${get_context}(#ctx)`);
diff --git a/src/compiler/compile/render_dom/wrappers/SlotTemplateIfBlock.ts b/src/compiler/compile/render_dom/wrappers/SlotTemplateIfBlock.ts
index 7f0cb129ee..8acb61df04 100644
--- a/src/compiler/compile/render_dom/wrappers/SlotTemplateIfBlock.ts
+++ b/src/compiler/compile/render_dom/wrappers/SlotTemplateIfBlock.ts
@@ -5,9 +5,10 @@ import { Identifier } from 'estree';
import SlotTemplateIfBlock from '../../nodes/SlotTemplateIfBlock';
import SlotTemplateWrapper from './SlotTemplate';
import SlotTemplate from '../../nodes/SlotTemplate';
-import { b } from 'code-red';
+import { x, b } from 'code-red';
import InlineComponentWrapper from './InlineComponent';
import TemplateScope from '../../nodes/shared/TemplateScope';
+import { add_const_tags, add_const_tags_context } from './shared/add_const_tags';
export default class SlotTemplateIfBlockWrapper extends Wrapper {
node: SlotTemplateIfBlock;
@@ -30,6 +31,8 @@ export default class SlotTemplateIfBlockWrapper extends Wrapper {
super(renderer, block, parent, node);
this.scope = node.scope;
+ add_const_tags_context(renderer, this.node.const_tags);
+
for (const child of this.node.children) {
if (child.type === 'SlotTemplate') {
this.children.push(new SlotTemplateWrapper(renderer, block, this, child as SlotTemplate, strip_whitespace, next_sibling));
@@ -39,6 +42,7 @@ export default class SlotTemplateIfBlockWrapper extends Wrapper {
}
if (node.else) {
+ add_const_tags_context(renderer, this.node.else.const_tags);
for (const child of node.else.children) {
if (child.type === 'SlotTemplate') {
this.else.push(new SlotTemplateWrapper(renderer, block, this, child as SlotTemplate, strip_whitespace, next_sibling));
@@ -55,11 +59,33 @@ export default class SlotTemplateIfBlockWrapper extends Wrapper {
}
render_slot_template_definition(block: Block) {
+ let if_get_context;
+ let else_get_context;
+
+ if (this.node.const_tags.length) {
+ if_get_context = block.renderer.component.get_unique_name('get_context');
+ block.renderer.blocks.push(b`
+ function ${if_get_context}(#ctx) {
+ ${add_const_tags(block, this.node.const_tags, '#ctx')}
+ }
+ `);
+ }
+ if (this.node.else && this.node.else.const_tags.length) {
+ else_get_context = block.renderer.component.get_unique_name('get_context');
+ block.renderer.blocks.push(b`
+ function ${else_get_context}(#ctx) {
+ ${add_const_tags(block, this.node.const_tags, '#ctx')}
+ }
+ `);
+ }
+
if (this.else.length > 0) {
return b`
if (${this.node.expression.manipulate(block, '#ctx')}) {
+ ${if_get_context ? x`${if_get_context}(#ctx)` : null}
${this.children.map(slot => slot.render_slot_template_definition(block))}
} else {
+ ${else_get_context ? x`${else_get_context}(#ctx)` : null}
${this.else.map(slot => slot.render_slot_template_definition(block))}
}
`;
@@ -67,6 +93,7 @@ export default class SlotTemplateIfBlockWrapper extends Wrapper {
return b`
if (${this.node.expression.manipulate(block, '#ctx')}) {
+ ${if_get_context ? x`${if_get_context}(#ctx)` : null}
${this.children.map(slot => slot.render_slot_template_definition(block))}
}
`;
diff --git a/src/compiler/compile/render_ssr/handlers/SlotTemplateIfBlock.ts b/src/compiler/compile/render_ssr/handlers/SlotTemplateIfBlock.ts
index c0f0b458aa..7e9ddcd2ca 100644
--- a/src/compiler/compile/render_ssr/handlers/SlotTemplateIfBlock.ts
+++ b/src/compiler/compile/render_ssr/handlers/SlotTemplateIfBlock.ts
@@ -1,7 +1,7 @@
import Renderer, { RenderOptions } from '../Renderer';
import { b } from 'code-red';
import SlotTemplateIfBlock from '../../nodes/SlotTemplateIfBlock';
-import { flatten } from '../../../utils/flatten';
+import { get_const_tags } from './shared/get_const_tags';
export default function (node: SlotTemplateIfBlock, renderer: Renderer, options: RenderOptions) {
const if_slot_scopes = [];
@@ -16,14 +16,17 @@ export default function (node: SlotTemplateIfBlock, renderer: Renderer, options:
}));
options.slot_scopes.push(b`
if (${node.expression.node}) {
+ ${get_const_tags(node.const_tags)}
${if_slot_scopes}
} else {
+ ${get_const_tags(node.else.const_tags)}
${else_slot_scopes}
}
`);
} else {
options.slot_scopes.push(b`if (${node.expression.node}) {
- ${flatten(if_slot_scopes)}
+ ${get_const_tags(node.const_tags)}
+ ${if_slot_scopes}
}`);
}
}
diff --git a/test/runtime/samples/component-dynamic-slot-7/Foo.svelte b/test/runtime/samples/component-dynamic-slot-7/Foo.svelte
new file mode 100644
index 0000000000..4dc85932e2
--- /dev/null
+++ b/test/runtime/samples/component-dynamic-slot-7/Foo.svelte
@@ -0,0 +1,7 @@
+
+
+
one: 1 two: 2
`, diff --git a/test/runtime/samples/component-slot-slot/_config.js b/test/runtime/samples/component-slot-slot/_config.js index 09311852cc..32af774fac 100644 --- a/test/runtime/samples/component-slot-slot/_config.js +++ b/test/runtime/samples/component-slot-slot/_config.js @@ -1,4 +1,3 @@ export default { - solo:true, html: '