Skip to content

Commit

Permalink
Merge pull request #11373 from rwjblue/multiple-actions
Browse files Browse the repository at this point in the history
[BUGFIX beta] Fix issue with multiple actions in a single element.
  • Loading branch information
rwjblue committed Jun 8, 2015
2 parents 17fcf1c + 4e7d3be commit cb00d37
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 20 deletions.
17 changes: 12 additions & 5 deletions packages/ember-routing-htmlbars/lib/keywords/element-action.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ export default {
},

render: function(node, env, scope, params, hash, template, inverse, visitor) {
var actionId = ActionHelper.registerAction({
let actionId = env.dom.getAttribute(node.element, 'data-ember-action') || uuid();

ActionHelper.registerAction({
actionId,
node: node,
eventName: hash.on || "click",
bubbles: hash.bubbles,
Expand All @@ -77,10 +80,14 @@ export var ActionHelper = {};
// that were using this undocumented API.
ActionHelper.registeredActions = ActionManager.registeredActions;

ActionHelper.registerAction = function({ node, eventName, preventDefault, bubbles, allowedKeys }) {
var actionId = uuid();
ActionHelper.registerAction = function({ actionId, node, eventName, preventDefault, bubbles, allowedKeys }) {
var actions = ActionManager.registeredActions[actionId];

if (!actions) {
actions = ActionManager.registeredActions[actionId] = [];
}

ActionManager.registeredActions[actionId] = {
actions.push({
eventName,
handler(event) {
if (!isAllowedEvent(event, allowedKeys)) {
Expand Down Expand Up @@ -116,7 +123,7 @@ ActionHelper.registerAction = function({ node, eventName, preventDefault, bubble
}
});
}
};
});

return actionId;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,6 @@ QUnit.test("should allow 'send' as action name (#594)", function() {
ok(eventHandlerWasCalled, "The view's send method was called");
});


QUnit.test("should send the view, event and current context to the action", function() {
var passedTarget;
var passedContext;
Expand Down Expand Up @@ -1053,6 +1052,47 @@ QUnit.test("a quoteless parameter that does not resolve to a value asserts", fun
"Perhaps you meant to use a quoted actionName? (e.g. {{action 'save'}}).");
});

QUnit.test('allows multiple actions on a single element', function() {
var clickActionWasCalled = false;
var doubleClickActionWasCalled = false;

var controller = EmberController.extend({
actions: {
clicked() {
clickActionWasCalled = true;
},

doubleClicked() {
doubleClickActionWasCalled = true;
}
}
}).create();

view = EmberView.create({
controller: controller,
template: compile(`
<a href="#"
{{action "clicked" on="click"}}
{{action "doubleClicked" on="doubleClick"}}
>click me</a>
`)
});

runAppend(view);

var actionId = view.$('a[data-ember-action]').attr('data-ember-action');

ok(ActionManager.registeredActions[actionId], "The action was registered");

view.$('a').trigger('click');

ok(clickActionWasCalled, "The clicked action was called");

view.$('a').trigger('dblclick');

ok(doubleClickActionWasCalled, "The double click handler was called");
});

QUnit.module("ember-routing-htmlbars: action helper - deprecated invoking directly on target", {
setup() {
dispatcher = EventDispatcher.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ QUnit.test("{{render}} helper should link child controllers to the parent contro

var button = jQuery("#parent-action");
var actionId = button.data('ember-action');
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var handler = action.handler;

equal(button.text(), "Go to Mom", "The parentController property is set on the child controller");
Expand Down
16 changes: 10 additions & 6 deletions packages/ember-views/lib/system/event_dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,17 @@ export default EmberObject.extend({

rootElement.on(event + '.ember', '[data-ember-action]', function(evt) {
var actionId = jQuery(evt.currentTarget).attr('data-ember-action');
var action = ActionManager.registeredActions[actionId];
var actions = ActionManager.registeredActions[actionId];

// 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) {
return action.handler(evt);
for (let index = 0, length = actions.length; index < length; index++) {
let action = actions[index];

// 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) {
return action.handler(evt);
}
}
});
},
Expand Down
14 changes: 7 additions & 7 deletions packages/ember/tests/routing/basic_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ QUnit.asyncTest("Events are triggered on the controller if a matching action nam
bootApplication();

var actionId = Ember.$("#qunit-fixture a").data("ember-action");
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var event = new Ember.$.Event("click");
action.handler(event);
});
Expand Down Expand Up @@ -1198,7 +1198,7 @@ QUnit.asyncTest("Events are triggered on the current state when defined in `acti
bootApplication();

var actionId = Ember.$("#qunit-fixture a").data("ember-action");
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var event = new Ember.$.Event("click");
action.handler(event);
});
Expand Down Expand Up @@ -1236,7 +1236,7 @@ QUnit.asyncTest("Events defined in `actions` object are triggered on the current
bootApplication();

var actionId = Ember.$("#qunit-fixture a").data("ember-action");
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var event = new Ember.$.Event("click");
action.handler(event);
});
Expand Down Expand Up @@ -1271,7 +1271,7 @@ QUnit.asyncTest("Events are triggered on the current state when defined in `even
bootApplication();

var actionId = Ember.$("#qunit-fixture a").data("ember-action");
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var event = new Ember.$.Event("click");
action.handler(event);
});
Expand Down Expand Up @@ -1310,7 +1310,7 @@ QUnit.asyncTest("Events defined in `events` object are triggered on the current
bootApplication();

var actionId = Ember.$("#qunit-fixture a").data("ember-action");
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var event = new Ember.$.Event("click");
action.handler(event);
});
Expand Down Expand Up @@ -1392,7 +1392,7 @@ QUnit.asyncTest("Actions are not triggered on the controller if a matching actio
bootApplication();

var actionId = Ember.$("#qunit-fixture a").data("ember-action");
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var event = new Ember.$.Event("click");
action.handler(event);
});
Expand Down Expand Up @@ -1431,7 +1431,7 @@ QUnit.asyncTest("actions can be triggered with multiple arguments", function() {
bootApplication();

var actionId = Ember.$("#qunit-fixture a").data("ember-action");
var action = ActionManager.registeredActions[actionId];
var [ action ] = ActionManager.registeredActions[actionId];
var event = new Ember.$.Event("click");
action.handler(event);
});
Expand Down

0 comments on commit cb00d37

Please sign in to comment.