UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

80 lines (79 loc) 2.31 kB
import { Component } from "../../../lib/Component"; const listeners = new WeakMap(); export class EventedComponent extends Component { constructor() { super(...arguments); this.evented = true; } get events() { if (!listeners.has(this)) { listeners.set(this, new Map()); } return listeners.get(this); } unmount() { listeners.delete(this); super.unmount(); } handleEvent(_) { // noop } listenEvents(events, cbOrObject = this) { const unsubs = events.map((eventName) => { return this.addEventListener(eventName, cbOrObject); }); return unsubs; } addEventListener(type, cbOrObject) { const cbs = this.events.get(type) || new Set(); cbs.add(cbOrObject); this.events.set(type, cbs); return () => this.removeEventListener(type, cbOrObject); } removeEventListener(type, cbOrObject) { const cbs = this.events.get(type); if (cbs) { cbs.delete(cbOrObject); } } _fireEvent(cmp, event) { const handlers = listeners.get(cmp)?.get?.(event.type); handlers?.forEach((cb) => { if (typeof cb === "function") { cb(event); } else if (cb instanceof Component && "handleEvent" in cb && typeof cb.handleEvent === "function") { cb.handleEvent?.(event); } }); } dispatchEvent(event) { const bubbles = event.bubbles || false; if (bubbles) { return this._dipping(this, event); } else if (this._hasListener(this, event.type)) { this._fireEvent(this, event); return false; } return false; } _dipping(startParent, event) { let stopPropagation = false; let parent = startParent; event.stopPropagation = () => { stopPropagation = true; }; do { this._fireEvent(parent, event); if (stopPropagation) { return false; } parent = parent.getParent(); } while (parent); return true; } _hasListener(comp, type) { return listeners.get(comp)?.has?.(type); } }