fix event handling for widget with multiple top level elements

This commit is contained in:
Michael Rawlings 2016-12-07 23:46:35 -08:00
parent 03c2e8de7e
commit 3388275787
4 changed files with 44 additions and 11 deletions

View File

@ -0,0 +1,14 @@
module.exports = {
getTemplateData: function(state, input) {
return {
};
},
init: function() {
this.buttonClickCalls = [];
},
handleButtonClick: function() {
this.buttonClickCalls.push(arguments);
}
};

View File

@ -0,0 +1,4 @@
<div w-bind>
<button ref="ok" type="button" onClick('handleButtonClick', 'ok')>OK</button>
<button ref="cancel" type="button" onClick('handleButtonClick', 'cancel')>Cancel</button>
</div>

View File

@ -0,0 +1,23 @@
var expect = require('chai').expect;
module.exports = function(helpers) {
var widget = helpers.mount(require('./index'), {});
expect(widget.buttonClickCalls.length).to.equal(0);
helpers.triggerClick(widget.getEl('ok'));
expect(widget.buttonClickCalls.length).to.equal(1);
expect(widget.buttonClickCalls[0][0]).to.equal('ok');
expect(widget.buttonClickCalls[0][1].stopPropagation).to.be.a('function');
expect(widget.buttonClickCalls[0][2].innerHTML).to.equal('OK');
helpers.triggerClick(widget.getEl('cancel'));
expect(widget.buttonClickCalls.length).to.equal(2);
expect(widget.buttonClickCalls[1][0]).to.equal('cancel');
expect(widget.buttonClickCalls[1][1].stopPropagation).to.be.a('function');
expect(widget.buttonClickCalls[1][2].innerHTML).to.equal('Cancel');
};

View File

@ -1,6 +1,7 @@
var _addEventListener = require('./addEventListener');
var updateManager = require('./update-manager');
var getObjectAttribute = require('./getObjectAttribute');
var widgetLookup = require('./lookup').widgets;
var attachBubbleEventListeners = function() {
var body = document.body;
@ -39,6 +40,7 @@ var attachBubbleEventListeners = function() {
do {
if ((target = getObjectAttribute(curNode, attrName))) {
var targetMethod = target[0];
var targetWidgetId = target[1];
var extraArgs;
@ -47,16 +49,7 @@ var attachBubbleEventListeners = function() {
extraArgs = target.slice(2);
}
var targetWidgetEl = document.getElementById(targetWidgetId);
if (!targetWidgetEl) {
// The target widget is not in the DOM anymore
// which can happen when the widget and its
// children are removed from the DOM while
// processing the event.
continue;
}
var targetWidget = targetWidgetEl.__widget;
var targetWidget = widgetLookup[targetWidgetId];
if (!targetWidget) {
throw new Error('Widget not found: ' + targetWidgetId);
@ -67,7 +60,6 @@ var attachBubbleEventListeners = function() {
throw new Error('Method not found on widget ' + targetWidget.id + ': ' + targetMethod);
}
// Invoke the widget method
if (extraArgs) {
targetFunc.apply(targetWidget, extraArgs.concat(event, curNode));