mirror of
https://github.com/sveltejs/svelte.git
synced 2024-12-01 17:30:59 +01:00
fix destructuring in slot let binding
This commit is contained in:
parent
5486d67adf
commit
75b8d3fb21
@ -7,7 +7,7 @@ import { BinaryExpression } from 'estree';
|
||||
export function get_slot_definition(block: Block, scope: TemplateScope, lets: Let[]) {
|
||||
if (lets.length === 0) return { block, scope };
|
||||
|
||||
const input = {
|
||||
const context_input = {
|
||||
type: 'ObjectPattern',
|
||||
properties: lets.map(l => ({
|
||||
type: 'Property',
|
||||
@ -17,10 +17,41 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
|
||||
}))
|
||||
};
|
||||
|
||||
const properties = [];
|
||||
const value_map = new Map();
|
||||
|
||||
lets.forEach(l => {
|
||||
let value;
|
||||
if (l.names.length > 1) {
|
||||
// more than one, probably destructuring
|
||||
const unique_name = block.get_unique_name(l.names.join('_')).name;
|
||||
value_map.set(l.value, unique_name);
|
||||
value = { type: 'Identifier', name: unique_name };
|
||||
} else {
|
||||
value = l.value || l.name;
|
||||
}
|
||||
properties.push({
|
||||
type: 'Property',
|
||||
kind: 'init',
|
||||
key: l.name,
|
||||
value,
|
||||
});
|
||||
});
|
||||
|
||||
const changes_input = {
|
||||
type: 'ObjectPattern',
|
||||
properties,
|
||||
};
|
||||
|
||||
const names: Set<string> = new Set();
|
||||
const names_lookup: Map<string, string> = new Map();
|
||||
|
||||
lets.forEach(l => {
|
||||
l.names.forEach(name => {
|
||||
names.add(name);
|
||||
if (value_map.has(l.value)) {
|
||||
names_lookup.set(name, value_map.get(l.value));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -43,8 +74,10 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
|
||||
const i = context_lookup.get(name).index.value as number;
|
||||
const g = Math.floor(i / 31);
|
||||
|
||||
const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name;
|
||||
|
||||
if (!grouped[g]) grouped[g] = [];
|
||||
grouped[g].push({ name, n: i % 31 });
|
||||
grouped[g].push({ name: lookup_name, n: i % 31 });
|
||||
});
|
||||
|
||||
const elements = [];
|
||||
@ -65,8 +98,9 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
|
||||
|
||||
return Array.from(names)
|
||||
.map(name => {
|
||||
const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name;
|
||||
const i = context_lookup.get(name).index.value as number;
|
||||
return x`${name} ? ${1 << i} : 0`;
|
||||
return x`${lookup_name} ? ${1 << i} : 0`;
|
||||
})
|
||||
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`) as BinaryExpression;
|
||||
}
|
||||
@ -75,7 +109,7 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
|
||||
return {
|
||||
block,
|
||||
scope,
|
||||
get_context: x`${input} => ${context}`,
|
||||
get_changes: x`${input} => ${changes}`
|
||||
get_context: x`${context_input} => ${context}`,
|
||||
get_changes: x`${changes_input} => ${changes}`
|
||||
};
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
export let props;
|
||||
</script>
|
||||
|
||||
<slot value={props} data={Array.isArray(props) ? props[0] : props.a} />
|
@ -0,0 +1,68 @@
|
||||
export default {
|
||||
html: `
|
||||
<div>
|
||||
hello world 0 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 0 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 0 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
`,
|
||||
async test({ assert, component, target, window }) {
|
||||
const [button1, button2, button3] = target.querySelectorAll('button');
|
||||
const event = new window.MouseEvent('click');
|
||||
|
||||
await button1.dispatchEvent(event);
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>
|
||||
hello world 1 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 0 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 0 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
`);
|
||||
|
||||
await button2.dispatchEvent(event);
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>
|
||||
hello world 1 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 1 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 0 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
`);
|
||||
|
||||
await button3.dispatchEvent(event);
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>
|
||||
hello world 1 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 1 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
<div>
|
||||
hello world 1 hello
|
||||
<button>Increment</button>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
};
|
@ -0,0 +1,28 @@
|
||||
<script>
|
||||
import Nested from "./Nested.svelte";
|
||||
let c = 0, d = 0, e = 0;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<Nested props={['hello', 'world']} let:value={pair} let:data={foo}>
|
||||
{pair[0]} {pair[1]} {c} {foo}
|
||||
</Nested>
|
||||
|
||||
<button on:click={() => { c += 1; }}>Increment</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Nested props={['hello', 'world']} let:value={[a, b]} let:data={foo}>
|
||||
{a} {b} {d} {foo}
|
||||
</Nested>
|
||||
|
||||
<button on:click={() => { d += 1; }}>Increment</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Nested props={{ a: 'hello', b: 'world' }} let:value={{ a, b }} let:data={foo}>
|
||||
{a} {b} {e} {foo}
|
||||
</Nested>
|
||||
|
||||
<button on:click={() => { e += 1; }}>Increment</button>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user