@semantic-ui-react/event-stack
Version:
Issues mentioned in `README` should be solved by other approaches: - `.addEventListener()` is blazing fast and is not a real performance issue - to solve issues with ordering in case when regular DOM event propogation is not available consider to use thi
78 lines (63 loc) • 2.19 kB
text/typescript
import EventPool from './EventPool'
import { EventListeners, TargetElement } from '../types'
export default class EventTarget {
private readonly handlers: Map<String, Function> = new Map()
private readonly pools: Map<String, EventPool> = new Map()
private readonly target: TargetElement
public constructor(target: TargetElement) {
this.target = target
}
public addHandlers(poolName: string, eventType: string, eventHandlers: EventListeners) {
if (this.pools.has(poolName)) {
const eventPool = this.pools.get(poolName) as EventPool
this.pools.set(poolName, eventPool.addHandlers(eventType, eventHandlers))
} else {
this.pools.set(poolName, EventPool.createByType(poolName, eventType, eventHandlers))
}
if (!this.handlers.has(eventType)) {
this.addTargetHandler(eventType)
}
}
public hasHandlers(): boolean {
return this.handlers.size > 0
}
public removeHandlers(poolName: string, eventType: string, eventHandlers: EventListeners) {
if (!this.pools.has(poolName)) {
return
}
const pool = this.pools.get(poolName) as EventPool
const newPool = pool.removeHandlers(eventType, eventHandlers)
if (newPool.hasHandlers()) {
this.pools.set(poolName, newPool)
} else {
this.pools.delete(poolName)
}
let hasHandlers = false;
this.pools.forEach(pool => hasHandlers = hasHandlers || pool.hasHandlers(eventType))
if (!hasHandlers) {
this.removeTargetHandler(eventType)
}
}
private createEmitter = (eventType: string): EventListener => {
return (event: Event) => {
this.pools.forEach(pool => {
pool.dispatchEvent(eventType, event)
})
}
}
private addTargetHandler(eventType: string) {
const handler = this.createEmitter(eventType)
this.handlers.set(eventType, handler)
this.target.addEventListener(eventType, handler, true)
}
private removeTargetHandler(eventType: string) {
if (this.handlers.has(eventType)) {
this.target.removeEventListener(
eventType,
this.handlers.get(eventType) as EventListener,
true,
)
this.handlers.delete(eventType)
}
}
}