mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-15 15:44:45 -04: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
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
import type { PropsWithChildren } from 'react'
|
import type { PropsWithChildren } from 'react'
|
||||||
import React, { createContext, useContext, useEffect, useMemo } from 'react'
|
import React, { createContext, useContext, useEffect, useMemo } from 'react'
|
||||||
import { EditorToRendererCommunicator } from '../../render-page/window-post-message-communicator/editor-to-renderer-communicator'
|
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)
|
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.
|
* Provides a {@link EditorToRendererCommunicator editor to renderer communicator} for the child components via Context.
|
||||||
*/
|
*/
|
||||||
export const EditorToRendererCommunicatorContextProvider: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
export const EditorToRendererCommunicatorContextProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
||||||
const communicator = useMemo<EditorToRendererCommunicator>(() => new EditorToRendererCommunicator(), [])
|
const communicator = useMemo<EditorToRendererCommunicator>(() => new EditorToRendererCommunicator(uuid()), [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentCommunicator = communicator
|
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 { RendererToEditorCommunicator } from '../../render-page/window-post-message-communicator/renderer-to-editor-communicator'
|
||||||
import { CommunicationMessageType } from '../../render-page/window-post-message-communicator/rendering-message'
|
import { CommunicationMessageType } from '../../render-page/window-post-message-communicator/rendering-message'
|
||||||
import { ORIGIN, useBaseUrl } from '../../../hooks/common/use-base-url'
|
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)
|
const RendererToEditorCommunicatorContext = createContext<RendererToEditorCommunicator | undefined>(undefined)
|
||||||
|
|
||||||
|
@ -28,7 +29,14 @@ export const useRendererToEditorCommunicator: () => RendererToEditorCommunicator
|
||||||
|
|
||||||
export const RendererToEditorCommunicatorContextProvider: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
export const RendererToEditorCommunicatorContextProvider: React.FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||||
const editorOrigin = useBaseUrl(ORIGIN.EDITOR)
|
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(() => {
|
useEffect(() => {
|
||||||
const currentCommunicator = communicator
|
const currentCommunicator = communicator
|
||||||
|
|
|
@ -8,6 +8,7 @@ import type { RefObject } from 'react'
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||||
import { Logger } from '../../../../utils/logger'
|
import { Logger } from '../../../../utils/logger'
|
||||||
import { ORIGIN, useBaseUrl } from '../../../../hooks/common/use-base-url'
|
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')
|
const log = new Logger('IframeLoader')
|
||||||
|
|
||||||
|
@ -19,14 +20,16 @@ const log = new Logger('IframeLoader')
|
||||||
*/
|
*/
|
||||||
export const useForceRenderPageUrlOnIframeLoadCallback = (
|
export const useForceRenderPageUrlOnIframeLoadCallback = (
|
||||||
iFrameReference: RefObject<HTMLIFrameElement>,
|
iFrameReference: RefObject<HTMLIFrameElement>,
|
||||||
onNavigateAway?: () => void
|
onNavigateAway: () => void
|
||||||
): (() => void) => {
|
): (() => void) => {
|
||||||
|
const iframeCommunicator = useEditorToRendererCommunicator()
|
||||||
const rendererBaseUrl = useBaseUrl(ORIGIN.RENDERER)
|
const rendererBaseUrl = useBaseUrl(ORIGIN.RENDERER)
|
||||||
const forcedUrl = useMemo(() => {
|
const forcedUrl = useMemo(() => {
|
||||||
const renderUrl = new URL(rendererBaseUrl)
|
const renderUrl = new URL(rendererBaseUrl)
|
||||||
renderUrl.pathname += 'render'
|
renderUrl.pathname += 'render'
|
||||||
|
renderUrl.searchParams.set('uuid', iframeCommunicator.getUuid())
|
||||||
return renderUrl.toString()
|
return renderUrl.toString()
|
||||||
}, [rendererBaseUrl])
|
}, [iframeCommunicator, rendererBaseUrl])
|
||||||
const redirectionInProgress = useRef<boolean>(false)
|
const redirectionInProgress = useRef<boolean>(false)
|
||||||
|
|
||||||
const loadCallback = useCallback(() => {
|
const loadCallback = useCallback(() => {
|
||||||
|
|
|
@ -17,6 +17,11 @@ export type Handler<MESSAGES, MESSAGE_TYPE extends string> = (
|
||||||
values: Extract<MESSAGES, MessagePayload<MESSAGE_TYPE>>
|
values: Extract<MESSAGES, MessagePayload<MESSAGE_TYPE>>
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
|
export interface MessagePayloadWithUuid<MESSAGE_TYPE extends string> {
|
||||||
|
uuid: string
|
||||||
|
payload: MessagePayload<MESSAGE_TYPE>
|
||||||
|
}
|
||||||
|
|
||||||
export interface MessagePayload<MESSAGE_TYPE extends string> {
|
export interface MessagePayload<MESSAGE_TYPE extends string> {
|
||||||
type: MESSAGE_TYPE
|
type: MESSAGE_TYPE
|
||||||
}
|
}
|
||||||
|
@ -36,12 +41,16 @@ export abstract class WindowPostMessageCommunicator<
|
||||||
private readonly log: Logger
|
private readonly log: Logger
|
||||||
private readonly boundListener: (event: MessageEvent) => void
|
private readonly boundListener: (event: MessageEvent) => void
|
||||||
|
|
||||||
public constructor() {
|
public constructor(private uuid: string) {
|
||||||
this.boundListener = this.handleEvent.bind(this)
|
this.boundListener = this.handleEvent.bind(this)
|
||||||
this.communicationEnabled = false
|
this.communicationEnabled = false
|
||||||
this.log = this.createLogger()
|
this.log = this.createLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getUuid(): string {
|
||||||
|
return this.uuid
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract createLogger(): Logger
|
protected abstract createLogger(): Logger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +113,13 @@ export abstract class WindowPostMessageCommunicator<
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
this.log.debug('Sent event', message)
|
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
|
* @param event The received event
|
||||||
* @return {@link true} if the event was processed.
|
* @return {@link true} if the event was processed.
|
||||||
*/
|
*/
|
||||||
protected handleEvent(event: MessageEvent<MessagePayload<RECEIVE_TYPE>>): void {
|
protected handleEvent(event: MessageEvent<MessagePayloadWithUuid<RECEIVE_TYPE>>): void {
|
||||||
Optional.ofNullable(event.data).ifPresent((payload) => {
|
Optional.ofNullable(event.data)
|
||||||
event.stopPropagation()
|
.filter((value) => value.uuid === this.uuid)
|
||||||
event.preventDefault()
|
.ifPresent((payload) => {
|
||||||
this.processPayload(payload)
|
event.stopPropagation()
|
||||||
})
|
event.preventDefault()
|
||||||
}
|
this.emitter.emit(payload.payload.type, payload.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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue