diff --git a/src/ol/events/Target.js b/src/ol/events/Target.js index dbc845d0dc..ff40285950 100644 --- a/src/ol/events/Target.js +++ b/src/ol/events/Target.js @@ -39,22 +39,22 @@ class Target extends Disposable { this.eventTarget_ = opt_target; /** + * @name pendingRemovals_ * @private * @type {!Object} */ - this.pendingRemovals_ = {}; /** + * @name dispatching_ * @private * @type {!Object} */ - this.dispatching_ = {}; /** + * @name listeners_ * @private * @type {!Object>} */ - this.listeners_ = {}; } /** @@ -65,11 +65,8 @@ class Target extends Disposable { if (!type || !listener) { return; } - let listeners = this.listeners_[type]; - if (!listeners) { - listeners = []; - this.listeners_[type] = listeners; - } + let listeners = this.listeners_ || (this.listeners_ = {}); + listeners = listeners[type] || (listeners[type] = []); if (listeners.indexOf(listener) === -1) { listeners.push(listener); } @@ -92,14 +89,17 @@ class Target extends Disposable { if (!evt.target) { evt.target = this.eventTarget_ || this; } - const listeners = this.listeners_[type]; + const listeners = this.listeners_ && this.listeners_[type]; let propagate; if (listeners) { - if (!(type in this.dispatching_)) { - this.dispatching_[type] = 0; - this.pendingRemovals_[type] = 0; + const dispatching = this.dispatching_ || (this.dispatching_ = {}); + const pendingRemovals = + this.pendingRemovals_ || (this.pendingRemovals_ = {}); + if (!(type in dispatching)) { + dispatching[type] = 0; + pendingRemovals[type] = 0; } - ++this.dispatching_[type]; + ++dispatching[type]; for (let i = 0, ii = listeners.length; i < ii; ++i) { if ('handleEvent' in listeners[i]) { propagate = /** @type {import("../events.js").ListenerObject} */ (listeners[ @@ -115,14 +115,14 @@ class Target extends Disposable { break; } } - --this.dispatching_[type]; - if (this.dispatching_[type] === 0) { - let pendingRemovals = this.pendingRemovals_[type]; - delete this.pendingRemovals_[type]; - while (pendingRemovals--) { + --dispatching[type]; + if (dispatching[type] === 0) { + let pr = pendingRemovals[type]; + delete pendingRemovals[type]; + while (pr--) { this.removeEventListener(type, VOID); } - delete this.dispatching_[type]; + delete dispatching[type]; } return propagate; } @@ -132,7 +132,7 @@ class Target extends Disposable { * Clean up. */ disposeInternal() { - clear(this.listeners_); + this.listeners_ && clear(this.listeners_); } /** @@ -140,10 +140,10 @@ class Target extends Disposable { * order that they will be called in. * * @param {string} type Type. - * @return {Array} Listeners. + * @return {Array|undefined} Listeners. */ getListeners(type) { - return this.listeners_[type]; + return this.listeners_ && this.listeners_[type]; } /** @@ -152,6 +152,9 @@ class Target extends Disposable { * @return {boolean} Has listeners. */ hasListener(opt_type) { + if (!this.listeners_) { + return false; + } return opt_type ? opt_type in this.listeners_ : Object.keys(this.listeners_).length > 0; @@ -162,11 +165,11 @@ class Target extends Disposable { * @param {import("../events.js").Listener} listener Listener. */ removeEventListener(type, listener) { - const listeners = this.listeners_[type]; + const listeners = this.listeners_ && this.listeners_[type]; if (listeners) { const index = listeners.indexOf(listener); if (index !== -1) { - if (type in this.pendingRemovals_) { + if (this.pendingRemovals_ && type in this.pendingRemovals_) { // make listener a no-op, and remove later in #dispatchEvent() listeners[index] = VOID; ++this.pendingRemovals_[type]; diff --git a/test/spec/ol/events/eventtarget.test.js b/test/spec/ol/events/eventtarget.test.js index 542b38ccea..48ef6c9b3a 100644 --- a/test/spec/ol/events/eventtarget.test.js +++ b/test/spec/ol/events/eventtarget.test.js @@ -24,9 +24,6 @@ describe('ol.events.EventTarget', function () { expect(eventTarget).to.be.a(EventTarget); expect(eventTarget).to.be.a(Disposable); }); - it('creates an empty listeners_ object', function () { - expect(Object.keys(eventTarget.listeners_)).to.have.length(0); - }); it('accepts a default target', function (done) { const defaultTarget = {}; const target = new EventTarget(defaultTarget); @@ -41,11 +38,11 @@ describe('ol.events.EventTarget', function () { describe('#hasListener', function () { it('reports any listeners when called without argument', function () { expect(eventTarget.hasListener()).to.be(false); - eventTarget.listeners_['foo'] = [function () {}]; + eventTarget.addEventListener('foo', function () {}); expect(eventTarget.hasListener()).to.be(true); }); it('reports listeners for the type passed as argument', function () { - eventTarget.listeners_['foo'] = [function () {}]; + eventTarget.addEventListener('foo', function () {}); expect(eventTarget.hasListener('foo')).to.be(true); expect(eventTarget.hasListener('bar')).to.be(false); });