Event-bus: Auto-forward across iframe and commsServer

This commit is contained in:
Tamius Han 2025-05-19 01:16:33 +02:00
parent a05eccce9e
commit a5f35248bd
4 changed files with 76 additions and 6 deletions

View File

@ -572,7 +572,17 @@ export default {
},
handleBusTunnelIn(payload) {
this.eventBus.send(payload.action, payload.config, payload.routingData);
this.eventBus.send(
payload.action,
payload.config,
{
...payload.context,
borderCrossings: {
...payload.context?.borderCrossings,
iframe: true
}
}
);
},
updateConfig() {

View File

@ -19,6 +19,10 @@ export interface EventBusContext {
frame?: any,
sourceFrame?: IframeData
forwardTo?: 'all' | 'active' | 'contentScript' | 'server' | 'sameOrigin' | 'popup' | 'all-frames',
};
borderCrossings?: {
commsServer?: boolean,
iframe?: boolean,
}
}
@ -29,6 +33,9 @@ export default class EventBus {
private disableTunnel: boolean = false;
private popupContext: any = {};
private iframeForwardingList: {iframe: any, fn: (action, payload, context?) => void}[] = [];
// private uiUri = window.location.href;
constructor(options?: {isUWServer?: boolean}) {
@ -83,6 +90,18 @@ export default class EventBus {
}
}
forwardToIframe(iframe: any, fn: (action: string, payload: any, context?: EventBusContext) => void) {
this.cancelIframeForwarding(iframe);
this.iframeForwardingList.push({iframe, fn});
}
cancelIframeForwarding(iframe: any) {
const existingForwarding = this.iframeForwardingList.findIndex((x: any) => x.iframe === iframe);
if (existingForwarding !== -1) {
this.iframeForwardingList.splice(existingForwarding, 1);
}
}
send(command: string, commandData: any, context?: EventBusContext) {
// execute commands we have subscriptions for
@ -96,8 +115,25 @@ export default class EventBus {
// CommsServer's job. EventBus does not have enough data for this decision.
// We do, however, have enough data to prevent backflow of messages that
// crossed CommsServer once already.
if (this.comms && context?.origin !== CommsOrigin.Server) {
if (this.comms && context?.origin !== CommsOrigin.Server && !context?.borderCrossings?.commsServer) {
this.comms.sendMessage({command, config: commandData, context}, context);
};
// call forwarding functions if they exist
if (!context?.borderCrossings?.iframe) {
for (const forwarding of this.iframeForwardingList) {
forwarding.fn(
command,
commandData,
{
...context,
borderCrossings: {
...context?.borderCrossings,
iframe: true
}
}
);
}
}
if (context?.stopPropagation) {

View File

@ -128,7 +128,7 @@ class CommsClient {
}
//#endregion
async sendMessage(message, context?: EventBusContext){
async sendMessage(message, context?: EventBusContext, borderCrossings?){
this.logger.info('sendMessage', ' <<< Sending message to background script:', message);
message = JSON.parse(JSON.stringify(message)); // vue quirk. We should really use vue store instead
@ -144,8 +144,11 @@ class CommsClient {
return port.postMessage(message);
}
}
// send to server
return chrome.runtime.sendMessage(null, message, null);
if (!context?.borderCrossings.commsServer) {
return chrome.runtime.sendMessage(null, message, null);
}
}
/**
@ -170,7 +173,10 @@ class CommsClient {
message.config,
{
comms,
origin: CommsOrigin.Server
origin: CommsOrigin.Server,
borderCrossings: {
commsServer: true
}
}
);
}

View File

@ -205,10 +205,18 @@ class UI {
document.addEventListener('mousemove', fn, true);
}
this.eventBus.forwardToIframe(
this.uiIframe,
(action, payload) => {
this.sendToIframe(action, payload, {})
}
);
this.rootDiv.appendChild(iframe);
}
unloadIframe() {
this.eventBus.cancelIframeForwarding(this.uiIframe);
window.removeEventListener('message', this.messageHandlerFn);
this.uiIframe?.remove();
delete this.uiIframe;
@ -416,7 +424,17 @@ class UI {
break;
case 'uw-bus-tunnel':
const busCommand = event.data.payload;
this.eventBus.send(busCommand.action, busCommand.config, busCommand.routingData);
this.eventBus.send(
busCommand.action,
busCommand.config,
{
...busCommand?.context,
borderCrossings: {
...busCommand?.context?.borderCrossings,
iframe: true,
}
}
);
break;
case 'uwui-get-role':
this.sendToIframeLowLevel('uwui-set-role', {role: this.isGlobal ? 'global' : 'player'});