0
0
mirror of https://github.com/sveltejs/svelte.git synced 2024-12-01 17:30:59 +01:00

server-side named slots

This commit is contained in:
Rich Harris 2017-08-26 17:04:29 -04:00
parent efe25555cf
commit 1ae3ab7bf9
5 changed files with 48 additions and 15 deletions

View File

@ -12,6 +12,8 @@ export class SsrGenerator extends Generator {
bindings: string[];
renderCode: string;
elementDepth: number; // TODO is this necessary? appears to be unused
appendTargets: Record<string, string> | null;
appendTarget: string | null;
constructor(
parsed: Parsed,
@ -24,6 +26,7 @@ export class SsrGenerator extends Generator {
this.bindings = [];
this.renderCode = '';
this.elementDepth = 0;
this.appendTargets = null;
// in an SSR context, we don't need to include events, methods, oncreate or ondestroy
const { templateProperties, defaultExport } = this;
@ -59,7 +62,23 @@ export class SsrGenerator extends Generator {
}
append(code: string) {
this.renderCode += code;
if (this.appendTarget) {
this.appendTargets[this.appendTarget] += code;
} else {
this.renderCode += code;
}
}
removeAppendTarget() {
this.appendTarget = this.appendTargets = null;
}
setAppendTarget(name: string) {
if (!this.appendTargets[name]) {
this.appendTargets[name] = '';
}
this.appendTarget = name;
}
}

View File

@ -80,19 +80,25 @@ export default function visitComponent(
let open = `\${${expression}.render({${props}}`;
if (node.children.length) {
open += `, { slotted: { default: () => \``;
generator.appendTargets = {};
generator.setAppendTarget('default');
generator.elementDepth += 1;
node.children.forEach((child: Node) => {
visit(generator, block, child);
});
generator.elementDepth -= 1;
const slotted = Object.keys(generator.appendTargets)
.map(name => `${name}: () => \`${generator.appendTargets[name]}\``)
.join(', ');
open += `, { slotted: { ${slotted} } }`;
generator.setAppendTarget(null);
}
generator.append(open);
generator.elementDepth += 1;
node.children.forEach((child: Node) => {
visit(generator, block, child);
});
generator.elementDepth -= 1;
const close = node.children.length ? `\` } })}` : ')}';
generator.append(close);
generator.append(')}');
}

View File

@ -47,6 +47,11 @@ export default function visitElement(
let openingTag = `<${node.name}`;
let textareaContents; // awkward special case
const slot = node.attributes.find((attribute: Node) => attribute.name === 'slot');
if (slot) {
generator.setAppendTarget(slot.value[0].data);
}
node.attributes.forEach((attribute: Node) => {
if (attribute.type !== 'Attribute') return;

View File

@ -9,7 +9,11 @@ export default function visitSlot(
node: Node
) {
// TODO named slots
generator.append(`<slot>\${options && options.slotted && options.slotted.default ? options.slotted.default() : '`);
const name = node.attributes.find((attribute: Node) => attribute.name);
const slotName = name && name.value[0].data || 'default';
generator.append(`<slot${slotName !== 'default' ? ` name='${slotName}'` : ''}>`);
generator.append(`\${options && options.slotted && options.slotted.${slotName} ? options.slotted.${slotName}() : '`);
generator.elementDepth += 1;

View File

@ -1,5 +1,4 @@
export default {
solo: true,
html: `
<div>
<slot>Hello</slot>