UNPKG

octobercms

Version:

AJAX Framework for October CMS

107 lines (91 loc) 3.56 kB
import { EventListener } from "./event-listener"; export class Dispatcher { constructor(application) { this.application = application; this.eventListenerMaps = new Map(); this.started = false; } start() { if (!this.started) { this.started = true; this.eventListeners.forEach((eventListener) => eventListener.connect()); } } stop() { if (this.started) { this.started = false; this.eventListeners.forEach((eventListener) => eventListener.disconnect()); } } get eventListeners() { return Array.from(this.eventListenerMaps.values()).reduce((listeners, map) => listeners.concat(Array.from(map.values())), []); } // Binding observer delegate bindingConnected(binding) { this.fetchEventListenerForBinding(binding).bindingConnected(binding); } bindingDisconnected(binding, clearEventListeners = false) { this.fetchEventListenerForBinding(binding).bindingDisconnected(binding); if (clearEventListeners) this.clearEventListenersForBinding(binding); } // Error handling handleError(error, message, detail = {}) { this.application.handleError(error, `Error ${message}`, detail); } clearEventListenersForBinding(binding) { const eventListener = this.fetchEventListenerForBinding(binding); if (!eventListener.hasBindings()) { eventListener.disconnect(); this.removeMappedEventListenerFor(binding); } } removeMappedEventListenerFor(binding) { const { eventTarget, eventName, eventOptions } = binding; const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget); const cacheKey = this.cacheKey(eventName, eventOptions); eventListenerMap.delete(cacheKey); if (eventListenerMap.size == 0) { this.eventListenerMaps.delete(eventTarget); } } fetchEventListenerForBinding(binding) { const { eventTarget, eventName, eventOptions } = binding; return this.fetchEventListener(eventTarget, eventName, eventOptions); } fetchEventListener(eventTarget, eventName, eventOptions) { const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget); const cacheKey = this.cacheKey(eventName, eventOptions); let eventListener = eventListenerMap.get(cacheKey); if (!eventListener) { eventListener = this.createEventListener(eventTarget, eventName, eventOptions); eventListenerMap.set(cacheKey, eventListener); } return eventListener; } createEventListener(eventTarget, eventName, eventOptions) { const eventListener = new EventListener(eventTarget, eventName, eventOptions); if (this.started) { eventListener.connect(); } return eventListener; } fetchEventListenerMapForEventTarget(eventTarget) { let eventListenerMap = this.eventListenerMaps.get(eventTarget); if (!eventListenerMap) { eventListenerMap = new Map(); this.eventListenerMaps.set(eventTarget, eventListenerMap); } return eventListenerMap; } cacheKey(eventName, eventOptions) { const parts = [eventName]; Object.keys(eventOptions) .sort() .forEach((key) => { parts.push(`${eventOptions[key] ? "" : "!"}${key}`); }); return parts.join(":"); } }