mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-13 22:54:42 -04:00
Reorganize redux and hooks (1/4) (#985)
Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
parent
bdf8110676
commit
1b7abf9f27
61 changed files with 898 additions and 986 deletions
|
@ -10,10 +10,10 @@ import { Alert } from 'react-bootstrap'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { InternalLink } from '../common/links/internal-link'
|
||||
import { ShowIf } from '../common/show-if/show-if'
|
||||
import { RawYAMLMetadata, YAMLMetaData } from '../editor/yaml-metadata/yaml-metadata'
|
||||
import { NoteFrontmatter, RawNoteFrontmatter } from '../editor/note-frontmatter/note-frontmatter'
|
||||
import { BasicMarkdownRenderer } from './basic-markdown-renderer'
|
||||
import { useExtractFirstHeadline } from './hooks/use-extract-first-headline'
|
||||
import { usePostMetaDataOnChange } from './hooks/use-post-meta-data-on-change'
|
||||
import { usePostFrontmatterOnChange } from './hooks/use-post-frontmatter-on-change'
|
||||
import { usePostTocAstOnChange } from './hooks/use-post-toc-ast-on-change'
|
||||
import { useReplacerInstanceListCreator } from './hooks/use-replacer-instance-list-creator'
|
||||
import { FullMarkdownItConfigurator } from './markdown-it-configurator/FullMarkdownItConfigurator'
|
||||
|
@ -25,7 +25,7 @@ import { useCalculateLineMarkerPosition } from './utils/calculate-line-marker-po
|
|||
export interface FullMarkdownRendererProps {
|
||||
onFirstHeadingChange?: (firstHeading: string | undefined) => void
|
||||
onLineMarkerPositionChanged?: (lineMarkerPosition: LineMarkerPosition[]) => void
|
||||
onMetaDataChange?: (yamlMetaData: YAMLMetaData | undefined) => void
|
||||
onFrontmatterChange?: (frontmatter: NoteFrontmatter | undefined) => void
|
||||
onTaskCheckedChange?: (lineInMarkdown: number, checked: boolean) => void
|
||||
onTocChange?: (ast: TocAst) => void
|
||||
rendererRef?: Ref<HTMLDivElement>
|
||||
|
@ -37,7 +37,7 @@ export const FullMarkdownRenderer: React.FC<FullMarkdownRendererProps & Addition
|
|||
{
|
||||
onFirstHeadingChange,
|
||||
onLineMarkerPositionChanged,
|
||||
onMetaDataChange,
|
||||
onFrontmatterChange,
|
||||
onTaskCheckedChange,
|
||||
onTocChange,
|
||||
content,
|
||||
|
@ -53,11 +53,11 @@ export const FullMarkdownRenderer: React.FC<FullMarkdownRendererProps & Addition
|
|||
const [showYamlError, setShowYamlError] = useState(false)
|
||||
const hasNewYamlError = useRef(false)
|
||||
|
||||
const rawMetaRef = useRef<RawYAMLMetadata>()
|
||||
const rawMetaRef = useRef<RawNoteFrontmatter>()
|
||||
const firstHeadingRef = useRef<string>()
|
||||
const documentElement = useRef<HTMLDivElement>(null)
|
||||
const currentLineMarkers = useRef<LineMarkers[]>()
|
||||
usePostMetaDataOnChange(rawMetaRef.current, firstHeadingRef.current, onMetaDataChange, onFirstHeadingChange)
|
||||
usePostFrontmatterOnChange(rawMetaRef.current, firstHeadingRef.current, onFrontmatterChange, onFirstHeadingChange)
|
||||
useCalculateLineMarkerPosition(documentElement, currentLineMarkers.current, onLineMarkerPositionChanged, documentElement.current?.offsetTop ?? 0)
|
||||
useExtractFirstHeadline(documentElement, content, onFirstHeadingChange)
|
||||
|
||||
|
@ -66,7 +66,7 @@ export const FullMarkdownRenderer: React.FC<FullMarkdownRendererProps & Addition
|
|||
|
||||
const markdownIt = useMemo(() => {
|
||||
return (new FullMarkdownItConfigurator(
|
||||
!!onMetaDataChange,
|
||||
!!onFrontmatterChange,
|
||||
errorState => hasNewYamlError.current = errorState,
|
||||
rawMeta => {
|
||||
rawMetaRef.current = rawMeta
|
||||
|
@ -78,9 +78,9 @@ export const FullMarkdownRenderer: React.FC<FullMarkdownRendererProps & Addition
|
|||
currentLineMarkers.current = lineMarkers
|
||||
}
|
||||
)).buildConfiguredMarkdownIt()
|
||||
}, [onMetaDataChange])
|
||||
}, [onFrontmatterChange])
|
||||
|
||||
const clearMetadata = useCallback(() => {
|
||||
const clearFrontmatter = useCallback(() => {
|
||||
hasNewYamlError.current = false
|
||||
rawMetaRef.current = undefined
|
||||
}, [])
|
||||
|
@ -107,7 +107,7 @@ export const FullMarkdownRenderer: React.FC<FullMarkdownRendererProps & Addition
|
|||
componentReplacers={allReplacers}
|
||||
markdownIt={markdownIt}
|
||||
documentReference={documentElement}
|
||||
onBeforeRendering={clearMetadata}
|
||||
onBeforeRendering={clearFrontmatter}
|
||||
onAfterRendering={checkYamlErrorState}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect } from 'react'
|
||||
import React, { useCallback, useEffect, useRef } from 'react'
|
||||
|
||||
export const useExtractFirstHeadline = (documentElement: React.RefObject<HTMLDivElement>, content: string, onFirstHeadingChange?: (firstHeading: string | undefined) => void): void => {
|
||||
const extractInnerText = useCallback((node: ChildNode): string => {
|
||||
const extractInnerText = useCallback((node: ChildNode | null): string => {
|
||||
if (!node) {
|
||||
return ''
|
||||
}
|
||||
|
||||
let innerText = ''
|
||||
|
||||
if ((node as HTMLElement).classList?.contains("katex-mathml")) {
|
||||
|
@ -15,7 +19,9 @@ export const useExtractFirstHeadline = (documentElement: React.RefObject<HTMLDiv
|
|||
}
|
||||
|
||||
if (node.childNodes && node.childNodes.length > 0) {
|
||||
node.childNodes.forEach((child) => { innerText += extractInnerText(child) })
|
||||
node.childNodes.forEach((child) => {
|
||||
innerText += extractInnerText(child)
|
||||
})
|
||||
} else if (node.nodeName === 'IMG') {
|
||||
innerText += (node as HTMLImageElement).getAttribute('alt')
|
||||
} else {
|
||||
|
@ -24,14 +30,17 @@ export const useExtractFirstHeadline = (documentElement: React.RefObject<HTMLDiv
|
|||
return innerText
|
||||
}, [])
|
||||
|
||||
const lastFirstHeading = useRef<string | undefined>()
|
||||
|
||||
useEffect(() => {
|
||||
if (onFirstHeadingChange && documentElement.current) {
|
||||
const firstHeading = documentElement.current.getElementsByTagName('h1').item(0)
|
||||
if (firstHeading) {
|
||||
onFirstHeadingChange(extractInnerText(firstHeading))
|
||||
} else {
|
||||
onFirstHeadingChange(undefined)
|
||||
const headingText = extractInnerText(firstHeading)
|
||||
if (headingText === lastFirstHeading.current) {
|
||||
return
|
||||
}
|
||||
lastFirstHeading.current = headingText
|
||||
onFirstHeadingChange(headingText)
|
||||
}
|
||||
}, [documentElement, extractInnerText, onFirstHeadingChange, content])
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import equal from 'fast-deep-equal'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { NoteFrontmatter, RawNoteFrontmatter } from '../../editor/note-frontmatter/note-frontmatter'
|
||||
|
||||
export const usePostFrontmatterOnChange = (
|
||||
rawFrontmatter: RawNoteFrontmatter | undefined,
|
||||
firstHeadingRef: string | undefined,
|
||||
onFrontmatterChange?: (frontmatter: NoteFrontmatter | undefined) => void,
|
||||
onFirstHeadingChange?: (firstHeading: string | undefined) => void
|
||||
): void => {
|
||||
const oldMetaRef = useRef<RawNoteFrontmatter>()
|
||||
const oldFirstHeadingRef = useRef<string>()
|
||||
|
||||
useEffect(() => {
|
||||
if (onFrontmatterChange && !equal(oldMetaRef.current, rawFrontmatter)) {
|
||||
if (rawFrontmatter) {
|
||||
const newFrontmatter = new NoteFrontmatter(rawFrontmatter)
|
||||
onFrontmatterChange(newFrontmatter)
|
||||
} else {
|
||||
onFrontmatterChange(undefined)
|
||||
}
|
||||
oldMetaRef.current = rawFrontmatter
|
||||
}
|
||||
if (onFirstHeadingChange && !equal(firstHeadingRef, oldFirstHeadingRef.current)) {
|
||||
onFirstHeadingChange(firstHeadingRef || undefined)
|
||||
oldFirstHeadingRef.current = firstHeadingRef
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import equal from 'fast-deep-equal'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { RawYAMLMetadata, YAMLMetaData } from '../../editor/yaml-metadata/yaml-metadata'
|
||||
|
||||
export const usePostMetaDataOnChange = (
|
||||
rawMetaRef: RawYAMLMetadata|undefined,
|
||||
firstHeadingRef: string|undefined,
|
||||
onMetaDataChange?: (yamlMetaData: YAMLMetaData | undefined) => void,
|
||||
onFirstHeadingChange?: (firstHeading: string | undefined) => void
|
||||
): void => {
|
||||
const oldMetaRef = useRef<RawYAMLMetadata>()
|
||||
const oldFirstHeadingRef = useRef<string>()
|
||||
|
||||
useEffect(() => {
|
||||
if (onMetaDataChange && !equal(oldMetaRef.current, rawMetaRef)) {
|
||||
if (rawMetaRef) {
|
||||
const newMetaData = new YAMLMetaData(rawMetaRef)
|
||||
onMetaDataChange(newMetaData)
|
||||
} else {
|
||||
onMetaDataChange(undefined)
|
||||
}
|
||||
oldMetaRef.current = rawMetaRef
|
||||
}
|
||||
if (onFirstHeadingChange && !equal(firstHeadingRef, oldFirstHeadingRef.current)) {
|
||||
onFirstHeadingChange(firstHeadingRef || undefined)
|
||||
oldFirstHeadingRef.current = firstHeadingRef
|
||||
}
|
||||
})
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import { TocAst } from 'markdown-it-toc-done-right'
|
||||
import { RawYAMLMetadata } from '../../editor/yaml-metadata/yaml-metadata'
|
||||
import { RawNoteFrontmatter } from '../../editor/note-frontmatter/note-frontmatter'
|
||||
import { documentToc } from '../markdown-it-plugins/document-toc'
|
||||
import { frontmatterExtract } from '../markdown-it-plugins/frontmatter'
|
||||
import { headlineAnchors } from '../markdown-it-plugins/headline-anchors'
|
||||
|
@ -28,7 +28,7 @@ export class FullMarkdownItConfigurator extends BasicMarkdownItConfigurator {
|
|||
constructor (
|
||||
private useFrontmatter: boolean,
|
||||
private passYamlErrorState: (error: boolean) => void,
|
||||
private onRawMeta: (rawMeta: RawYAMLMetadata) => void,
|
||||
private onRawMeta: (rawMeta: RawNoteFrontmatter) => void,
|
||||
private onToc: (toc: TocAst) => void,
|
||||
private onLineMarkers: (lineMarkers: LineMarkers[]) => void
|
||||
) {
|
||||
|
@ -45,8 +45,8 @@ export class FullMarkdownItConfigurator extends BasicMarkdownItConfigurator {
|
|||
!this.useFrontmatter
|
||||
? undefined
|
||||
: {
|
||||
onYamlError: (hasError: boolean) => this.passYamlErrorState(hasError),
|
||||
onRawMeta: (rawMeta: RawYAMLMetadata) => this.onRawMeta(rawMeta)
|
||||
onParseError: (hasError: boolean) => this.passYamlErrorState(hasError),
|
||||
onRawMeta: (rawMeta: RawNoteFrontmatter) => this.onRawMeta(rawMeta)
|
||||
})
|
||||
},
|
||||
headlineAnchors,
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
import yaml from 'js-yaml'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import frontmatter from 'markdown-it-front-matter'
|
||||
import { RawYAMLMetadata } from '../../editor/yaml-metadata/yaml-metadata'
|
||||
import { RawNoteFrontmatter } from '../../editor/note-frontmatter/note-frontmatter'
|
||||
|
||||
interface FrontmatterPluginOptions {
|
||||
onYamlError: (error: boolean) => void,
|
||||
onRawMeta: (rawMeta: RawYAMLMetadata) => void,
|
||||
onParseError: (error: boolean) => void,
|
||||
onRawMeta: (rawMeta: RawNoteFrontmatter) => void,
|
||||
}
|
||||
|
||||
export const frontmatterExtract: MarkdownIt.PluginWithOptions<FrontmatterPluginOptions> = (markdownIt: MarkdownIt, options) => {
|
||||
|
@ -20,13 +20,13 @@ export const frontmatterExtract: MarkdownIt.PluginWithOptions<FrontmatterPluginO
|
|||
}
|
||||
frontmatter(markdownIt, (rawMeta: string) => {
|
||||
try {
|
||||
const meta: RawYAMLMetadata = yaml.load(rawMeta) as RawYAMLMetadata
|
||||
options.onYamlError(false)
|
||||
const meta: RawNoteFrontmatter = yaml.load(rawMeta) as RawNoteFrontmatter
|
||||
options.onParseError(false)
|
||||
options.onRawMeta(meta)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
options.onYamlError(true)
|
||||
options.onRawMeta({} as RawYAMLMetadata)
|
||||
options.onParseError(true)
|
||||
options.onRawMeta({} as RawNoteFrontmatter)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue