Skip to content

Commit

Permalink
fix(EventStack): fix erroneous removal of non-empty EventPool (#2992)
Browse files Browse the repository at this point in the history
* docs(EventStack): fix a numbering mistake

* fix(EventStack): don't remove eventPool on unsub if not necessary

Closes #2905

* rename handlers in tests

Signed-off-by: Oleksandr Fediashov <[email protected]>

* refactor hasHandlers

Signed-off-by: Oleksandr Fediashov <[email protected]>
  • Loading branch information
mic4ael authored and levithomason committed Jul 14, 2018
1 parent 972b999 commit a9e0aae
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 15 deletions.
9 changes: 3 additions & 6 deletions src/lib/eventStack/EventPool.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,10 @@ export default class EventPool {
}

/**
* @param {String} eventType
* @return {Boolean}
*/
hasHandlers(eventType) {
const handlerSet = this.handlerSets.get(eventType)

if (handlerSet) return handlerSet.hasHandlers()
return false
hasHandlers() {
return this.handlerSets.size > 0
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/lib/eventStack/EventTarget.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ export default class EventTarget {
if (pool) {
const newPool = pool.removeHandlers(eventType, eventHandlers)

if (newPool.hasHandlers(eventType)) {
this.removeTargetHandler(eventType)
if (newPool.hasHandlers()) {
this.pools.set(poolName, newPool)
} else {
this.removeTargetHandler(eventType)
this.pools.delete(poolName)
}

this.removeTargetHandler(eventType)

if (this.pools.size > 0) this.addTargetHandler(eventType)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/eventStack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

The `EventStack` solves two design problems:
1. Reduces the number of connected listeners to DOM nodes compared to `element.addListener()`.
1. Respects event ordering. Example, two modals are open and you only want the top modal to close on document click.
2. Respects event ordering. Example, two modals are open and you only want the top modal to close on document click.

## EventStack

Expand Down
10 changes: 6 additions & 4 deletions test/specs/lib/eventStack/EventPool-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,16 @@ describe('EventPool', () => {
})

describe('hasHandlers', () => {
const pool = EventPool.createByType('default', 'click', [() => {}])

it('returns "true" if has handlers', () => {
pool.hasHandlers('click').should.have.be.true()
const pool = EventPool.createByType('default', 'click', [() => {}])

pool.hasHandlers().should.have.be.true()
})

it('returns "false" if has not handlers', () => {
pool.hasHandlers('mousedown').should.have.be.false()
const pool = new EventPool('default', new Map())

pool.hasHandlers().should.have.be.false()
})
})

Expand Down
16 changes: 15 additions & 1 deletion test/specs/lib/eventStack/EventStack-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('EventStack', () => {
handler.should.have.been.calledOnce()
})

it('unsubscribes but leaves eventTarget if it contains handlers', () => {
it('unsubscribes and leaves eventTarget if it contains handlers', () => {
const clickHandler = sandbox.spy()
const keyHandler = sandbox.spy()

Expand All @@ -104,6 +104,20 @@ describe('EventStack', () => {
keyHandler.should.have.not.been.called()
})

it('unsubscribes and leaves an eventPool if contains handlers', () => {
const firstHandler = sandbox.spy()
const secondHandler = sandbox.spy()

eventStack.sub('click', firstHandler)
eventStack.unsub('mouseup', firstHandler)
eventStack.sub('click', secondHandler)

domEvent.click(document)

firstHandler.should.have.been.calledOnce()
secondHandler.should.have.been.calledOnce()
})

it('unsubscribes from same event multiple times', () => {
const handler = sandbox.spy()

Expand Down

0 comments on commit a9e0aae

Please sign in to comment.