Skip to content

Commit

Permalink
Merge pull request #1366 from sveltejs/gh-1353
Browse files Browse the repository at this point in the history
prevent stale state in component event handlers
  • Loading branch information
Rich-Harris authored Apr 22, 2018
2 parents a78f37d + 3a955ba commit 4f86820
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/generators/nodes/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import mungeAttribute from './shared/mungeAttribute';
import Node from './shared/Node';
import Block from '../dom/Block';
import Attribute from './Attribute';
import usesThisOrArguments from '../../validate/js/utils/usesThisOrArguments';

export default class Component extends Node {
type: 'Component';
Expand Down Expand Up @@ -494,20 +495,24 @@ function mungeEventHandler(generator: DomGenerator, node: Node, handler: Node, b
);
}

let usesState = false;

handler.expression.arguments.forEach((arg: Node) => {
const { contexts } = block.contextualise(arg, null, true);
if (contexts.has('state')) usesState = true;

contexts.forEach(context => {
allContexts.add(context);
});
});

body = deindent`
${usesState && `const state = #component.get();`}
[✂${handler.expression.start}-${handler.expression.end}✂];
`;
} else {
body = deindent`
${block.alias('component')}.fire('${handler.name}', event);
#component.fire('${handler.name}', event);
`;
}

Expand Down
1 change: 1 addition & 0 deletions test/runtime/samples/component-event-not-stale/Button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<button on:click><slot/></button>
30 changes: 30 additions & 0 deletions test/runtime/samples/component-event-not-stale/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export default {
data: {
value: 1,
},

test(assert, component, target, window) {
const buttons = target.querySelectorAll('button');
const click = new window.MouseEvent('click');

const events = [];
component.on('value', event => {
events.push(event);
});

buttons[0].dispatchEvent(click);
buttons[1].dispatchEvent(click);

component.set({ value: 2 });

buttons[0].dispatchEvent(click);
buttons[1].dispatchEvent(click);

assert.deepEqual(events, [
{ value: 1 },
{ value: 1 },
{ value: 2 },
{ value: 2 }
]);
},
};
20 changes: 20 additions & 0 deletions test/runtime/samples/component-event-not-stale/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Button on:click="handleClick()">one</Button>
<Button on:click="fire('value', {value})">two</Button>

<script>
import Button from './Button.html';

export default {
components: {
Button
},

methods: {
handleClick() {
const { value } = this.get();
this.fire('value', { value });
}
}

}
</script>

0 comments on commit 4f86820

Please sign in to comment.