Merge remote-tracking branch 'remotes/workadventure-main/develop' into menu-command-api

This commit is contained in:
jonny 2021-05-10 09:54:39 +02:00
commit 4758820aa4
3 changed files with 122 additions and 70 deletions

View File

@ -1,7 +1,59 @@
export interface IframeEvent {
type: string;
data: unknown; import { ButtonClickedEvent } from './ButtonClickedEvent';
import { ChatEvent } from './ChatEvent';
import { ClosePopupEvent } from './ClosePopupEvent';
import { EnterLeaveEvent } from './EnterLeaveEvent';
import { GoToPageEvent } from './GoToPageEvent';
import { MenuItemClickedEvent } from './MenuItemClickedEvent';
import { MenuItemRegisterEvent } from './MenuItemRegisterEvent';
import { OpenCoWebSiteEvent } from './OpenCoWebSiteEvent';
import { OpenPopupEvent } from './OpenPopupEvent';
import { OpenTabEvent } from './OpenTabEvent';
import { UserInputChatEvent } from './UserInputChatEvent';
export interface TypedMessageEvent<T> extends MessageEvent {
data: T
}
export type IframeEventMap = {
//getState: GameStateEvent,
// updateTile: UpdateTileEvent
registerMenuCommand: MenuItemRegisterEvent
chat: ChatEvent,
openPopup: OpenPopupEvent
closePopup: ClosePopupEvent
openTab: OpenTabEvent
goToPage: GoToPageEvent
openCoWebSite: OpenCoWebSiteEvent
closeCoWebSite: null
disablePlayerControl: null
restorePlayerControl: null
displayBubble: null
removeBubble: null
}
export interface IframeEvent<T extends keyof IframeEventMap> {
type: T;
data: IframeEventMap[T];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isIframeEventWrapper = (event: any): event is IframeEvent<keyof IframeEventMap> => typeof event.type === 'string';
export interface IframeResponseEventMap {
userInputChat: UserInputChatEvent
enterEvent: EnterLeaveEvent
leaveEvent: EnterLeaveEvent
buttonClickedEvent: ButtonClickedEvent
menuItemClicked: MenuItemClickedEvent
// gameState: GameStateEvent
}
export interface IframeResponseEvent<T extends keyof IframeResponseEventMap> {
type: T;
data: IframeResponseEventMap[T];
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isIframeEventWrapper = (event: any): event is IframeEvent => typeof event.type === 'string'; export const isIframeResponseEventWrapper = (event: { type?: string }): event is IframeResponseEvent<keyof IframeResponseEventMap> => typeof event.type === 'string';

View File

@ -1,7 +1,5 @@
import { Subject } from "rxjs"; import { Subject } from "rxjs";
import { ChatEvent, isChatEvent } from "./Events/ChatEvent"; import { ChatEvent, isChatEvent } from "./Events/ChatEvent";
import {IframeEvent, isIframeEventWrapper} from "./Events/IframeEvent";
import {UserInputChatEvent} from "./Events/UserInputChatEvent";
import * as crypto from "crypto"; import * as crypto from "crypto";
import { HtmlUtils } from "../WebRtc/HtmlUtils"; import { HtmlUtils } from "../WebRtc/HtmlUtils";
import { EnterLeaveEvent } from "./Events/EnterLeaveEvent"; import { EnterLeaveEvent } from "./Events/EnterLeaveEvent";
@ -12,6 +10,8 @@ import {ClosePopupEvent, isClosePopupEvent} from "./Events/ClosePopupEvent";
import { scriptUtils } from "./ScriptUtils"; import { scriptUtils } from "./ScriptUtils";
import { GoToPageEvent, isGoToPageEvent } from "./Events/GoToPageEvent"; import { GoToPageEvent, isGoToPageEvent } from "./Events/GoToPageEvent";
import { isOpenCoWebsite, OpenCoWebSiteEvent } from "./Events/OpenCoWebSiteEvent"; import { isOpenCoWebsite, OpenCoWebSiteEvent } from "./Events/OpenCoWebSiteEvent";
import { IframeEventMap, IframeEvent, IframeResponseEvent, IframeResponseEventMap, isIframeEventWrapper, TypedMessageEvent } from "./Events/IframeEvent";
import { UserInputChatEvent } from "./Events/UserInputChatEvent";
import { isMenuItemRegisterEvent } from './Events/MenuItemRegisterEvent'; import { isMenuItemRegisterEvent } from './Events/MenuItemRegisterEvent';
import { MenuItemClickedEvent } from './Events/MenuItemClickedEvent'; import { MenuItemClickedEvent } from './Events/MenuItemClickedEvent';
@ -60,7 +60,7 @@ class IframeListener {
private readonly scripts = new Map<string, HTMLIFrameElement>(); private readonly scripts = new Map<string, HTMLIFrameElement>();
init() { init() {
window.addEventListener("message", (message) => { window.addEventListener("message", (message: TypedMessageEvent<IframeEvent<keyof IframeEventMap>>) => {
// Do we trust the sender of this message? // Do we trust the sender of this message?
// Let's only accept messages from the iframe that are allowed. // Let's only accept messages from the iframe that are allowed.
// Note: maybe we could restrict on the domain too for additional security (in case the iframe goes to another domain). // Note: maybe we could restrict on the domain too for additional security (in case the iframe goes to another domain).
@ -246,7 +246,7 @@ class IframeListener {
/** /**
* Sends the message... to all allowed iframes. * Sends the message... to all allowed iframes.
*/ */
private postMessage(message: IframeEvent) { private postMessage(message: IframeResponseEvent<keyof IframeResponseEventMap>) {
for (const iframe of this.iframes) { for (const iframe of this.iframes) {
iframe.contentWindow?.postMessage(message, '*'); iframe.contentWindow?.postMessage(message, '*');
} }

View File

@ -1,5 +1,5 @@
import {ChatEvent, isChatEvent} from "./Api/Events/ChatEvent"; import { ChatEvent } from "./Api/Events/ChatEvent";
import {isIframeEventWrapper} from "./Api/Events/IframeEvent"; import { isIframeResponseEventWrapper } from "./Api/Events/IframeEvent";
import { isUserInputChatEvent, UserInputChatEvent } from "./Api/Events/UserInputChatEvent"; import { isUserInputChatEvent, UserInputChatEvent } from "./Api/Events/UserInputChatEvent";
import { Subject } from "rxjs"; import { Subject } from "rxjs";
import { EnterLeaveEvent, isEnterLeaveEvent } from "./Api/Events/EnterLeaveEvent"; import { EnterLeaveEvent, isEnterLeaveEvent } from "./Api/Events/EnterLeaveEvent";
@ -218,9 +218,9 @@ window.addEventListener('message', message => {
const payload = message.data; const payload = message.data;
console.log(payload); console.debug(payload);
if (isIframeEventWrapper(payload)) { if (isIframeResponseEventWrapper(payload)) {
const payloadData = payload.data; const payloadData = payload.data;
if (payload.type === 'userInputChat' && isUserInputChatEvent(payloadData)) { if (payload.type === 'userInputChat' && isUserInputChatEvent(payloadData)) {
userInputChatStream.next(payloadData); userInputChatStream.next(payloadData);