@gravity-ui/graph
Version:
Modern graph editor component
80 lines (79 loc) • 2.31 kB
JavaScript
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);
}
}