ultrawidify/src/ext/lib/EventBus.ts

108 lines
2.8 KiB
TypeScript
Raw Normal View History

2021-10-26 22:19:41 +02:00
export interface EventBusCommand {
isGlobal?: boolean,
function: (commandConfig: any) => void | Promise<void>
}
export default class EventBus {
private commands: { [x: string]: EventBusCommand[]} = {};
2022-05-06 00:22:35 +02:00
private downstreamBuses: EventBus[] = [];
2021-10-26 22:19:41 +02:00
private upstreamBus?: EventBus;
2022-05-06 00:22:35 +02:00
setUpstreamBus(eventBus: EventBus, stopRecursing: boolean = false) {
this.upstreamBus = eventBus;
if (!stopRecursing) {
this.upstreamBus.addDownstreamBus(this, true);
}
}
unsetUpstreamBus(stopRecursing: boolean = false) {
if (!stopRecursing) {
this.upstreamBus.removeDownstreamBus(this, false);
}
this.upstreamBus = undefined;
}
2022-05-06 00:22:35 +02:00
addDownstreamBus(eventBus: EventBus, stopRecursing: boolean = false) {
if (!this.downstreamBuses.includes(eventBus)) {
this.downstreamBuses.push(eventBus);
if (!stopRecursing) {
eventBus.setUpstreamBus(this, true);
}
}
}
2021-10-26 22:19:41 +02:00
removeDownstreamBus(eventBus: EventBus, stopRecursing: boolean = false) {
this.downstreamBuses = this.downstreamBuses.filter(x => x !== eventBus);
if (!stopRecursing) {
eventBus.unsetUpstreamBus(true);
}
}
2021-10-26 22:19:41 +02:00
subscribe(commandString: string, command: EventBusCommand) {
if (!this.commands[commandString]) {
this.commands[commandString] = [command];
} else {
this.commands[commandString].push(command);
}
}
send(command: string, config: any, stopPropagation?: boolean) {
if (!this.commands ||!this.commands[command]) {
// ensure send is not being called for commands that we have no subscriptions for
return;
}
2021-10-26 22:19:41 +02:00
for (const eventBusCommand of this.commands[command]) {
eventBusCommand.function(config);
if (eventBusCommand.isGlobal && !stopPropagation) {
this.sendUpstream(command, config);
this.sendDownstream(command, config);
}
}
}
/**
* Send, but intended for sending commands from iframe to content scripts
* @param command
* @param config
*/
sendToTunnel(command: string, config: any) {
window.parent.postMessage(
{
action: 'uw-bus-tunnel',
payload: {action: command, config}
},
'*'
);
}
2021-10-26 22:19:41 +02:00
sendGlobal(command: string, config: any) {
2022-05-06 00:22:35 +02:00
this.send(command, config);
this.sendUpstream(command, config);
this.sendDownstream(command, config);
2021-10-26 22:19:41 +02:00
}
2022-05-06 00:22:35 +02:00
sendDownstream(command: string, config: any, sourceEventBus?: EventBus) {
for (const eventBus of this.downstreamBuses) {
if (eventBus !== sourceEventBus) {
eventBus.send(command, config);
eventBus.sendDownstream(command, config);
}
}
2021-10-26 22:19:41 +02:00
}
2022-05-06 00:22:35 +02:00
sendUpstream(command: string, config: any) {
if (this.upstreamBus) {
this.upstreamBus.send(command, config);
this.upstreamBus.sendUpstream(command, config);
this.upstreamBus.sendDownstream(command, config, this);
}
2021-10-26 22:19:41 +02:00
}
}