mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-15 07:34:42 -04:00
Refactor iframe load callback to fix race condition (#1536)
* Refactor iframe load callback to fix race condition Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
ee7cde0096
commit
bd036b5b68
3 changed files with 75 additions and 53 deletions
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { isTestMode } from '../../../utils/test-modes'
|
||||
import { RendererProps } from '../../render-page/markdown-document'
|
||||
import {
|
||||
|
@ -16,7 +15,7 @@ import {
|
|||
SetScrollStateMessage
|
||||
} from '../../render-page/window-post-message-communicator/rendering-message'
|
||||
import { useEditorToRendererCommunicator } from '../render-context/editor-to-renderer-communicator-context-provider'
|
||||
import { useOnIframeLoad } from './hooks/use-on-iframe-load'
|
||||
import { useForceRenderPageUrlOnIframeLoadCallback } from './hooks/use-force-render-page-url-on-iframe-load-callback'
|
||||
import { CommunicatorImageLightbox } from './communicator-image-lightbox'
|
||||
import { setRendererStatus } from '../../../redux/renderer-status/methods'
|
||||
import { useEditorReceiveHandler } from '../../render-page/window-post-message-communicator/hooks/use-editor-receive-handler'
|
||||
|
@ -24,6 +23,8 @@ import { useIsRendererReady } from '../../render-page/window-post-message-commun
|
|||
import { useSendDarkModeStatusToRenderer } from './hooks/use-send-dark-mode-status-to-renderer'
|
||||
import { useSendMarkdownToRenderer } from './hooks/use-send-markdown-to-renderer'
|
||||
import { useSendScrollState } from './hooks/use-send-scroll-state'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
|
||||
export interface RenderIframeProps extends RendererProps {
|
||||
rendererType: RendererType
|
||||
|
@ -31,6 +32,8 @@ export interface RenderIframeProps extends RendererProps {
|
|||
frameClasses?: string
|
||||
}
|
||||
|
||||
const log = new Logger('RenderIframe')
|
||||
|
||||
export const RenderIframe: React.FC<RenderIframeProps> = ({
|
||||
markdownContent,
|
||||
onTaskCheckedChange,
|
||||
|
@ -44,17 +47,14 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
}) => {
|
||||
const frameReference = useRef<HTMLIFrameElement>(null)
|
||||
const rendererOrigin = useApplicationState((state) => state.config.iframeCommunication.rendererOrigin)
|
||||
const renderPageUrl = `${rendererOrigin}render`
|
||||
const resetRendererReady = useCallback(() => setRendererStatus(false), [])
|
||||
const iframeCommunicator = useEditorToRendererCommunicator()
|
||||
const resetRendererReady = useCallback(() => {
|
||||
log.debug('Reset render status')
|
||||
iframeCommunicator.unsetMessageTarget()
|
||||
setRendererStatus(false)
|
||||
}, [iframeCommunicator])
|
||||
const rendererReady = useIsRendererReady()
|
||||
const onIframeLoad = useOnIframeLoad(
|
||||
frameReference,
|
||||
iframeCommunicator,
|
||||
rendererOrigin,
|
||||
renderPageUrl,
|
||||
resetRendererReady
|
||||
)
|
||||
const onIframeLoad = useForceRenderPageUrlOnIframeLoadCallback(frameReference, rendererOrigin, resetRendererReady)
|
||||
const [frameHeight, setFrameHeight] = useState<number>(0)
|
||||
|
||||
useEffect(
|
||||
|
@ -99,6 +99,18 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
useEditorReceiveHandler(
|
||||
CommunicationMessageType.RENDERER_READY,
|
||||
useCallback(() => {
|
||||
const frame = frameReference.current
|
||||
if (!frame) {
|
||||
log.error('Load triggered without frame in ref')
|
||||
return
|
||||
}
|
||||
const otherWindow = frame.contentWindow
|
||||
if (!otherWindow) {
|
||||
log.error('Load triggered without content window')
|
||||
return
|
||||
}
|
||||
log.debug(`Set iframecommunicator window with origin ${rendererOrigin}`)
|
||||
iframeCommunicator.setMessageTarget(otherWindow, rendererOrigin)
|
||||
iframeCommunicator.enableCommunication()
|
||||
iframeCommunicator.sendMessageToOtherSide({
|
||||
type: CommunicationMessageType.SET_BASE_CONFIGURATION,
|
||||
|
@ -108,7 +120,7 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
}
|
||||
})
|
||||
setRendererStatus(true)
|
||||
}, [iframeCommunicator, rendererType])
|
||||
}, [iframeCommunicator, rendererOrigin, rendererType])
|
||||
)
|
||||
|
||||
useSendScrollState(scrollState)
|
||||
|
@ -123,7 +135,6 @@ export const RenderIframe: React.FC<RenderIframeProps> = ({
|
|||
data-cy={'documentIframe'}
|
||||
onLoad={onIframeLoad}
|
||||
title='render'
|
||||
src={renderPageUrl}
|
||||
{...(isTestMode() ? {} : { sandbox: 'allow-downloads allow-same-origin allow-scripts allow-popups' })}
|
||||
ref={frameReference}
|
||||
className={`border-0 ${frameClasses ?? ''}`}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue