mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-03-21 03:24:19 +00:00
feat(window post message communicator): Add uuid to frames
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
883f868399
commit
16bb83f74a
4 changed files with 43 additions and 22 deletions
|
@ -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,6 +7,7 @@
|
|||
import type { PropsWithChildren } from 'react'
|
||||
import React, { createContext, useContext, useEffect, useMemo } from 'react'
|
||||
import { EditorToRendererCommunicator } from '../../render-page/window-post-message-communicator/editor-to-renderer-communicator'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
|
||||
const EditorToRendererCommunicatorContext = createContext<EditorToRendererCommunicator | undefined>(undefined)
|
||||
|
||||
|
@ -27,8 +28,8 @@ export const useEditorToRendererCommunicator: () => EditorToRendererCommunicator
|
|||
/**
|
||||
* Provides a {@link EditorToRendererCommunicator editor to renderer communicator} for the child components via Context.
|
||||
*/
|
||||
export const EditorToRendererCommunicatorContextProvider: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const communicator = useMemo<EditorToRendererCommunicator>(() => new EditorToRendererCommunicator(), [])
|
||||
export const EditorToRendererCommunicatorContextProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
||||
const communicator = useMemo<EditorToRendererCommunicator>(() => new EditorToRendererCommunicator(uuid()), [])
|
||||
|
||||
useEffect(() => {
|
||||
const currentCommunicator = communicator
|
||||
|
|
|
@ -9,6 +9,7 @@ import React, { createContext, useContext, useEffect, useMemo } from 'react'
|
|||
import { RendererToEditorCommunicator } from '../../render-page/window-post-message-communicator/renderer-to-editor-communicator'
|
||||
import { CommunicationMessageType } from '../../render-page/window-post-message-communicator/rendering-message'
|
||||
import { ORIGIN, useBaseUrl } from '../../../hooks/common/use-base-url'
|
||||
import { useSingleStringUrlParameter } from '../../../hooks/common/use-single-string-url-parameter'
|
||||
|
||||
const RendererToEditorCommunicatorContext = createContext<RendererToEditorCommunicator | undefined>(undefined)
|
||||
|
||||
|
@ -28,7 +29,14 @@ export const useRendererToEditorCommunicator: () => RendererToEditorCommunicator
|
|||
|
||||
export const RendererToEditorCommunicatorContextProvider: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const editorOrigin = useBaseUrl(ORIGIN.EDITOR)
|
||||
const communicator = useMemo<RendererToEditorCommunicator>(() => new RendererToEditorCommunicator(), [])
|
||||
const uuid = useSingleStringUrlParameter('uuid', undefined)
|
||||
const communicator = useMemo<RendererToEditorCommunicator>(() => {
|
||||
if (uuid === undefined) {
|
||||
throw new Error('no uuid found in url!')
|
||||
} else {
|
||||
return new RendererToEditorCommunicator(uuid)
|
||||
}
|
||||
}, [uuid])
|
||||
|
||||
useEffect(() => {
|
||||
const currentCommunicator = communicator
|
||||
|
|
|
@ -8,6 +8,7 @@ import type { RefObject } from 'react'
|
|||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import { ORIGIN, useBaseUrl } from '../../../../hooks/common/use-base-url'
|
||||
import { useEditorToRendererCommunicator } from '../../render-context/editor-to-renderer-communicator-context-provider'
|
||||
|
||||
const log = new Logger('IframeLoader')
|
||||
|
||||
|
@ -19,14 +20,16 @@ const log = new Logger('IframeLoader')
|
|||
*/
|
||||
export const useForceRenderPageUrlOnIframeLoadCallback = (
|
||||
iFrameReference: RefObject<HTMLIFrameElement>,
|
||||
onNavigateAway?: () => void
|
||||
onNavigateAway: () => void
|
||||
): (() => void) => {
|
||||
const iframeCommunicator = useEditorToRendererCommunicator()
|
||||
const rendererBaseUrl = useBaseUrl(ORIGIN.RENDERER)
|
||||
const forcedUrl = useMemo(() => {
|
||||
const renderUrl = new URL(rendererBaseUrl)
|
||||
renderUrl.pathname += 'render'
|
||||
renderUrl.searchParams.set('uuid', iframeCommunicator.getUuid())
|
||||
return renderUrl.toString()
|
||||
}, [rendererBaseUrl])
|
||||
}, [iframeCommunicator, rendererBaseUrl])
|
||||
const redirectionInProgress = useRef<boolean>(false)
|
||||
|
||||
const loadCallback = useCallback(() => {
|
||||
|
|
|
@ -17,6 +17,11 @@ export type Handler<MESSAGES, MESSAGE_TYPE extends string> = (
|
|||
values: Extract<MESSAGES, MessagePayload<MESSAGE_TYPE>>
|
||||
) => void
|
||||
|
||||
export interface MessagePayloadWithUuid<MESSAGE_TYPE extends string> {
|
||||
uuid: string
|
||||
payload: MessagePayload<MESSAGE_TYPE>
|
||||
}
|
||||
|
||||
export interface MessagePayload<MESSAGE_TYPE extends string> {
|
||||
type: MESSAGE_TYPE
|
||||
}
|
||||
|
@ -36,12 +41,16 @@ export abstract class WindowPostMessageCommunicator<
|
|||
private readonly log: Logger
|
||||
private readonly boundListener: (event: MessageEvent) => void
|
||||
|
||||
public constructor() {
|
||||
public constructor(private uuid: string) {
|
||||
this.boundListener = this.handleEvent.bind(this)
|
||||
this.communicationEnabled = false
|
||||
this.log = this.createLogger()
|
||||
}
|
||||
|
||||
public getUuid(): string {
|
||||
return this.uuid
|
||||
}
|
||||
|
||||
protected abstract createLogger(): Logger
|
||||
|
||||
/**
|
||||
|
@ -104,7 +113,13 @@ export abstract class WindowPostMessageCommunicator<
|
|||
)
|
||||
}
|
||||
this.log.debug('Sent event', message)
|
||||
this.messageTarget.postMessage(message, this.targetOrigin)
|
||||
this.messageTarget.postMessage(
|
||||
{
|
||||
uuid: this.uuid,
|
||||
payload: message
|
||||
} as MessagePayloadWithUuid<SEND_TYPE>,
|
||||
this.targetOrigin
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,19 +150,13 @@ export abstract class WindowPostMessageCommunicator<
|
|||
* @param event The received event
|
||||
* @return {@link true} if the event was processed.
|
||||
*/
|
||||
protected handleEvent(event: MessageEvent<MessagePayload<RECEIVE_TYPE>>): void {
|
||||
Optional.ofNullable(event.data).ifPresent((payload) => {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
this.processPayload(payload)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a {@link MessagePayload message payload} using the correct {@link Handler handler}.
|
||||
* @param payload The payload that should be processed
|
||||
*/
|
||||
private processPayload(payload: MessagePayload<string>): void {
|
||||
this.emitter.emit(payload.type, payload)
|
||||
protected handleEvent(event: MessageEvent<MessagePayloadWithUuid<RECEIVE_TYPE>>): void {
|
||||
Optional.ofNullable(event.data)
|
||||
.filter((value) => value.uuid === this.uuid)
|
||||
.ifPresent((payload) => {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
this.emitter.emit(payload.payload.type, payload.payload)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue