From 8759ccddbdfa0283cb5c397512f84aafe1db0433 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 28 Apr 2018 18:48:07 -0400 Subject: [PATCH] simplify ssr --- src/generators/nodes/AwaitBlock.ts | 9 ++-- src/generators/nodes/Comment.ts | 6 +-- src/generators/nodes/Component.ts | 40 ++++++++++++++---- src/generators/nodes/EachBlock.ts | 9 ++-- src/generators/nodes/Element.ts | 6 ++- src/generators/nodes/Head.ts | 8 ++-- src/generators/nodes/IfBlock.ts | 11 ++--- src/generators/nodes/MustacheTag.ts | 4 +- src/generators/nodes/RawMustacheTag.ts | 4 +- src/generators/nodes/Slot.ts | 8 ++-- src/generators/nodes/Text.ts | 4 +- src/generators/nodes/Title.ts | 8 ++-- src/generators/server-side-rendering/Block.ts | 41 ------------------- src/generators/server-side-rendering/index.ts | 10 +---- .../server-side-rendering/interfaces.ts | 14 ------- src/interfaces.ts | 5 +++ 16 files changed, 75 insertions(+), 112 deletions(-) delete mode 100644 src/generators/server-side-rendering/Block.ts delete mode 100644 src/generators/server-side-rendering/interfaces.ts diff --git a/src/generators/nodes/AwaitBlock.ts b/src/generators/nodes/AwaitBlock.ts index 634b97d659..9178e53714 100644 --- a/src/generators/nodes/AwaitBlock.ts +++ b/src/generators/nodes/AwaitBlock.ts @@ -220,21 +220,20 @@ export default class AwaitBlock extends Node { }); } - ssr(compiler, block) { + ssr() { + const { compiler } = this; const { snippet } = this.expression; - const childBlock = block.child({}); - compiler.append('${(function(__value) { if(@isPromise(__value)) return `'); this.pending.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); compiler.append('`; return function(ctx) { return `'); this.then.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); compiler.append(`\`;}(Object.assign({}, ctx, { ${this.value}: __value }));}(${snippet})) }`); diff --git a/src/generators/nodes/Comment.ts b/src/generators/nodes/Comment.ts index 4dfd493602..017011ed88 100644 --- a/src/generators/nodes/Comment.ts +++ b/src/generators/nodes/Comment.ts @@ -9,10 +9,10 @@ export default class Comment extends Node { this.data = info.data; } - ssr(compiler) { + ssr() { // Allow option to preserve comments, otherwise ignore - if (compiler.options.preserveComments) { - compiler.append(``); + if (this.compiler.options.preserveComments) { + this.compiler.append(``); } } } \ No newline at end of file diff --git a/src/generators/nodes/Component.ts b/src/generators/nodes/Component.ts index 2dc2a412b6..a6c0c9fb63 100644 --- a/src/generators/nodes/Component.ts +++ b/src/generators/nodes/Component.ts @@ -15,7 +15,7 @@ import mapChildren from './shared/mapChildren'; import Binding from './Binding'; import EventHandler from './EventHandler'; import Expression from './shared/Expression'; -import { AppendTarget } from '../server-side-rendering/interfaces'; +import { AppendTarget } from '../../interfaces'; export default class Component extends Node { type: 'Component'; @@ -483,7 +483,7 @@ export default class Component extends Node { return `${this.var}._mount(${name}._slotted.default, null);`; } - ssr(compiler, block) { + ssr() { function stringifyAttribute(chunk: Node) { if (chunk.type === 'Text') { return escapeTemplate(escape(chunk.data)); @@ -540,13 +540,35 @@ export default class Component extends Node { const isDynamicComponent = this.name === 'svelte:component'; const expression = ( - this.name === 'svelte:self' ? compiler.name : + this.name === 'svelte:self' ? this.compiler.name : isDynamicComponent ? `((${this.expression.snippet}) || @missingComponent)` : `%components-${this.name}` ); this.bindings.forEach(binding => { - block.addBinding(binding, expression); + const conditions = []; + + let node = this; + while (node = node.parent) { + if (node.type === 'IfBlock') { + // TODO handle contextual bindings... + conditions.push(`(${node.expression.snippet})`); + } + } + + conditions.push(`!('${binding.name}' in ctx)`); + + const { name } = getObject(binding.value.node); + + this.compiler.bindings.push(deindent` + if (${conditions.reverse().join('&&')}) { + tmp = ${expression}.data(); + if ('${name}' in tmp) { + ctx.${binding.name} = tmp.${name}; + settled = false; + } + } + `); }); let open = `\${${expression}._render(__result, ${props}`; @@ -560,10 +582,10 @@ export default class Component extends Node { slotStack: ['default'] }; - compiler.appendTargets.push(appendTarget); + this.compiler.appendTargets.push(appendTarget); this.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); const slotted = Object.keys(appendTarget.slots) @@ -572,15 +594,15 @@ export default class Component extends Node { options.push(`slotted: { ${slotted} }`); - compiler.appendTargets.pop(); + this.compiler.appendTargets.pop(); } if (options.length) { open += `, { ${options.join(', ')} }`; } - compiler.append(open); - compiler.append(')}'); + this.compiler.append(open); + this.compiler.append(')}'); } } diff --git a/src/generators/nodes/EachBlock.ts b/src/generators/nodes/EachBlock.ts index 52f3869c5c..41ba3a5251 100644 --- a/src/generators/nodes/EachBlock.ts +++ b/src/generators/nodes/EachBlock.ts @@ -473,7 +473,8 @@ export default class EachBlock extends Node { return `for (var #i = 0; #i < ${this.iterations}.length; #i += 1) ${this.iterations}[#i].m(${name}._slotted.default, null);`; } - ssr(compiler, block) { + ssr() { + const { compiler } = this; const { snippet } = this.expression; const props = [`${this.context}: item`] @@ -486,10 +487,8 @@ export default class EachBlock extends Node { const open = `\${ ${this.else ? `${snippet}.length ? ` : ''}@each(${snippet}, ${getContext}, ctx => \``; compiler.append(open); - const childBlock = block.child({}); - this.children.forEach((child: Node) => { - child.ssr(compiler, childBlock); + child.ssr(); }); const close = `\`)`; @@ -498,7 +497,7 @@ export default class EachBlock extends Node { if (this.else) { compiler.append(` : \``); this.else.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); compiler.append(`\``); } diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts index 9e56deb2bf..4f9bd7f5ca 100644 --- a/src/generators/nodes/Element.ts +++ b/src/generators/nodes/Element.ts @@ -831,7 +831,9 @@ export default class Element extends Node { } } - ssr(compiler, block) { + ssr() { + const { compiler } = this; + let openingTag = `<${this.name}`; let textareaContents; // awkward special case @@ -902,7 +904,7 @@ export default class Element extends Node { compiler.append(textareaContents); } else { this.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); } diff --git a/src/generators/nodes/Head.ts b/src/generators/nodes/Head.ts index e9d0ea041f..dc53e99613 100644 --- a/src/generators/nodes/Head.ts +++ b/src/generators/nodes/Head.ts @@ -36,13 +36,13 @@ export default class Head extends Node { }); } - ssr(compiler, block) { - compiler.append('${(__result.head += `'); + ssr() { + this.compiler.append('${(__result.head += `'); this.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); - compiler.append('`, "")}'); + this.compiler.append('`, "")}'); } } diff --git a/src/generators/nodes/IfBlock.ts b/src/generators/nodes/IfBlock.ts index 40a1ec46b6..b79b0b3a83 100644 --- a/src/generators/nodes/IfBlock.ts +++ b/src/generators/nodes/IfBlock.ts @@ -476,24 +476,21 @@ export default class IfBlock extends Node { return branches; } - ssr(compiler, block) { + ssr() { + const { compiler } = this; const { snippet } = this.expression; compiler.append('${ ' + snippet + ' ? `'); - const childBlock = block.child({ - conditions: block.conditions.concat(snippet), - }); - this.children.forEach((child: Node) => { - child.ssr(compiler, childBlock); + child.ssr(); }); compiler.append('` : `'); if (this.else) { this.else.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); } diff --git a/src/generators/nodes/MustacheTag.ts b/src/generators/nodes/MustacheTag.ts index 9547db2878..cad7a991ae 100644 --- a/src/generators/nodes/MustacheTag.ts +++ b/src/generators/nodes/MustacheTag.ts @@ -25,8 +25,8 @@ export default class MustacheTag extends Tag { return `@appendNode(${this.var}, ${name}._slotted.default);`; } - ssr(compiler) { - compiler.append( + ssr() { + this.compiler.append( this.parent && this.parent.type === 'Element' && this.parent.name === 'style' diff --git a/src/generators/nodes/RawMustacheTag.ts b/src/generators/nodes/RawMustacheTag.ts index bee92f0fe4..00881bebd7 100644 --- a/src/generators/nodes/RawMustacheTag.ts +++ b/src/generators/nodes/RawMustacheTag.ts @@ -88,7 +88,7 @@ export default class RawMustacheTag extends Tag { return `@appendNode(${this.var}, ${name}._slotted.default);`; } - ssr(compiler) { - compiler.append('${' + this.expression.snippet + '}'); + ssr() { + this.compiler.append('${' + this.expression.snippet + '}'); } } \ No newline at end of file diff --git a/src/generators/nodes/Slot.ts b/src/generators/nodes/Slot.ts index c8b58c9b4d..0069fa9d8d 100644 --- a/src/generators/nodes/Slot.ts +++ b/src/generators/nodes/Slot.ts @@ -151,16 +151,16 @@ export default class Slot extends Element { return null; } - ssr(compiler, block) { + ssr() { const name = this.attributes.find(attribute => attribute.name === 'name'); const slotName = name && name.chunks[0].data || 'default'; - compiler.append(`\${options && options.slotted && options.slotted.${slotName} ? options.slotted.${slotName}() : \``); + this.compiler.append(`\${options && options.slotted && options.slotted.${slotName} ? options.slotted.${slotName}() : \``); this.children.forEach((child: Node) => { - child.ssr(compiler, block); + child.ssr(); }); - compiler.append(`\`}`); + this.compiler.append(`\`}`); } } \ No newline at end of file diff --git a/src/generators/nodes/Text.ts b/src/generators/nodes/Text.ts index 8a8c533366..5f9237c219 100644 --- a/src/generators/nodes/Text.ts +++ b/src/generators/nodes/Text.ts @@ -68,7 +68,7 @@ export default class Text extends Node { return `@appendNode(${this.var}, ${name}._slotted.default);`; } - ssr(compiler) { + ssr() { let text = this.data; if ( !this.parent || @@ -78,6 +78,6 @@ export default class Text extends Node { // unless this Text node is inside a