diff --git a/CHANGES.md b/CHANGES.md index 04f906719e49..49c550731790 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,10 +1,12 @@ Change Log ========== + ### 1.38 - 2017-10-02 * Added ability to add an animation to `ModelAnimationCollection` by its index. [#5815](https://github.com/AnalyticalGraphicsInc/cesium/pull/5815) * Fixed a bug in `ModelAnimationCollection` that caused adding an animation by its name to throw an error. [#5815](https://github.com/AnalyticalGraphicsInc/cesium/pull/5815) * Zoom about mouse now maintains camera heading, pitch, and roll [#4639](https://github.com/AnalyticalGraphicsInc/cesium/pull/5603) +* Fixed removing multiple event listeners within event callbacks. [#5827](https://github.com/AnalyticalGraphicsInc/cesium/issues/5827) ### 1.37 - 2017-09-01 diff --git a/Source/Core/Event.js b/Source/Core/Event.js index 4244fca65768..2f5b6b810add 100644 --- a/Source/Core/Event.js +++ b/Source/Core/Event.js @@ -120,6 +120,10 @@ define([ return false; }; + function compareNumber(a,b) { + return b - a; + } + /** * Raises the event by calling each registered listener with all supplied arguments. * @@ -146,12 +150,15 @@ define([ //Actually remove items removed in removeEventListener. var toRemove = this._toRemove; length = toRemove.length; - for (i = 0; i < length; i++) { - var index = toRemove[i]; - listeners.splice(index, 1); - scopes.splice(index, 1); + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; } - toRemove.length = 0; this._insideRaiseEvent = false; }; diff --git a/Specs/Core/EventSpec.js b/Specs/Core/EventSpec.js index 944a04f61a2e..1134fe10d034 100644 --- a/Specs/Core/EventSpec.js +++ b/Specs/Core/EventSpec.js @@ -45,7 +45,7 @@ defineSuite([ expect(spyListener).not.toHaveBeenCalled(); }); - it('can remove from withing a callback', function() { + it('can remove from within a callback', function() { var doNothing = function(evt) { }; @@ -67,6 +67,25 @@ defineSuite([ expect(event.numberOfListeners).toEqual(0); }); + it('can remove multiple listeners within a callback', function() { + var removeEvent0 = event.addEventListener(function() { removeEvent0(); }); + event.addEventListener(function() {}); + var removeEvent2 = event.addEventListener(function() { removeEvent2(); }); + event.addEventListener(function() {}); + var removeEvent4 = event.addEventListener(function() { removeEvent4(); }); + event.addEventListener(function() {}); + var removeEvent6 = event.addEventListener(function() { removeEvent6(); }); + event.addEventListener(function() {}); + var removeEvent8 = event.addEventListener(function() { removeEvent8(); }); + event.addEventListener(function() {}); + + expect(event.numberOfListeners).toEqual(10); + event.raiseEvent(); + expect(event.numberOfListeners).toEqual(5); + event.raiseEvent(); + expect(event.numberOfListeners).toEqual(5); + }); + it('addEventListener and removeEventListener works with same function of different scopes', function() { var Scope = function() { this.timesCalled = 0;