Move and rename files (2/4) (#987)

Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
Tilman Vatteroth 2021-02-02 00:03:47 +01:00 committed by GitHub
parent 1b7abf9f27
commit 123f959fb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
145 changed files with 586 additions and 301 deletions

View file

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { RefObject, useCallback, useRef } from 'react'
import { IframeEditorToRendererCommunicator } from '../../../render-page/iframe-editor-to-renderer-communicator'
export const useOnIframeLoad = (frameReference: RefObject<HTMLIFrameElement>, iframeCommunicator: IframeEditorToRendererCommunicator,
rendererOrigin: string, renderPageUrl: string, onNavigateAway: () => void): () => void => {
const sendToRenderPage = useRef<boolean>(true)
return useCallback(() => {
const frame = frameReference.current
if (!frame || !frame.contentWindow) {
iframeCommunicator.unsetOtherSide()
return
}
if (sendToRenderPage.current) {
iframeCommunicator.setOtherSide(frame.contentWindow, rendererOrigin)
sendToRenderPage.current = false
return
} else {
onNavigateAway()
console.error("Navigated away from unknown URL")
frame.src = renderPageUrl
sendToRenderPage.current = true
}
}, [frameReference, iframeCommunicator, onNavigateAway, renderPageUrl, rendererOrigin])
}

View file

@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import equal from 'fast-deep-equal'
import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useSelector } from 'react-redux'
import { useIsDarkModeActivated } from '../../../hooks/common/use-is-dark-mode-activated'
import { ApplicationState } from '../../../redux'
import { isTestMode } from '../../../utils/is-test-mode'
import { IframeEditorToRendererCommunicator } from '../../render-page/iframe-editor-to-renderer-communicator'
import { MarkdownDocumentProps } from '../../render-page/markdown-document'
import { ImageDetails } from '../../render-page/rendering-message'
import { ScrollState } from '../synced-scroll/scroll-props'
import { useOnIframeLoad } from './hooks/use-on-iframe-load'
import { ShowOnPropChangeImageLightbox } from './show-on-prop-change-image-lightbox'
export const RenderIframe: React.FC<MarkdownDocumentProps> = (
{
markdownContent,
onTaskCheckedChange,
onFrontmatterChange,
scrollState,
onFirstHeadingChange,
wide,
onScroll,
onMakeScrollSource,
extraClasses
}) => {
const darkMode = useIsDarkModeActivated()
const [rendererReady, setRendererReady] = useState<boolean>(false)
const [lightboxDetails, setLightboxDetails] = useState<ImageDetails | undefined>(undefined)
const frameReference = useRef<HTMLIFrameElement>(null)
const rendererOrigin = useSelector((state: ApplicationState) => state.config.iframeCommunication.rendererOrigin)
const renderPageUrl = `${rendererOrigin}/render`
const resetRendererReady = useCallback(() => setRendererReady(false), [])
const iframeCommunicator = useMemo(() => new IframeEditorToRendererCommunicator(), [])
const onIframeLoad = useOnIframeLoad(frameReference, iframeCommunicator, rendererOrigin, renderPageUrl, resetRendererReady)
useEffect(() => () => iframeCommunicator.unregisterEventListener(), [iframeCommunicator])
useEffect(() => iframeCommunicator.onFirstHeadingChange(onFirstHeadingChange), [iframeCommunicator, onFirstHeadingChange])
useEffect(() => iframeCommunicator.onFrontmatterChange(onFrontmatterChange), [iframeCommunicator, onFrontmatterChange])
useEffect(() => iframeCommunicator.onSetScrollState(onScroll), [iframeCommunicator, onScroll])
useEffect(() => iframeCommunicator.onSetScrollSourceToRenderer(onMakeScrollSource), [iframeCommunicator, onMakeScrollSource])
useEffect(() => iframeCommunicator.onTaskCheckboxChange(onTaskCheckedChange), [iframeCommunicator, onTaskCheckedChange])
useEffect(() => iframeCommunicator.onImageClicked(setLightboxDetails), [iframeCommunicator])
useEffect(() => iframeCommunicator.onRendererReady(() => setRendererReady(true)), [darkMode, iframeCommunicator, scrollState, wide])
useEffect(() => {
if (rendererReady) {
iframeCommunicator.sendSetDarkmode(darkMode)
}
}, [darkMode, iframeCommunicator, rendererReady])
const oldScrollState = useRef<ScrollState | undefined>(undefined)
useEffect(() => {
if (rendererReady && !equal(scrollState, oldScrollState.current)) {
oldScrollState.current = scrollState
iframeCommunicator.sendScrollState(scrollState)
}
}, [iframeCommunicator, rendererReady, scrollState])
useEffect(() => {
if (rendererReady) {
iframeCommunicator.sendSetWide(wide ?? false)
}
}, [iframeCommunicator, rendererReady, wide])
useEffect(() => {
if (rendererReady) {
iframeCommunicator.sendSetBaseUrl(window.location.toString())
}
}, [iframeCommunicator, rendererReady])
useEffect(() => {
if (rendererReady) {
iframeCommunicator.sendSetMarkdownContent(markdownContent)
}
}, [iframeCommunicator, markdownContent, rendererReady])
return <Fragment>
<ShowOnPropChangeImageLightbox details={lightboxDetails}/>
<iframe data-cy={'documentIframe'} onLoad={onIframeLoad} title="render" src={renderPageUrl}
{...isTestMode() ? {} : { sandbox: 'allow-downloads allow-same-origin allow-scripts allow-popups' }}
ref={frameReference} className={`h-100 w-100 border-0 ${extraClasses ?? ''}`}/>
</Fragment>
}

View file

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { useCallback, useEffect, useState } from 'react'
import { ImageLightboxModal } from '../../markdown-renderer/replace-components/image/image-lightbox-modal'
import { ImageDetails } from '../../render-page/rendering-message'
export interface ShowOnPropChangeImageLightboxProps {
details?: ImageDetails
}
export const ShowOnPropChangeImageLightbox: React.FC<ShowOnPropChangeImageLightboxProps> = ({ details }) => {
const [show, setShow] = useState<boolean>(false)
const hideLightbox = useCallback(() => {
setShow(false)
}, [])
useEffect(() => {
if (details) {
setShow(true)
}
}, [details])
return (
<ImageLightboxModal show={show} onHide={hideLightbox} src={details?.src}
alt={details?.alt} title={details?.title}/>
)
}

View file

@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React from 'react'
import { Alert } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import links from '../../../links.json'
import { ApplicationState } from '../../../redux'
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
import { ShowIf } from '../../common/show-if/show-if'
export const YamlArrayDeprecationAlert: React.FC = () => {
useTranslation()
const yamlDeprecatedTags = useSelector((state: ApplicationState) => state.noteDetails.frontmatter.deprecatedTagsSyntax)
return <ShowIf condition={yamlDeprecatedTags}>
<Alert data-cy={'yamlArrayDeprecationAlert'} className={'text-wrap'} variant='warning' dir='auto'>
<span className={'text-wrap'}>
<span className={'text-wrap'}>
<Trans i18nKey='editor.deprecatedTags' />
</span>
</span>
<br/>
<TranslatedExternalLink i18nKey={'common.readForMoreInfo'} href={links.faq} className={'text-primary'}/>
</Alert>
</ShowIf>
}