Skip to content

Commit

Permalink
[BUGFIX release] Fixing IE and Edge issue (#15076) which caused actio…
Browse files Browse the repository at this point in the history
…n handlers to be fired twice.
  • Loading branch information
Wesley Workman committed Mar 28, 2017
1 parent eb3299a commit 00e95be
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1440,4 +1440,38 @@ moduleFor('Helpers test: element action', class extends RenderingTest {
document.getElementById('ddButton').click();
});
}

['@test action handler that shifts element attributes doesn\'t trigger multiple invocations']() {
let actionCount = 0;
let ExampleComponent = Component.extend({
selected: false,
actions: {
toggleSelected() {
actionCount++;
this.toggleProperty('selected');
}
}
});

this.registerComponent('example-component', {
ComponentClass: ExampleComponent,
template: '<button class="{{if selected \'selected\'}}" {{action "toggleSelected"}}>Toggle Selected</button>'
});

this.render('{{example-component}}');

this.runTask(() => {
this.$('button').click();
});

this.assert.equal(actionCount, 1, 'Click action only fired once.');
this.assert.ok(this.$('button').hasClass('selected'), 'Element with action handler has properly updated it\'s conditional class');

this.runTask(() => {
this.$('button').click();
});

this.assert.equal(actionCount, 2, 'Second click action only fired once.');
this.assert.ok(!this.$('button').hasClass('selected'), 'Element with action handler has properly updated it\'s conditional class');
}
});
7 changes: 6 additions & 1 deletion packages/ember-views/lib/system/event_dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ export default EmberObject.extend({

rootElement.on(`${event}.ember`, '[data-ember-action]', evt => {
let attributes = evt.currentTarget.attributes;
let handledActions = [];

for (let i = 0; i < attributes.length; i++) {
let attr = attributes.item(i);
Expand All @@ -231,8 +232,12 @@ export default EmberObject.extend({
// We have to check for action here since in some cases, jQuery will trigger
// an event on `removeChild` (i.e. focusout) after we've already torn down the
// action handlers for the view.
if (action && action.eventName === eventName) {
if (action && action.eventName === eventName && handledActions.indexOf(action) === -1) {
action.handler(evt);
// Action handlers can mutate state which in turn creates new attributes on the element.
// This effect could cause the `data-ember-action` attribute to shift down and be invoked twice.
// To avoid this, we keep track of which actions have been handled.
handledActions.push(action);
}
}
}
Expand Down

0 comments on commit 00e95be

Please sign in to comment.