From af887877aa0f5364f2804b84f82a360af1460eec Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Sat, 3 Apr 2021 12:59:14 +0200 Subject: [PATCH] Add context for iframe communicator in editor page (#1146) Signed-off-by: Tilman Vatteroth --- src/components/editor-page/editor-page.tsx | 54 ++++++++++--------- .../iframe-communicator-context-provider.tsx | 25 +++++++++ .../renderer-pane/render-iframe.tsx | 6 +-- 3 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 src/components/editor-page/render-context/iframe-communicator-context-provider.tsx diff --git a/src/components/editor-page/editor-page.tsx b/src/components/editor-page/editor-page.tsx index 35493b064..836999b1d 100644 --- a/src/components/editor-page/editor-page.tsx +++ b/src/components/editor-page/editor-page.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import React, { Fragment, useCallback, useRef, useState } from 'react' +import React, { useCallback, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' import { useApplyDarkMode } from '../../hooks/common/use-apply-dark-mode' @@ -34,6 +34,7 @@ import { RendererType } from '../render-page/rendering-message' import { useEditorModeFromUrl } from './hooks/useEditorModeFromUrl' import { UiNotifications } from '../notifications/ui-notifications' import { useNotificationTest } from './use-notification-test' +import { IframeCommunicatorContextProvider } from './render-context/iframe-communicator-context-provider' export interface EditorPagePathParams { id: string @@ -86,13 +87,35 @@ export const EditorPage: React.FC = () => { useNotificationTest() + const leftPane = useMemo(() => + + , [markdownContent, onEditorScroll, scrollState.editorScrollState, setEditorToScrollSource]) + + const rightPane = useMemo(() => + + , [markdownContent, onMarkdownRendererScroll, scrollState.rendererScrollState, + setRendererToScrollSource]) + return ( - +
-
@@ -101,33 +124,16 @@ export const EditorPage: React.FC = () => {
- } + left={ leftPane } showRight={ editorMode === EditorMode.PREVIEW || editorMode === EditorMode.BOTH } - right={ - - } + right={ rightPane } containerClassName={ 'overflow-hidden' }/>
- + ) } + export default EditorPage diff --git a/src/components/editor-page/render-context/iframe-communicator-context-provider.tsx b/src/components/editor-page/render-context/iframe-communicator-context-provider.tsx new file mode 100644 index 000000000..bab6c7f91 --- /dev/null +++ b/src/components/editor-page/render-context/iframe-communicator-context-provider.tsx @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import React, { useContext, useMemo } from 'react' +import { IframeEditorToRendererCommunicator } from '../../render-page/iframe-editor-to-renderer-communicator' + +const IFrameEditorToRendererCommunicatorContext = React.createContext(undefined) + +export const useIFrameCommunicator: () => IframeEditorToRendererCommunicator | undefined = () => useContext(IFrameEditorToRendererCommunicatorContext) + +export const useContextOrStandaloneIframeCommunicator: () => IframeEditorToRendererCommunicator = () => { + const contextCommunicator = useIFrameCommunicator() + return useMemo(() => contextCommunicator ? contextCommunicator : new IframeEditorToRendererCommunicator(), [contextCommunicator]) +} + +export const IframeCommunicatorContextProvider: React.FC = ({ children }) => { + const currentIFrameCommunicator = useMemo(() => new IframeEditorToRendererCommunicator(), []) + + return + { children } + +} diff --git a/src/components/editor-page/renderer-pane/render-iframe.tsx b/src/components/editor-page/renderer-pane/render-iframe.tsx index 1b2ea5a82..68c493c57 100644 --- a/src/components/editor-page/renderer-pane/render-iframe.tsx +++ b/src/components/editor-page/renderer-pane/render-iframe.tsx @@ -4,14 +4,14 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import equal from 'fast-deep-equal' -import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import React, { Fragment, useCallback, useEffect, 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 { RendererProps } from '../../render-page/markdown-document' import { ImageDetails, RendererType } from '../../render-page/rendering-message' +import { useContextOrStandaloneIframeCommunicator } from '../render-context/iframe-communicator-context-provider' import { ScrollState } from '../synced-scroll/scroll-props' import { useOnIframeLoad } from './hooks/use-on-iframe-load' import { ShowOnPropChangeImageLightbox } from './show-on-prop-change-image-lightbox' @@ -46,7 +46,7 @@ export const RenderIframe: React.FC = ( const rendererOrigin = useSelector((state: ApplicationState) => state.config.iframeCommunication.rendererOrigin) const renderPageUrl = `${ rendererOrigin }/render` const resetRendererReady = useCallback(() => setRendererReady(false), []) - const iframeCommunicator = useMemo(() => new IframeEditorToRendererCommunicator(), []) + const iframeCommunicator = useContextOrStandaloneIframeCommunicator() const onIframeLoad = useOnIframeLoad(frameReference, iframeCommunicator, rendererOrigin, renderPageUrl, resetRendererReady) const [frameHeight, setFrameHeight] = useState(0)