From 3388275787480fac976ed8162467437eb683fbb2 Mon Sep 17 00:00:00 2001 From: Michael Rawlings Date: Wed, 7 Dec 2016 23:46:35 -0800 Subject: [PATCH] fix event handling for widget with multiple top level elements --- .../component.js | 14 +++++++++++ .../index.marko | 4 ++++ .../test.js | 23 +++++++++++++++++++ widgets/event-delegation.js | 14 +++-------- 4 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/component.js create mode 100644 test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/index.marko create mode 100644 test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/test.js diff --git a/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/component.js b/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/component.js new file mode 100644 index 000000000..c8ac44b34 --- /dev/null +++ b/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/component.js @@ -0,0 +1,14 @@ +module.exports = { + getTemplateData: function(state, input) { + return { + }; + }, + + init: function() { + this.buttonClickCalls = []; + }, + + handleButtonClick: function() { + this.buttonClickCalls.push(arguments); + } +}; \ No newline at end of file diff --git a/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/index.marko b/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/index.marko new file mode 100644 index 000000000..d2482abc1 --- /dev/null +++ b/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/index.marko @@ -0,0 +1,4 @@ +
+ + +
\ No newline at end of file diff --git a/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/test.js b/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/test.js new file mode 100644 index 000000000..aec3a28eb --- /dev/null +++ b/test/autotests/widgets-browser/event-handler-dom-args-bubbling-multiple-top-level-elements/test.js @@ -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'); +}; \ No newline at end of file diff --git a/widgets/event-delegation.js b/widgets/event-delegation.js index 1f65a870a..811916917 100644 --- a/widgets/event-delegation.js +++ b/widgets/event-delegation.js @@ -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));