diff --git a/src/compiler/compile/render_dom/Renderer.ts b/src/compiler/compile/render_dom/Renderer.ts
index c02d646ebf..5092626d25 100644
--- a/src/compiler/compile/render_dom/Renderer.ts
+++ b/src/compiler/compile/render_dom/Renderer.ts
@@ -60,7 +60,7 @@ export default class Renderer {
if (component.slots.size > 0) {
this.add_to_context('$$scope');
- this.add_to_context('$$slots');
+ this.add_to_context('#slots');
}
if (this.binding_groups.size > 0) {
diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts
index 7d0dce8315..4ee9abae49 100644
--- a/src/compiler/compile/render_dom/index.ts
+++ b/src/compiler/compile/render_dom/index.ts
@@ -70,6 +70,15 @@ export default function dom(
);
}
+ const uses_slots = component.var_lookup.has('$$slots');
+ let compute_slots;
+ if (uses_slots) {
+ compute_slots = b`
+ const $$slots = @compute_slots(#slots);
+ `;
+ }
+
+
const uses_props = component.var_lookup.has('$$props');
const uses_rest = component.var_lookup.has('$$restProps');
const $$props = uses_props || uses_rest ? `$$new_props` : `$$props`;
@@ -409,13 +418,14 @@ export default function dom(
${resubscribable_reactive_store_unsubscribers}
+ ${component.slots.size || component.compile_options.dev || uses_slots ? b`let { $$slots: #slots = {}, $$scope } = $$props;` : null}
+ ${component.compile_options.dev && b`@validate_slots('${component.tag}', #slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`}
+ ${compute_slots}
+
${instance_javascript}
${unknown_props_check}
- ${component.slots.size || component.compile_options.dev ? b`let { $$slots = {}, $$scope } = $$props;` : null}
- ${component.compile_options.dev && b`@validate_slots('${component.tag}', $$slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`}
-
${renderer.binding_groups.size > 0 && b`const $$binding_groups = [${[...renderer.binding_groups.keys()].map(_ => x`[]`)}];`}
${component.partly_hoisted}
diff --git a/src/compiler/compile/render_dom/wrappers/Slot.ts b/src/compiler/compile/render_dom/wrappers/Slot.ts
index bf808196c0..5c02e78158 100644
--- a/src/compiler/compile/render_dom/wrappers/Slot.ts
+++ b/src/compiler/compile/render_dom/wrappers/Slot.ts
@@ -125,7 +125,7 @@ export default class SlotWrapper extends Wrapper {
const slot_or_fallback = has_fallback ? block.get_unique_name(`${sanitize(slot_name)}_slot_or_fallback`) : slot;
block.chunks.init.push(b`
- const ${slot_definition} = ${renderer.reference('$$slots')}.${slot_name};
+ const ${slot_definition} = ${renderer.reference('#slots')}.${slot_name};
const ${slot} = @create_slot(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn});
${has_fallback ? b`const ${slot_or_fallback} = ${slot} || ${this.fallback.name}(#ctx);` : null}
`);
diff --git a/src/compiler/compile/render_ssr/handlers/Slot.ts b/src/compiler/compile/render_ssr/handlers/Slot.ts
index 3b1e199c75..32b6246e64 100644
--- a/src/compiler/compile/render_ssr/handlers/Slot.ts
+++ b/src/compiler/compile/render_ssr/handlers/Slot.ts
@@ -11,8 +11,8 @@ export default function(node: Slot, renderer: Renderer, options: RenderOptions)
const result = renderer.pop();
renderer.add_expression(x`
- $$slots.${node.slot_name}
- ? $$slots.${node.slot_name}(${slot_data})
+ #slots.${node.slot_name}
+ ? #slots.${node.slot_name}(${slot_data})
: ${result}
`);
}
diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts
index a72b8b35ae..ff45abd78b 100644
--- a/src/compiler/compile/render_ssr/index.ts
+++ b/src/compiler/compile/render_ssr/index.ts
@@ -34,6 +34,9 @@ export default function ssr(
const props = component.vars.filter(variable => !variable.module && variable.export_name);
const rest = uses_rest ? b`let $$restProps = @compute_rest_props($$props, [${props.map(prop => `"${prop.export_name}"`).join(',')}]);` : null;
+ const uses_slots = component.var_lookup.has('$$slots');
+ const slots = uses_slots ? b`let $$slots = @compute_slots(#slots);` : null;
+
const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$');
const reactive_store_values = reactive_stores
.map(({ name }) => {
@@ -118,6 +121,7 @@ export default function ssr(
const blocks = [
rest,
+ slots,
...reactive_stores.map(({ name }) => {
const store_name = name.slice(1);
const store = component.var_lookup.get(store_name);
@@ -144,7 +148,7 @@ export default function ssr(
${component.fully_hoisted}
- const ${name} = @create_ssr_component(($$result, $$props, $$bindings, $$slots) => {
+ const ${name} = @create_ssr_component(($$result, $$props, $$bindings, #slots) => {
${blocks}
});
`;
diff --git a/src/compiler/compile/utils/reserved_keywords.ts b/src/compiler/compile/utils/reserved_keywords.ts
index 75825c1719..d6eb8b9673 100644
--- a/src/compiler/compile/utils/reserved_keywords.ts
+++ b/src/compiler/compile/utils/reserved_keywords.ts
@@ -1,4 +1,4 @@
-export const reserved_keywords = new Set(["$$props", "$$restProps"]);
+export const reserved_keywords = new Set(["$$props", "$$restProps", "$$slots"]);
export function is_reserved_keyword(name) {
return reserved_keywords.has(name);
diff --git a/src/runtime/internal/utils.ts b/src/runtime/internal/utils.ts
index 3fd0a2b701..633b6f054c 100644
--- a/src/runtime/internal/utils.ts
+++ b/src/runtime/internal/utils.ts
@@ -128,6 +128,14 @@ export function compute_rest_props(props, keys) {
return rest;
}
+export function compute_slots(slots) {
+ const result = {};
+ for (const key in slots) {
+ result[key] = true;
+ }
+ return result;
+}
+
export function once(fn) {
let ran = false;
return function(this: any, ...args) {
diff --git a/test/runtime/samples/$$slot/A.svelte b/test/runtime/samples/$$slot/A.svelte
new file mode 100644
index 0000000000..ffa166166c
--- /dev/null
+++ b/test/runtime/samples/$$slot/A.svelte
@@ -0,0 +1,31 @@
+
+
+