From 020998c0365bea620ec3adef9409a70a5fa5da2b Mon Sep 17 00:00:00 2001 From: Gheric Speiginer Date: Fri, 15 Sep 2017 14:28:56 -0400 Subject: [PATCH] Fixed removing multiple event listeners within event callbacks #5827 --- CHANGES.md | 1 + Source/Core/Event.js | 17 ++++++++++++----- Specs/Core/EventSpec.js | 21 ++++++++++++++++++++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 61dd099c1a7b..ec962294b6c6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ Change Log * Fixed CZML processing of `velocityReference` within an interval. [#5738](https://github.com/AnalyticalGraphicsInc/cesium/issues/5738) * Zoom about mouse now maintains camera heading, pitch, and roll [#4639](https://github.com/AnalyticalGraphicsInc/cesium/pull/5603) * Fixed a bug in `PolylineCollection` preventing the display of more than 16K points in a single collection [#5538](https://github.com/AnalyticalGraphicsInc/cesium/pull/5782) +* 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;