Skip to content

Commit

Permalink
Allow other event args to pass through
Browse files Browse the repository at this point in the history
And finish writing tests
  • Loading branch information
Jon Q committed Dec 17, 2018
1 parent 2a36f0d commit ff370ce
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 13 deletions.
119 changes: 119 additions & 0 deletions src/__tests__/createListeners.test.js
Expand Up @@ -9,3 +9,122 @@ test('Can find an item from an element', () => {

expect(listeners.find(mockElement)).toBe(mockListener)
})

test('Adds events to element', () => {
const spy = jest.fn()
const mockElement = document.createElement('div')
const listeners = createListeners()
const noop = () => {}

mockElement.scrollTop = 50
listeners.addEventListener(mockElement, noop)

expect(listeners.find(mockElement)).toBeTruthy()

mockElement.addEventListener('scrollUp', spy)
mockElement.scrollTop = 0
mockElement.dispatchEvent(new Event('scroll'))

expect(spy).toHaveBeenCalled()
})

test('Removes events to element', () => {
const spy = jest.fn()
const mockElement = document.createElement('div')
const listeners = createListeners()
const noop = () => {}

mockElement.scrollTop = 50
listeners.addEventListener(mockElement, noop)

expect(listeners.find(mockElement)).toBeTruthy()

mockElement.addEventListener('scrollUp', spy)

listeners.removeEventListener(mockElement, noop)
mockElement.removeEventListener('scrollUp', spy)

mockElement.scrollTop = 0
mockElement.dispatchEvent(new Event('scroll'))

expect(spy).not.toHaveBeenCalled()
})

test('Adds multiple events to element', () => {
const spy = jest.fn()
const spy2 = jest.fn()
const mockElement = document.createElement('div')
const listeners = createListeners()
const noop = () => {}

mockElement.scrollTop = 50
listeners.addEventListener(mockElement, noop)
listeners.addEventListener(mockElement, noop)

expect(listeners.find(mockElement)).toBeTruthy()

mockElement.addEventListener('scrollUp', spy)
mockElement.addEventListener('scrollUp', spy2)
mockElement.scrollTop = 0
mockElement.dispatchEvent(new Event('scroll'))

expect(spy).toHaveBeenCalled()
expect(spy2).toHaveBeenCalled()
})

test('Can retrieve state from listeners', () => {
const mockElement = document.createElement('div')
const listeners = createListeners()
const noop = () => {}

mockElement.scrollTop = 50
listeners.addEventListener(mockElement, noop)

expect(listeners.getState().length).toBe(1)
})

test('Can clear state from listeners', () => {
const mockElement = document.createElement('div')
const listeners = createListeners()
const noop = () => {}

mockElement.scrollTop = 50
listeners.addEventListener(mockElement, noop)

expect(listeners.getState().length).toBe(1)

listeners.clear()

expect(listeners.getState().length).toBe(0)
})

test('Removes listener if element is removed from DOM', () => {
const mockElement = document.createElement('div')
const listeners = createListeners()
const noop = () => {}

document.body.appendChild(mockElement)

listeners.addEventListener(mockElement, noop)
expect(listeners.getState().length).toBe(1)

mockElement.parentElement.removeChild(mockElement)
listeners.removeEventListener(mockElement, noop)

expect(listeners.getState().length).toBe(0)
})

test('Does not remove listener if element stays in DOM', () => {
const mockElement = document.createElement('div')
const listeners = createListeners()
const noop = () => {}

document.body.appendChild(mockElement)

listeners.addEventListener(mockElement, noop)
expect(listeners.getState().length).toBe(1)

listeners.removeEventListener(mockElement, noop)

expect(listeners.getState().length).toBe(1)
})
4 changes: 2 additions & 2 deletions src/createEventListeners.js
Expand Up @@ -13,7 +13,7 @@ function createEventListeners() {
const addEvent = addEventListenerRef.bind(this)
// Adding the custom scroll event
if (SUPPORTED_EVENTS.includes(event)) {
listeners.addEventListener(this, handler)
listeners.addEventListener(this, handler, ...args)
}
// Execute the default addEventHandler function
return addEvent(event, handler, ...args)
Expand All @@ -23,7 +23,7 @@ function createEventListeners() {
const removeEvent = removeEventListenerRef.bind(this)
// Removing the custom scroll event
if (SUPPORTED_EVENTS.includes(event)) {
listeners.removeEventListener(this, handler)
listeners.removeEventListener(this, handler, ...args)
}
// Execute the default removeEventHandler function
return removeEvent(event, handler, ...args)
Expand Down
23 changes: 12 additions & 11 deletions src/createListeners.js
Expand Up @@ -11,18 +11,26 @@ function Listeners() {
state.push(listener)
}

function addEventListener(element, handler) {
function addEventListener(element, handler, ...args) {
if (!find(element)) {
const listener = new ScrollListener(element, handler)
element.addEventListener('scroll', listener.dispatch.bind(listener))
element.addEventListener(
'scroll',
listener.dispatch.bind(listener),
...args,
)
add(listener)
}
}

function removeEventListener(element) {
function removeEventListener(element, handler, ...args) {
const listener = find(element)
const el = listener.element
element.removeEventListener('scroll', listener.dispatch.bind(listener))
element.removeEventListener(
'scroll',
listener.dispatch.bind(listener),
...args,
)
// Remove reference to DOM node, if it no longer exists
if (!el || !el.ownerDocument.contains(el)) {
remove(listener)
Expand All @@ -33,12 +41,6 @@ function Listeners() {
return state.find(i => i.element === element)
}

function dispatch() {
for (let i = 0, len = state.length; i < len; i++) {
state[i].dispatch()
}
}

function getState() {
return state
}
Expand All @@ -55,7 +57,6 @@ function Listeners() {
add,
addEventListener,
clear,
dispatch,
find,
getState,
remove,
Expand Down

0 comments on commit ff370ce

Please sign in to comment.