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[]) {
|
export function get_slot_definition(block: Block, scope: TemplateScope, lets: Let[]) {
|
||||||
if (lets.length === 0) return { block, scope };
|
if (lets.length === 0) return { block, scope };
|
||||||
|
|
||||||
const input = {
|
const context_input = {
|
||||||
type: 'ObjectPattern',
|
type: 'ObjectPattern',
|
||||||
properties: lets.map(l => ({
|
properties: lets.map(l => ({
|
||||||
type: 'Property',
|
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: Set<string> = new Set();
|
||||||
|
const names_lookup: Map<string, string> = new Map();
|
||||||
|
|
||||||
lets.forEach(l => {
|
lets.forEach(l => {
|
||||||
l.names.forEach(name => {
|
l.names.forEach(name => {
|
||||||
names.add(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 i = context_lookup.get(name).index.value as number;
|
||||||
const g = Math.floor(i / 31);
|
const g = Math.floor(i / 31);
|
||||||
|
|
||||||
|
const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name;
|
||||||
|
|
||||||
if (!grouped[g]) grouped[g] = [];
|
if (!grouped[g]) grouped[g] = [];
|
||||||
grouped[g].push({ name, n: i % 31 });
|
grouped[g].push({ name: lookup_name, n: i % 31 });
|
||||||
});
|
});
|
||||||
|
|
||||||
const elements = [];
|
const elements = [];
|
||||||
@ -65,8 +98,9 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
|
|||||||
|
|
||||||
return Array.from(names)
|
return Array.from(names)
|
||||||
.map(name => {
|
.map(name => {
|
||||||
|
const lookup_name = names_lookup.has(name) ? names_lookup.get(name) : name;
|
||||||
const i = context_lookup.get(name).index.value as number;
|
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;
|
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`) as BinaryExpression;
|
||||||
}
|
}
|
||||||
@ -75,7 +109,7 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le
|
|||||||
return {
|
return {
|
||||||
block,
|
block,
|
||||||
scope,
|
scope,
|
||||||
get_context: x`${input} => ${context}`,
|
get_context: x`${context_input} => ${context}`,
|
||||||
get_changes: x`${input} => ${changes}`
|
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