...
Also, since addons are not extending from a HTMLElement, addons cannot subscribe to events themselves. HTML events are only going upwards in the DOMTree, not downwards and/or to siblings.
...
If we want plug-ins for OpenSCD to be asynchronous accessible to each other, OpenSCD-Core should make use of a central event-bus.
Instead of dispatching an event on the plug-in itself, the plug-in can dispatch an event on the central event-bus. This will take care of the current problems we're facing:
Addons
Addons can listen to CustomEvents being caught by the OpenSCD HTML Element. This will solve the communication problem from a plug-in or addon to a different addon.
Plug-ins communicating between themselves are not solved by this solution.
Code Block |
---|
```ts |
...
export class EventBus implements EventTarget { |
...
private _eventListeners: Map<string, EventListenerOrEventListenerObject[]>; |
...
constructor() { |
...
this._eventListeners = new Map<string, EventListenerOrEventListenerObject[]>(); |
...
} |
...
addEventListener(type: string, callback: EventListenerOrEventListenerObject): void { |
...
if (!this._eventListeners.has(type)) { |
...
this._eventListeners.set(type, []); |
...
} |
...
this._eventListeners.get(type)!.push(callback); |
...
} |
...
...
dispatchEvent(event: Event): boolean { |
...
if (this._eventListeners.has(event.type)) { |
...
this._eventListeners |
...
.get(event.type) |
...
!.forEach((cb) => |
...
typeof cb === 'function' ? cb(event) : cb.handleEvent(event) |
...
); |
...
return true; |
...
} |
...
return false; |
...
} |
...
removeEventListener(type: string, callback: EventListenerOrEventListenerObject): void { |
...
if (this._eventListeners.has(type)) { |
...
this._eventListeners.set(type, this._eventListeners.get(type)!.filter((cb) => cb !== callback)); |
...
} |
...
} |
...
} |
...
``` |
Alternatives
Instead of the central EventBus, we can let plugins dispatch events on the plugin itself. If a plugin needs an event from another plugin, It can listen to an event being dispatched to Open-SCD Core
.
...
Due to WebApi restrictions, Events that are emitted by one of the plugins are only bubbling up directly (https://www.freecodecamp.org/news/event-bubbling-in-javascript/)
Drawio | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Pro's:
No new Code needs to be introduced
...
This is only working for HTMLElements (Plugins).
It is possible to stop the event from bubbling further inside a plugin. This means that a plugin can negate an event that should be handled by a different plugin. (Plugin A sends an event (that should be read by Plugin B), Plugin C is listening to this event and stops the event from going further (event.preventDefault()). Because of Plugin C, plugin B never gets the event).
Consequences
Implementing a central event-bus means that current OSCD plugins need some refactoring to dispatch events to the event-bus instead of dispatching events on itself.