various fixes

pull/3539/head
Richard Harris 6 years ago
parent 23167da0dd
commit 1e2f29bf4e

@ -78,7 +78,7 @@ export default class Renderer {
});
this.literal.expressions.push(node);
this.current = { value: '' };
this.current.value = '';
}
push() {

@ -66,22 +66,20 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
const slot = node.get_static_attribute_value('slot');
const nearest_inline_component = node.find_nearest(/InlineComponent/);
if (slot && nearest_inline_component) {
const slot = node.attributes.find((attribute) => attribute.name === 'slot');
const slot_name = (slot.chunks[0] as Text).data;
const target = renderer.targets[renderer.targets.length - 1];
target.slot_stack.push(slot_name);
target.slots[slot_name] = '';
const lets = node.lets;
const seen = new Set(lets.map(l => l.name.name));
// if (slot && nearest_inline_component) {
// const slot = node.attributes.find((attribute) => attribute.name === 'slot');
// const slot_name = (slot.chunks[0] as Text).data;
nearest_inline_component.lets.forEach(l => {
if (!seen.has(l.name.name)) lets.push(l);
});
// const lets = node.lets;
// const seen = new Set(lets.map(l => l.name.name));
options.slot_scopes.set(slot_name, get_slot_scope(node.lets));
}
// nearest_inline_component.lets.forEach(l => {
// if (!seen.has(l.name.name)) lets.push(l);
// });
// options.slot_scopes.set(slot_name, get_slot_scope(node.lets));
// }
const class_expression = node.classes.map((class_directive: Class) => {
const { expression, name } = class_directive;
@ -189,6 +187,21 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
} else {
renderer.add_expression(node_contents);
}
} else if (slot && nearest_inline_component) {
renderer.push();
renderer.render(node.children, options);
const lets = node.lets;
const seen = new Set(lets.map(l => l.name.name));
nearest_inline_component.lets.forEach(l => {
if (!seen.has(l.name.name)) lets.push(l);
});
options.slot_scopes.set(slot, {
input: get_slot_scope(node.lets),
output: renderer.pop()
});
} else {
renderer.render(node.children, options);
}

@ -36,17 +36,16 @@ export default function(node: InlineComponent, renderer: Renderer, options: Rend
let props;
if (uses_spread) {
props = `@_Object.assign(${
props = x`@_Object.assign(${
node.attributes
.map(attribute => {
if (attribute.is_spread) {
return snip(attribute.expression);
return attribute.expression.node;
} else {
return `{ ${quote_name_if_necessary(attribute.name)}: ${get_prop_value(attribute)} }`;
return x`{ ${attribute.name}: ${get_prop_value(attribute)} }`;
}
})
.concat(binding_props.map(p => `{ ${p} }`))
.join(', ')
})`;
} else {
props = x`{
@ -61,7 +60,7 @@ export default function(node: InlineComponent, renderer: Renderer, options: Rend
const expression = (
node.name === 'svelte:self'
? '__svelte:self__' // TODO conflict-proof this
? options.name
: node.name === 'svelte:component'
? x`(${node.expression.node}) || @missing_component`
: node.name

@ -5,6 +5,7 @@ import { stringify, string_literal } from '../utils/stringify';
import Renderer from './Renderer';
import { INode as TemplateNode } from '../nodes/interfaces'; // TODO
import Text from '../nodes/Text';
import { extract_names } from '../utils/scope';
export default function ssr(
component: Component,
@ -32,14 +33,15 @@ export default function ssr(
.map(({ name }) => {
const store_name = name.slice(1);
const store = component.var_lookup.get(store_name);
if (store && store.hoistable) return;
if (store && store.hoistable) return null;
const assignment = `${name} = @get_store_value(${store_name});`;
const assignment = b`${name} = @get_store_value(${store_name});`;
return component.compile_options.dev
? `@validate_store(${store_name}, '${store_name}'); ${assignment}`
? b`@validate_store(${store_name}, '${store_name}'); ${assignment}`
: assignment;
});
})
.filter(Boolean);
// TODO remove this, just use component.vars everywhere
const props = component.vars.filter(variable => !variable.module && variable.export_name);
@ -67,33 +69,35 @@ export default function ssr(
})
: [];
const reactive_declarations = component.reactive_declarations.map(_d => {
throw new Error('TODO');
// let snippet = `[✂${d.node.body.start}-${d.node.end}✂]`;
// if (d.declaration) {
// const declared = extract_names(d.declaration);
// const injected = declared.filter(name => {
// return name[0] !== '$' && component.var_lookup.get(name).injected;
// });
// const self_dependencies = injected.filter(name => d.dependencies.has(name));
// if (injected.length) {
// // in some cases we need to do `let foo; [expression]`, in
// // others we can do `let [expression]`
// const separate = (
// self_dependencies.length > 0 ||
// declared.length > injected.length
// );
// snippet = separate
// ? `let ${injected.join(', ')}; ${snippet}`
// : `let ${snippet}`;
// }
// }
// return snippet;
const reactive_declarations = component.reactive_declarations.map(d => {
let snippet = b`${d.node}`;
if (d.declaration) {
const declared = extract_names(d.declaration);
const injected = declared.filter(name => {
return name[0] !== '$' && component.var_lookup.get(name).injected;
});
const self_dependencies = injected.filter(name => d.dependencies.has(name));
if (injected.length) {
// in some cases we need to do `let foo; [expression]`, in
// others we can do `let [expression]`
const separate = (
self_dependencies.length > 0 ||
declared.length > injected.length
);
snippet = separate
? b`
${injected.map(name => b`let ${name};`)}
${snippet}`
: b`
let ${snippet}`;
}
}
return snippet;
});
const main = renderer.has_bindings

@ -1,4 +0,0 @@
export function snip(expression) {
throw new Error(`snip bad`);
return `[✂${expression.node.start}-${expression.node.end}✂]`;
}

@ -1,20 +1,52 @@
export default {
html: `<div>foo</div><div>bar</div><div>baz</div>`,
props: {
state: 'deconflicted',
states: [
'Alabama',
'Alaska',
'Arizona',
'Arkansas',
'...and some others'
]
},
html: `
<p>Current state: deconflicted</p>
<ul>
<li>Alabama</li>
<li>Alaska</li>
<li>Arizona</li>
<li>Arkansas</li>
<li>...and some others</li>
</ul>
`,
test({ assert, component, target }) {
let elems = target.querySelectorAll('div');
assert.equal(component.divs.length, 3, 'three divs are registered (unkeyed array)');
component.divs.forEach((e, i) => {
assert.equal(e, elems[i], `div ${i} is correct (unkeyed array)`);
});
component.states = [
'Maine',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana'
];
component.items = ['foo', 'baz'];
assert.equal(component.divs.length, 3, 'the divs array is still 3 long');
assert.equal(component.divs[2], null, 'the last div is unregistered');
assert.htmlEqual( target.innerHTML, `
<p>Current state: deconflicted</p>
elems = target.querySelectorAll('div');
component.divs.forEach((e, i) => {
assert.equal(e, elems[i], `div ${i} is still correct`);
});
<ul>
<li>Maine</li>
<li>Maryland</li>
<li>Massachusetts</li>
<li>Michigan</li>
<li>Minnesota</li>
<li>Mississippi</li>
<li>Missouri</li>
<li>Montana</li>
</ul>
` );
}
};

@ -1,8 +1,12 @@
<script>
export let items = ['foo', 'bar', 'baz'];
export let divs = [];
export let state;
export let states;
</script>
{#each items as item, j}
<div bind:this={divs[j]}>{item}</div>
<p>Current state: {state}</p>
<ul>
{#each states as state}
<li>{state}</li>
{/each}
</ul>
Loading…
Cancel
Save