mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-25 12:34:45 -04:00
Move frontmatter extraction from renderer to redux (#1413)
This commit is contained in:
parent
7fb7c55877
commit
04e16d8880
34 changed files with 680 additions and 589 deletions
|
@ -3,8 +3,6 @@
|
|||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { NoteFrontmatter } from '../editor-page/note-frontmatter/note-frontmatter'
|
||||
import { ScrollState } from '../editor-page/synced-scroll/scroll-props'
|
||||
import { IframeCommunicator } from './iframe-communicator'
|
||||
import {
|
||||
|
@ -14,6 +12,7 @@ import {
|
|||
RendererToEditorIframeMessage,
|
||||
RenderIframeMessageType
|
||||
} from './rendering-message'
|
||||
import { RendererFrontmatterInfo } from '../common/note-frontmatter/types'
|
||||
|
||||
export class IframeEditorToRendererCommunicator extends IframeCommunicator<
|
||||
EditorToRendererIframeMessage,
|
||||
|
@ -22,7 +21,6 @@ export class IframeEditorToRendererCommunicator extends IframeCommunicator<
|
|||
private onSetScrollSourceToRendererHandler?: () => void
|
||||
private onTaskCheckboxChangeHandler?: (lineInMarkdown: number, checked: boolean) => void
|
||||
private onFirstHeadingChangeHandler?: (heading?: string) => void
|
||||
private onFrontmatterChangeHandler?: (frontmatter?: NoteFrontmatter) => void
|
||||
private onSetScrollStateHandler?: (scrollState: ScrollState) => void
|
||||
private onRendererReadyHandler?: () => void
|
||||
private onImageClickedHandler?: (details: ImageDetails) => void
|
||||
|
@ -33,10 +31,6 @@ export class IframeEditorToRendererCommunicator extends IframeCommunicator<
|
|||
this.onHeightChangeHandler = handler
|
||||
}
|
||||
|
||||
public onFrontmatterChange(handler?: (frontmatter?: NoteFrontmatter) => void): void {
|
||||
this.onFrontmatterChangeHandler = handler
|
||||
}
|
||||
|
||||
public onImageClicked(handler?: (details: ImageDetails) => void): void {
|
||||
this.onImageClickedHandler = handler
|
||||
}
|
||||
|
@ -102,6 +96,13 @@ export class IframeEditorToRendererCommunicator extends IframeCommunicator<
|
|||
})
|
||||
}
|
||||
|
||||
public sendSetFrontmatterInfo(frontmatterInfo: RendererFrontmatterInfo): void {
|
||||
this.sendMessageToOtherSide({
|
||||
type: RenderIframeMessageType.SET_FRONTMATTER_INFO,
|
||||
frontmatterInfo: frontmatterInfo
|
||||
})
|
||||
}
|
||||
|
||||
protected handleEvent(event: MessageEvent<RendererToEditorIframeMessage>): boolean | undefined {
|
||||
const renderMessage = event.data
|
||||
switch (renderMessage.type) {
|
||||
|
@ -121,9 +122,6 @@ export class IframeEditorToRendererCommunicator extends IframeCommunicator<
|
|||
case RenderIframeMessageType.ON_TASK_CHECKBOX_CHANGE:
|
||||
this.onTaskCheckboxChangeHandler?.(renderMessage.lineInMarkdown, renderMessage.checked)
|
||||
return false
|
||||
case RenderIframeMessageType.ON_SET_FRONTMATTER:
|
||||
this.onFrontmatterChangeHandler?.(renderMessage.frontmatter)
|
||||
return false
|
||||
case RenderIframeMessageType.IMAGE_CLICKED:
|
||||
this.onImageClickedHandler?.(renderMessage.details)
|
||||
return false
|
||||
|
|
|
@ -8,18 +8,22 @@ import React, { useCallback, useEffect, useState } from 'react'
|
|||
import { ScrollState } from '../editor-page/synced-scroll/scroll-props'
|
||||
import { BaseConfiguration, RendererType } from './rendering-message'
|
||||
import { setDarkMode } from '../../redux/dark-mode/methods'
|
||||
import { NoteFrontmatter } from '../editor-page/note-frontmatter/note-frontmatter'
|
||||
import { setNoteFrontmatter } from '../../redux/note-details/methods'
|
||||
import { ImageClickHandler } from '../markdown-renderer/replace-components/image/image-replacer'
|
||||
import { useImageClickHandler } from './hooks/use-image-click-handler'
|
||||
import { MarkdownDocument } from './markdown-document'
|
||||
import { useIFrameRendererToEditorCommunicator } from '../editor-page/render-context/iframe-renderer-to-editor-communicator-context-provider'
|
||||
import { countWords } from './word-counter'
|
||||
import { RendererFrontmatterInfo } from '../common/note-frontmatter/types'
|
||||
|
||||
export const IframeMarkdownRenderer: React.FC = () => {
|
||||
const [markdownContent, setMarkdownContent] = useState('')
|
||||
const [scrollState, setScrollState] = useState<ScrollState>({ firstLineInView: 1, scrolledPercentage: 0 })
|
||||
const [baseConfiguration, setBaseConfiguration] = useState<BaseConfiguration | undefined>(undefined)
|
||||
const [frontmatterInfo, setFrontmatterInfo] = useState<RendererFrontmatterInfo>({
|
||||
offsetLines: 0,
|
||||
frontmatterInvalid: false,
|
||||
deprecatedSyntax: false
|
||||
})
|
||||
|
||||
const iframeCommunicator = useIFrameRendererToEditorCommunicator()
|
||||
|
||||
|
@ -37,6 +41,7 @@ export const IframeMarkdownRenderer: React.FC = () => {
|
|||
useEffect(() => iframeCommunicator.onSetMarkdownContent(setMarkdownContent), [iframeCommunicator])
|
||||
useEffect(() => iframeCommunicator.onSetDarkMode(setDarkMode), [iframeCommunicator])
|
||||
useEffect(() => iframeCommunicator.onSetScrollState(setScrollState), [iframeCommunicator, scrollState])
|
||||
useEffect(() => iframeCommunicator.onSetFrontmatterInfo(setFrontmatterInfo), [iframeCommunicator, setFrontmatterInfo])
|
||||
useEffect(
|
||||
() => iframeCommunicator.onGetWordCount(countWordsInRenderedDocument),
|
||||
[iframeCommunicator, countWordsInRenderedDocument]
|
||||
|
@ -60,14 +65,6 @@ export const IframeMarkdownRenderer: React.FC = () => {
|
|||
iframeCommunicator.sendSetScrollSourceToRenderer()
|
||||
}, [iframeCommunicator])
|
||||
|
||||
const onFrontmatterChange = useCallback(
|
||||
(frontmatter?: NoteFrontmatter) => {
|
||||
setNoteFrontmatter(frontmatter)
|
||||
iframeCommunicator.sendSetFrontmatter(frontmatter)
|
||||
},
|
||||
[iframeCommunicator]
|
||||
)
|
||||
|
||||
const onScroll = useCallback(
|
||||
(scrollState: ScrollState) => {
|
||||
iframeCommunicator.sendSetScrollState(scrollState)
|
||||
|
@ -97,11 +94,11 @@ export const IframeMarkdownRenderer: React.FC = () => {
|
|||
onTaskCheckedChange={onTaskCheckedChange}
|
||||
onFirstHeadingChange={onFirstHeadingChange}
|
||||
onMakeScrollSource={onMakeScrollSource}
|
||||
onFrontmatterChange={onFrontmatterChange}
|
||||
scrollState={scrollState}
|
||||
onScroll={onScroll}
|
||||
baseUrl={baseConfiguration.baseUrl}
|
||||
onImageClick={onImageClick}
|
||||
frontmatterInfo={frontmatterInfo}
|
||||
/>
|
||||
)
|
||||
case RendererType.INTRO:
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { NoteFrontmatter } from '../editor-page/note-frontmatter/note-frontmatter'
|
||||
import { ScrollState } from '../editor-page/synced-scroll/scroll-props'
|
||||
import { IframeCommunicator } from './iframe-communicator'
|
||||
import {
|
||||
|
@ -14,6 +13,7 @@ import {
|
|||
RendererToEditorIframeMessage,
|
||||
RenderIframeMessageType
|
||||
} from './rendering-message'
|
||||
import { RendererFrontmatterInfo } from '../common/note-frontmatter/types'
|
||||
|
||||
export class IframeRendererToEditorCommunicator extends IframeCommunicator<
|
||||
RendererToEditorIframeMessage,
|
||||
|
@ -24,6 +24,7 @@ export class IframeRendererToEditorCommunicator extends IframeCommunicator<
|
|||
private onSetScrollStateHandler?: (scrollState: ScrollState) => void
|
||||
private onSetBaseConfigurationHandler?: (baseConfiguration: BaseConfiguration) => void
|
||||
private onGetWordCountHandler?: () => void
|
||||
private onSetFrontmatterInfoHandler?: (frontmatterInfo: RendererFrontmatterInfo) => void
|
||||
|
||||
public onSetBaseConfiguration(handler?: (baseConfiguration: BaseConfiguration) => void): void {
|
||||
this.onSetBaseConfigurationHandler = handler
|
||||
|
@ -45,6 +46,10 @@ export class IframeRendererToEditorCommunicator extends IframeCommunicator<
|
|||
this.onGetWordCountHandler = handler
|
||||
}
|
||||
|
||||
public onSetFrontmatterInfo(handler?: (frontmatterInfo: RendererFrontmatterInfo) => void): void {
|
||||
this.onSetFrontmatterInfoHandler = handler
|
||||
}
|
||||
|
||||
public sendRendererReady(): void {
|
||||
this.enableCommunication()
|
||||
this.sendMessageToOtherSide({
|
||||
|
@ -73,13 +78,6 @@ export class IframeRendererToEditorCommunicator extends IframeCommunicator<
|
|||
})
|
||||
}
|
||||
|
||||
public sendSetFrontmatter(frontmatter: NoteFrontmatter | undefined): void {
|
||||
this.sendMessageToOtherSide({
|
||||
type: RenderIframeMessageType.ON_SET_FRONTMATTER,
|
||||
frontmatter: frontmatter
|
||||
})
|
||||
}
|
||||
|
||||
public sendSetScrollState(scrollState: ScrollState): void {
|
||||
this.sendMessageToOtherSide({
|
||||
type: RenderIframeMessageType.SET_SCROLL_STATE,
|
||||
|
@ -126,6 +124,9 @@ export class IframeRendererToEditorCommunicator extends IframeCommunicator<
|
|||
case RenderIframeMessageType.GET_WORD_COUNT:
|
||||
this.onGetWordCountHandler?.()
|
||||
return false
|
||||
case RenderIframeMessageType.SET_FRONTMATTER_INFO:
|
||||
this.onSetFrontmatterInfoHandler?.(renderMessage.frontmatterInfo)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import { TocAst } from 'markdown-it-toc-done-right'
|
||||
import React, { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import useResizeObserver from 'use-resize-observer'
|
||||
import { NoteFrontmatter } from '../editor-page/note-frontmatter/note-frontmatter'
|
||||
import { YamlArrayDeprecationAlert } from '../editor-page/renderer-pane/yaml-array-deprecation-alert'
|
||||
import { useSyncedScrolling } from '../editor-page/synced-scroll/hooks/use-synced-scrolling'
|
||||
import { ScrollProps } from '../editor-page/synced-scroll/scroll-props'
|
||||
|
@ -17,10 +16,11 @@ import './markdown-document.scss'
|
|||
import { WidthBasedTableOfContents } from './width-based-table-of-contents'
|
||||
import { ShowIf } from '../common/show-if/show-if'
|
||||
import { useApplicationState } from '../../hooks/common/use-application-state'
|
||||
import { RendererFrontmatterInfo } from '../common/note-frontmatter/types'
|
||||
import { InvalidYamlAlert } from '../markdown-renderer/invalid-yaml-alert'
|
||||
|
||||
export interface RendererProps extends ScrollProps {
|
||||
onFirstHeadingChange?: (firstHeading: string | undefined) => void
|
||||
onFrontmatterChange?: (frontmatter: NoteFrontmatter | undefined) => void
|
||||
onTaskCheckedChange?: (lineInMarkdown: number, checked: boolean) => void
|
||||
documentRenderPaneRef?: MutableRefObject<HTMLDivElement | null>
|
||||
markdownContent: string
|
||||
|
@ -33,13 +33,13 @@ export interface MarkdownDocumentProps extends RendererProps {
|
|||
additionalRendererClasses?: string
|
||||
disableToc?: boolean
|
||||
baseUrl: string
|
||||
frontmatterInfo?: RendererFrontmatterInfo
|
||||
}
|
||||
|
||||
export const MarkdownDocument: React.FC<MarkdownDocumentProps> = ({
|
||||
additionalOuterContainerClasses,
|
||||
additionalRendererClasses,
|
||||
onFirstHeadingChange,
|
||||
onFrontmatterChange,
|
||||
onMakeScrollSource,
|
||||
onTaskCheckedChange,
|
||||
baseUrl,
|
||||
|
@ -48,7 +48,8 @@ export const MarkdownDocument: React.FC<MarkdownDocumentProps> = ({
|
|||
onScroll,
|
||||
scrollState,
|
||||
onHeightChange,
|
||||
disableToc
|
||||
disableToc,
|
||||
frontmatterInfo
|
||||
}) => {
|
||||
const rendererRef = useRef<HTMLDivElement | null>(null)
|
||||
const rendererSize = useResizeObserver({ ref: rendererRef.current })
|
||||
|
@ -85,19 +86,20 @@ export const MarkdownDocument: React.FC<MarkdownDocumentProps> = ({
|
|||
onMouseEnter={onMakeScrollSource}>
|
||||
<div className={'markdown-document-side'} />
|
||||
<div className={'markdown-document-content'}>
|
||||
<YamlArrayDeprecationAlert />
|
||||
<InvalidYamlAlert show={!!frontmatterInfo?.frontmatterInvalid} />
|
||||
<YamlArrayDeprecationAlert show={!!frontmatterInfo?.deprecatedSyntax} />
|
||||
<BasicMarkdownRenderer
|
||||
outerContainerRef={rendererRef}
|
||||
className={`mb-3 ${additionalRendererClasses ?? ''}`}
|
||||
content={markdownContent}
|
||||
onFirstHeadingChange={onFirstHeadingChange}
|
||||
onLineMarkerPositionChanged={onLineMarkerPositionChanged}
|
||||
onFrontmatterChange={onFrontmatterChange}
|
||||
onTaskCheckedChange={onTaskCheckedChange}
|
||||
onTocChange={setTocAst}
|
||||
baseUrl={baseUrl}
|
||||
onImageClick={onImageClick}
|
||||
useAlternativeBreaks={useAlternativeBreaks}
|
||||
frontmatterLineOffset={frontmatterInfo?.offsetLines}
|
||||
/>
|
||||
</div>
|
||||
<div className={'markdown-document-side pt-4'}>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { NoteFrontmatter } from '../editor-page/note-frontmatter/note-frontmatter'
|
||||
import { ScrollState } from '../editor-page/synced-scroll/scroll-props'
|
||||
import { RendererFrontmatterInfo } from '../common/note-frontmatter/types'
|
||||
|
||||
export enum RenderIframeMessageType {
|
||||
SET_MARKDOWN_CONTENT = 'SET_MARKDOWN_CONTENT',
|
||||
|
@ -14,12 +14,12 @@ export enum RenderIframeMessageType {
|
|||
ON_FIRST_HEADING_CHANGE = 'ON_FIRST_HEADING_CHANGE',
|
||||
SET_SCROLL_SOURCE_TO_RENDERER = 'SET_SCROLL_SOURCE_TO_RENDERER',
|
||||
SET_SCROLL_STATE = 'SET_SCROLL_STATE',
|
||||
ON_SET_FRONTMATTER = 'ON_SET_FRONTMATTER',
|
||||
IMAGE_CLICKED = 'IMAGE_CLICKED',
|
||||
ON_HEIGHT_CHANGE = 'ON_HEIGHT_CHANGE',
|
||||
SET_BASE_CONFIGURATION = 'SET_BASE_CONFIGURATION',
|
||||
GET_WORD_COUNT = 'GET_WORD_COUNT',
|
||||
ON_WORD_COUNT_CALCULATED = 'ON_WORD_COUNT_CALCULATED'
|
||||
ON_WORD_COUNT_CALCULATED = 'ON_WORD_COUNT_CALCULATED',
|
||||
SET_FRONTMATTER_INFO = 'SET_FRONTMATTER_INFO'
|
||||
}
|
||||
|
||||
export interface RendererToEditorSimpleMessage {
|
||||
|
@ -72,9 +72,9 @@ export interface OnFirstHeadingChangeMessage {
|
|||
firstHeading: string | undefined
|
||||
}
|
||||
|
||||
export interface OnFrontmatterChangeMessage {
|
||||
type: RenderIframeMessageType.ON_SET_FRONTMATTER
|
||||
frontmatter: NoteFrontmatter | undefined
|
||||
export interface SetFrontmatterInfoMessage {
|
||||
type: RenderIframeMessageType.SET_FRONTMATTER_INFO
|
||||
frontmatterInfo: RendererFrontmatterInfo
|
||||
}
|
||||
|
||||
export interface OnHeightChangeMessage {
|
||||
|
@ -93,12 +93,12 @@ export type EditorToRendererIframeMessage =
|
|||
| SetScrollStateMessage
|
||||
| SetBaseUrlMessage
|
||||
| GetWordCountMessage
|
||||
| SetFrontmatterInfoMessage
|
||||
|
||||
export type RendererToEditorIframeMessage =
|
||||
| RendererToEditorSimpleMessage
|
||||
| OnFirstHeadingChangeMessage
|
||||
| OnTaskCheckboxChangeMessage
|
||||
| OnFrontmatterChangeMessage
|
||||
| SetScrollStateMessage
|
||||
| ImageClickedMessage
|
||||
| OnHeightChangeMessage
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue