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

event propagation shorthand for components (#638)

This commit is contained in:
Rich Harris 2017-07-29 18:19:04 -04:00
parent 51af8c29e0
commit 1b92f5fa20
4 changed files with 49 additions and 14 deletions

View File

@ -13,22 +13,25 @@ export default function visitEventHandler(
local
) {
// TODO verify that it's a valid callee (i.e. built-in or declared method)
generator.addSourcemapLocations(attribute.expression);
generator.code.prependRight(
attribute.expression.start,
`${block.alias('component')}.`
);
const usedContexts: string[] = [];
attribute.expression.arguments.forEach((arg: Node) => {
const { contexts } = block.contextualise(arg, null, true);
contexts.forEach(context => {
if (!~usedContexts.indexOf(context)) usedContexts.push(context);
if (!~local.allUsedContexts.indexOf(context))
local.allUsedContexts.push(context);
if (attribute.expression) {
generator.addSourcemapLocations(attribute.expression);
generator.code.prependRight(
attribute.expression.start,
`${block.alias('component')}.`
);
attribute.expression.arguments.forEach((arg: Node) => {
const { contexts } = block.contextualise(arg, null, true);
contexts.forEach(context => {
if (!~usedContexts.indexOf(context)) usedContexts.push(context);
if (!~local.allUsedContexts.indexOf(context))
local.allUsedContexts.push(context);
});
});
});
}
// TODO hoist event handlers? can do `this.__component.method(...)`
const declarations = usedContexts.map(name => {
@ -42,7 +45,9 @@ export default function visitEventHandler(
const handlerBody =
(declarations.length ? declarations.join('\n') + '\n\n' : '') +
`[✂${attribute.expression.start}-${attribute.expression.end}✂];`;
(attribute.expression ?
`[✂${attribute.expression.start}-${attribute.expression.end}✂];` :
`${block.alias('component')}.fire('${attribute.name}', event);`);
local.create.addBlock(deindent`
${local.name}.on( '${attribute.name}', function ( event ) {

View File

@ -0,0 +1 @@
<button on:click='fire("foo", { answer: 42 })'>click me</button>

View File

@ -0,0 +1,18 @@
export default {
html: `
<button>click me</button>
`,
test (assert, component, target, window) {
const button = target.querySelector('button');
const event = new window.MouseEvent('click');
let answer;
component.on('foo', event => {
answer = event.answer;
});
button.dispatchEvent(event);
assert.equal(answer, 42);
}
};

View File

@ -0,0 +1,11 @@
<Widget on:foo/>
<script>
import Widget from './Widget.html';
export default {
components: {
Widget
}
};
</script>