pass default slot values through to named slots

pull/2419/head
Richard Harris 5 years ago
parent 9b5615ffc2
commit ff01d64791

@ -3,16 +3,17 @@ import { CompileOptions } from '../../interfaces';
import Component from '../Component';
import FragmentWrapper from './wrappers/Fragment';
import CodeBuilder from '../utils/CodeBuilder';
import SlotWrapper from './wrappers/Slot';
export default class Renderer {
component: Component; // TODO Maybe Renderer shouldn't know about Component?
options: CompileOptions;
blocks: (Block | string)[];
readonly: Set<string>;
slots: Set<string>;
meta_bindings: CodeBuilder;
binding_groups: string[];
blocks: (Block | string)[] = [];
readonly: Set<string> = new Set();
slots: Map<string, { slot: SlotWrapper, block: Block }> = new Map();
meta_bindings: CodeBuilder = new CodeBuilder(); // initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag
binding_groups: string[] = [];
block: Block;
fragment: FragmentWrapper;
@ -24,16 +25,8 @@ export default class Renderer {
this.options = options;
this.locate = component.locate; // TODO messy
this.readonly = new Set();
this.slots = new Set();
this.file_var = options.dev && this.component.get_unique_name('file');
// initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag
this.meta_bindings = new CodeBuilder();
this.binding_groups = [];
// main block
this.block = new Block({
renderer: this,
@ -46,7 +39,6 @@ export default class Renderer {
});
this.block.has_update_method = true;
this.blocks = [];
this.fragment = new FragmentWrapper(
this,

@ -220,10 +220,6 @@ export default class ElementWrapper extends Wrapper {
render(block: Block, parent_node: string, parent_nodes: string) {
const { renderer } = this;
if (this.node.name === 'slot') {
renderer.slots.add((this.node as Slot).slot_name);
}
if (this.node.name === 'noscript') return;
if (this.slot_block) {

@ -9,10 +9,12 @@ import add_to_set from '../../utils/add_to_set';
import get_slot_data from '../../utils/get_slot_data';
import { stringify_props } from '../../utils/stringify_props';
import Expression from '../../nodes/shared/Expression';
import Attribute from '../../nodes/Attribute';
export default class SlotWrapper extends Wrapper {
node: Slot;
fragment: FragmentWrapper;
slot_values: Map<string, Attribute> = new Map();
var = 'slot';
dependencies: Set<string> = new Set(['$$scope']);
@ -38,14 +40,44 @@ export default class SlotWrapper extends Wrapper {
);
this.node.attributes.forEach(attribute => {
add_to_set(this.dependencies, attribute.dependencies);
if (attribute.name !== 'name') this.slot_values.set(attribute.name, attribute);
});
block.add_dependencies(this.dependencies);
if (this.node.slot_name === 'default') {
// if this is the default slot, add our dependencies to any
// other slots (which inherit our slot values) that were
// previously encountered
renderer.slots.forEach(({ slot, block }) => {
this.slot_values.forEach((attribute, name) => {
if (!slot.slot_values.has(name)) {
slot.slot_values.set(name, attribute);
add_to_set(slot.dependencies, attribute.dependencies);
block.add_dependencies(attribute.dependencies);
}
});
});
} else if (renderer.slots.has('default')) {
// otherwise, go the other way — inherit values from
// a previously encountered default slot
const { slot: default_slot } = renderer.slots.get('default');
default_slot.slot_values.forEach((attribute, name) => {
if (!this.slot_values.has(name)) {
this.slot_values.set(name, attribute);
}
});
}
this.slot_values.forEach(attribute => {
add_to_set(this.dependencies, attribute.dependencies);
block.add_dependencies(attribute.dependencies);
});
// we have to do this, just in case
block.add_intro();
block.add_outro();
renderer.slots.set(this.node.slot_name, { slot: this, block });
}
render(
@ -56,14 +88,13 @@ export default class SlotWrapper extends Wrapper {
const { renderer } = this;
const { slot_name } = this.node;
renderer.slots.add(slot_name);
let get_slot_changes;
let get_slot_context;
const attributes = this.node.attributes.filter(attribute => attribute.name !== 'name');
if (this.slot_values.size > 0) {
const attributes = Array.from(this.slot_values.values());
if (attributes.length > 0) {
get_slot_changes = renderer.component.get_unique_name(`get_${slot_name}_slot_changes`);
get_slot_context = renderer.component.get_unique_name(`get_${slot_name}_slot_context`);

Loading…
Cancel
Save