From 883f8683994f0f1fdeadb3a47cee46f7f6e45d5e Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Mon, 26 Sep 2022 16:23:45 +0200 Subject: [PATCH] feat(window post message communicator): Use EventEmitter2 Signed-off-by: Tilman Vatteroth --- package.json | 1 + .../hooks/use-editor-receive-handler.ts | 13 +++---- .../hooks/use-renderer-receive-handler.ts | 8 ++--- .../window-post-message-communicator.ts | 36 ++++++++++--------- yarn.lock | 8 +++++ 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index beb37950d..5c7520cf6 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "dompurify": "2.4.0", "emoji-picker-element": "1.12.1", "emoji-picker-element-data": "1.3.0", + "eventemitter2": "6.4.9", "fast-deep-equal": "3.1.3", "firacode": "6.2.0", "flowchart.js": "1.17.1", diff --git a/src/components/render-page/window-post-message-communicator/hooks/use-editor-receive-handler.ts b/src/components/render-page/window-post-message-communicator/hooks/use-editor-receive-handler.ts index ffebe0ef6..86d94e834 100644 --- a/src/components/render-page/window-post-message-communicator/hooks/use-editor-receive-handler.ts +++ b/src/components/render-page/window-post-message-communicator/hooks/use-editor-receive-handler.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import { useEffect } from 'react' import type { CommunicationMessages, RendererToEditorMessageType } from '../rendering-message' import { useEditorToRendererCommunicator } from '../../../editor-page/render-context/editor-to-renderer-communicator-context-provider' -import type { MaybeHandler } from '../window-post-message-communicator' +import type { Handler } from '../window-post-message-communicator' /** * Sets the handler for the given message type in the current editor to renderer communicator. @@ -17,13 +17,14 @@ import type { MaybeHandler } from '../window-post-message-communicator' */ export const useEditorReceiveHandler = ( messageType: R, - handler: MaybeHandler + handler?: Handler ): void => { const editorToRendererCommunicator = useEditorToRendererCommunicator() useEffect(() => { - editorToRendererCommunicator.setHandler(messageType, handler) - return () => { - editorToRendererCommunicator.setHandler(messageType, undefined) + if (!handler) { + return } + editorToRendererCommunicator.on(messageType, handler) + return () => editorToRendererCommunicator.off(messageType, handler) }, [editorToRendererCommunicator, handler, messageType]) } diff --git a/src/components/render-page/window-post-message-communicator/hooks/use-renderer-receive-handler.ts b/src/components/render-page/window-post-message-communicator/hooks/use-renderer-receive-handler.ts index 96c242a9d..a8279c821 100644 --- a/src/components/render-page/window-post-message-communicator/hooks/use-renderer-receive-handler.ts +++ b/src/components/render-page/window-post-message-communicator/hooks/use-renderer-receive-handler.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -26,9 +26,7 @@ export const useRendererReceiveHandler = { const editorToRendererCommunicator = useRendererToEditorCommunicator() useEffect(() => { - editorToRendererCommunicator.setHandler(messageType, handler) - return () => { - editorToRendererCommunicator.setHandler(messageType, undefined) - } + editorToRendererCommunicator.on(messageType, handler) + return () => editorToRendererCommunicator.off(messageType, handler) }, [editorToRendererCommunicator, handler, messageType]) } diff --git a/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts b/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts index e2c75b389..de82a888e 100644 --- a/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts +++ b/src/components/render-page/window-post-message-communicator/window-post-message-communicator.ts @@ -6,6 +6,7 @@ import type { Logger } from '../../../utils/logger' import { Optional } from '@mrdrogdrog/optional' +import EventEmitter2 from 'eventemitter2' /** * Error that will be thrown if a message couldn't be sent. @@ -16,12 +17,6 @@ export type Handler = ( values: Extract> ) => void -export type MaybeHandler = Handler | undefined - -export type HandlerMap = Partial<{ - [key in MESSAGE_TYPE]: MaybeHandler -}> - export interface MessagePayload { type: MESSAGE_TYPE } @@ -37,7 +32,7 @@ export abstract class WindowPostMessageCommunicator< private messageTarget?: Window private targetOrigin?: string private communicationEnabled: boolean - private readonly handlers: HandlerMap = {} + private readonly emitter: EventEmitter2 = new EventEmitter2() private readonly log: Logger private readonly boundListener: (event: MessageEvent) => void @@ -113,15 +108,25 @@ export abstract class WindowPostMessageCommunicator< } /** - * Sets the handler method that processes messages with the given message type. - * If there is already a handler for the given message type then the handler will be overwritten. + * Registers a handler for the given message type. * * @param messageType The message type for which the handler should be called * @param handler The handler that processes messages with the given message type. */ - public setHandler(messageType: R, handler: MaybeHandler): void { - this.log.debug(handler === undefined ? 'Unset' : 'Set', 'handler for', messageType) - this.handlers[messageType] = handler as MaybeHandler + public on(messageType: R, handler: Handler): void { + this.log.debug('Set handler for', messageType) + this.emitter.on(messageType, handler) + } + + /** + * Deletes a handler for the given message type. + * + * @param messageType The message type for which the handler should be removed + * @param handler The handler that should be removed. + */ + public off(messageType: R, handler: Handler): void { + this.log.debug('Unset handler for', messageType) + this.emitter.off(messageType, handler) } /** @@ -142,10 +147,7 @@ export abstract class WindowPostMessageCommunicator< * Processes a {@link MessagePayload message payload} using the correct {@link Handler handler}. * @param payload The payload that should be processed */ - private processPayload(payload: MessagePayload): void { - return Optional.ofNullable>(this.handlers[payload.type]).ifPresent((handler) => { - this.log.debug('Received event', payload) - handler(payload as Extract>) - }) + private processPayload(payload: MessagePayload): void { + this.emitter.emit(payload.type, payload) } } diff --git a/yarn.lock b/yarn.lock index 0d8e46958..6ea020bd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1987,6 +1987,7 @@ __metadata: eslint-plugin-prettier: 4.2.1 eslint-plugin-promise: 6.0.1 eslint-plugin-testing-library: 5.7.0 + eventemitter2: 6.4.9 fast-deep-equal: 3.1.3 firacode: 6.2.0 flowchart.js: 1.17.1 @@ -7009,6 +7010,13 @@ __metadata: languageName: node linkType: hard +"eventemitter2@npm:6.4.9": + version: 6.4.9 + resolution: "eventemitter2@npm:6.4.9" + checksum: be59577c1e1c35509c7ba0e2624335c35bbcfd9485b8a977384c6cc6759341ea1a98d3cb9dbaa5cea4fff9b687e504504e3f9c2cc1674cf3bd8a43a7c74ea3eb + languageName: node + linkType: hard + "execa@npm:4.1.0": version: 4.1.0 resolution: "execa@npm:4.1.0"