From 03fa49f02773794ca543f8f478a8c11c959a9ce4 Mon Sep 17 00:00:00 2001 From: Chris Chua Date: Sun, 24 Nov 2013 14:40:46 -0800 Subject: [PATCH] fix(jqLite): Support unbind self within handler If an event handler unbinds itself, the next event handler on the same event and element doesn't get executed. This works fine in jQuery, and since jqLite doesn't support .one, this might be a common use case. --- src/jqLite.js | 5 ++++- test/jqLiteSpec.js | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/jqLite.js b/src/jqLite.js index 218efe244be1..bffb047b46ab 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -631,7 +631,10 @@ function createEventHandler(element, events) { return event.defaultPrevented || event.returnValue === false; }; - forEach(events[type || event.type], function(fn) { + // Copy event handlers in case event handlers array is modified during execution. + var eventHandlersCopy = shallowCopy(events[type || event.type] || []); + + forEach(eventHandlersCopy, function(fn) { fn.call(element, event); }); diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js index 02a17df81679..5b73d0f4d99d 100644 --- a/test/jqLiteSpec.js +++ b/test/jqLiteSpec.js @@ -1099,6 +1099,28 @@ describe('jqLite', function() { }); + it('should deregister specific listener within the listener and call subsequent listeners', function() { + var aElem = jqLite(a), + clickOnceSpy = jasmine.createSpy('clickOnce'), + clickSpy = jasmine.createSpy('click'), + clickOnceListener = function () { + aElem.off('click', clickOnceListener); + return clickOnceSpy(); + }; + + aElem.on('click', clickOnceListener); + aElem.on('click', clickSpy); + + browserTrigger(a, 'click'); + expect(clickOnceSpy).toHaveBeenCalledOnce(); + expect(clickSpy).toHaveBeenCalledOnce(); + + browserTrigger(a, 'click'); + expect(clickOnceSpy).toHaveBeenCalledOnce(); + expect(clickSpy.callCount).toBe(2); + }); + + it('should deregister specific listener for multiple types separated by spaces', function() { var aElem = jqLite(a), masterSpy = jasmine.createSpy('master'),