mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-29 06:15:29 -04:00
Move and rename files (2/4) (#987)
Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
parent
1b7abf9f27
commit
123f959fb3
145 changed files with 586 additions and 301 deletions
|
@ -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])
|
||||
}
|
89
src/components/editor-page/renderer-pane/render-iframe.tsx
Normal file
89
src/components/editor-page/renderer-pane/render-iframe.tsx
Normal 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>
|
||||
}
|
|
@ -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}/>
|
||||
)
|
||||
}
|
|
@ -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>
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue