From 8a27abae896de3c4d94c407e8bb381e099d2d7f7 Mon Sep 17 00:00:00 2001 From: Chris Chua Date: Sat, 25 Jan 2014 11:43:16 -0800 Subject: [PATCH] fix(jqLite): triggerHandler support unbind self Fixes .one if the event is invoked from triggerHandler. Closes #5984 --- src/jqLite.js | 6 ++++-- test/jqLiteSpec.js | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/jqLite.js b/src/jqLite.js index 9d342bfb..1fe2e4a0 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -948,7 +948,9 @@ forEach({ clone: jqLiteClone, triggerHandler: function(element, eventName, eventData) { - var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName]; + // Copy event handlers in case event handlers array is modified during execution. + var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName], + eventFnsCopy = shallowCopy(eventFns || []); eventData = eventData || []; @@ -962,7 +964,7 @@ forEach({ stopPropagation: noop }]; - forEach(eventFns, function(fn) { + forEach(eventFnsCopy, function(fn) { fn.apply(element, event.concat(eventData)); }); } diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js index 3124b47a..942e0ead 100644 --- a/test/jqLiteSpec.js +++ b/test/jqLiteSpec.js @@ -1743,6 +1743,26 @@ describe('jqLite', function() { event.preventDefault(); expect(event.isDefaultPrevented()).toBe(true); }); + + + it('should support handlers that deregister themselves', function() { + var element = jqLite('poke'), + clickSpy = jasmine.createSpy('click'), + clickOnceSpy = jasmine.createSpy('clickOnce').andCallFake(function() { + element.off('click', clickOnceSpy); + }); + + element.on('click', clickOnceSpy); + element.on('click', clickSpy); + + element.triggerHandler('click'); + expect(clickOnceSpy).toHaveBeenCalledOnce(); + expect(clickSpy).toHaveBeenCalledOnce(); + + element.triggerHandler('click'); + expect(clickOnceSpy).toHaveBeenCalledOnce(); + expect(clickSpy.callCount).toBe(2); + }); });