-
-
+
+
+
+
{ markdownReactDom }
)
}
+
+export default BasicMarkdownRenderer
diff --git a/src/components/markdown-renderer/document-length-limit-reached-alert.tsx b/src/components/markdown-renderer/document-length-limit-reached-alert.tsx
index e0b910f2b..c5d031124 100644
--- a/src/components/markdown-renderer/document-length-limit-reached-alert.tsx
+++ b/src/components/markdown-renderer/document-length-limit-reached-alert.tsx
@@ -10,17 +10,15 @@ import { Trans, useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { ApplicationState } from '../../redux'
import { ShowIf } from '../common/show-if/show-if'
+import { SimpleAlertProps } from '../common/simple-alert/simple-alert-props'
-export interface DocumentLengthLimitReachedAlertProps {
- contentLength: number
-}
-
-export const DocumentLengthLimitReachedAlert: React.FC
= ({ contentLength }) => {
+export const DocumentLengthLimitReachedAlert: React.FC = ({ show }) => {
useTranslation()
+
const maxLength = useSelector((state: ApplicationState) => state.config.maxDocumentLength)
return (
- maxLength }>
+
diff --git a/src/components/markdown-renderer/full-markdown-renderer.tsx b/src/components/markdown-renderer/full-markdown-renderer.tsx
deleted file mode 100644
index 173ad5736..000000000
--- a/src/components/markdown-renderer/full-markdown-renderer.tsx
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
- *
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-import { TocAst } from 'markdown-it-toc-done-right'
-import React, { Ref, useCallback, useMemo, useRef, useState } from 'react'
-import { useTranslation } from 'react-i18next'
-import { NoteFrontmatter, RawNoteFrontmatter } from '../editor-page/note-frontmatter/note-frontmatter'
-import { BasicMarkdownRenderer } from './basic-markdown-renderer'
-import { useExtractFirstHeadline } from './hooks/use-extract-first-headline'
-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 { InvalidYamlAlert } from './invalid-yaml-alert'
-import { FullMarkdownItConfigurator } from './markdown-it-configurator/FullMarkdownItConfigurator'
-import { ImageClickHandler } from './replace-components/image/image-replacer'
-import { LineMarkers } from './replace-components/linemarker/line-number-marker'
-import { AdditionalMarkdownRendererProps, LineMarkerPosition } from './types'
-import { useCalculateLineMarkerPosition } from './utils/calculate-line-marker-positions'
-
-export interface FullMarkdownRendererProps {
- onFirstHeadingChange?: (firstHeading: string | undefined) => void
- onLineMarkerPositionChanged?: (lineMarkerPosition: LineMarkerPosition[]) => void
- onFrontmatterChange?: (frontmatter: NoteFrontmatter | undefined) => void
- onTaskCheckedChange?: (lineInMarkdown: number, checked: boolean) => void
- onTocChange?: (ast: TocAst) => void
- rendererRef?: Ref
- baseUrl?: string
- onImageClick?: ImageClickHandler
-}
-
-export const FullMarkdownRenderer: React.FC = (
- {
- onFirstHeadingChange,
- onLineMarkerPositionChanged,
- onFrontmatterChange,
- onTaskCheckedChange,
- onTocChange,
- content,
- className,
- rendererRef,
- baseUrl,
- onImageClick
- }) => {
- const allReplacers = useReplacerInstanceListCreator(onTaskCheckedChange, onImageClick, baseUrl)
- useTranslation()
-
- const [showYamlError, setShowYamlError] = useState(false)
- const hasNewYamlError = useRef(false)
-
- const rawMetaRef = useRef()
- const firstHeadingRef = useRef()
- const documentElement = useRef(null)
- const currentLineMarkers = useRef()
- usePostFrontmatterOnChange(rawMetaRef.current, firstHeadingRef.current, onFrontmatterChange, onFirstHeadingChange)
- useCalculateLineMarkerPosition(documentElement, currentLineMarkers.current, onLineMarkerPositionChanged, documentElement.current?.offsetTop ?? 0)
- useExtractFirstHeadline(documentElement, content, onFirstHeadingChange)
-
- const tocAst = useRef()
- usePostTocAstOnChange(tocAst, onTocChange)
-
- const markdownIt = useMemo(() => {
- return (new FullMarkdownItConfigurator(
- !!onFrontmatterChange,
- errorState => hasNewYamlError.current = errorState,
- rawMeta => {
- rawMetaRef.current = rawMeta
- },
- toc => {
- tocAst.current = toc
- },
- onLineMarkerPositionChanged === undefined
- ? undefined
- : lineMarkers => {
- currentLineMarkers.current = lineMarkers
- }
- )).buildConfiguredMarkdownIt()
- }, [onLineMarkerPositionChanged, onFrontmatterChange])
-
- const clearFrontmatter = useCallback(() => {
- hasNewYamlError.current = false
- rawMetaRef.current = undefined
- }, [])
-
- const checkYamlErrorState = useCallback(() => {
- if (hasNewYamlError.current !== showYamlError) {
- setShowYamlError(hasNewYamlError.current)
- }
- }, [setShowYamlError, showYamlError])
-
- return (
-
-
-
-
- )
-}
diff --git a/src/components/markdown-renderer/hooks/use-replacer-instance-list-creator.ts b/src/components/markdown-renderer/hooks/use-component-replacers.ts
similarity index 87%
rename from src/components/markdown-renderer/hooks/use-replacer-instance-list-creator.ts
rename to src/components/markdown-renderer/hooks/use-component-replacers.ts
index 87ac97716..80bbef93a 100644
--- a/src/components/markdown-renderer/hooks/use-replacer-instance-list-creator.ts
+++ b/src/components/markdown-renderer/hooks/use-component-replacers.ts
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { useMemo } from 'react'
+import { useCallback } from 'react'
import { AbcReplacer } from '../replace-components/abc/abc-replacer'
import { AsciinemaReplacer } from '../replace-components/asciinema/asciinema-replacer'
import { ComponentReplacer } from '../replace-components/ComponentReplacer'
@@ -21,14 +21,13 @@ import { MarkmapReplacer } from '../replace-components/markmap/markmap-replacer'
import { MermaidReplacer } from '../replace-components/mermaid/mermaid-replacer'
import { ColoredBlockquoteReplacer } from '../replace-components/colored-blockquote/colored-blockquote-replacer'
import { SequenceDiagramReplacer } from '../replace-components/sequence-diagram/sequence-diagram-replacer'
-import { TaskListReplacer } from '../replace-components/task-list/task-list-replacer'
+import { TaskCheckedChangeHandler, TaskListReplacer } from '../replace-components/task-list/task-list-replacer'
import { VegaReplacer } from '../replace-components/vega-lite/vega-replacer'
import { VimeoReplacer } from '../replace-components/vimeo/vimeo-replacer'
import { YoutubeReplacer } from '../replace-components/youtube/youtube-replacer'
-export const useReplacerInstanceListCreator = (onTaskCheckedChange?: (lineInMarkdown: number, checked: boolean) => void,
- onImageClick?: ImageClickHandler, baseUrl?: string): () => ComponentReplacer[] => useMemo(() =>
- () => [
+export const useComponentReplacers = (onTaskCheckedChange?: TaskCheckedChangeHandler, onImageClick?: ImageClickHandler, baseUrl?: string): () => ComponentReplacer[] =>
+ useCallback(() => [
new LinemarkerReplacer(),
new GistReplacer(),
new YoutubeReplacer(),
diff --git a/src/components/markdown-renderer/hooks/use-convert-markdown-to-react-dom.ts b/src/components/markdown-renderer/hooks/use-convert-markdown-to-react-dom.ts
index 33eb31ed2..16bb38350 100644
--- a/src/components/markdown-renderer/hooks/use-convert-markdown-to-react-dom.ts
+++ b/src/components/markdown-renderer/hooks/use-convert-markdown-to-react-dom.ts
@@ -15,7 +15,8 @@ import { calculateNewLineNumberMapping } from '../utils/line-number-mapping'
export const useConvertMarkdownToReactDom = (
markdownCode: string,
markdownIt: MarkdownIt,
- componentReplacers?: () => ComponentReplacer[],
+ baseReplacers: () => ComponentReplacer[],
+ additionalReplacers?: () => ComponentReplacer[],
onBeforeRendering?: () => void,
onAfterRendering?: () => void): ReactElement[] => {
const oldMarkdownLineKeys = useRef()
@@ -33,11 +34,14 @@ export const useConvertMarkdownToReactDom = (
} = calculateNewLineNumberMapping(contentLines, oldMarkdownLineKeys.current ?? [], lastUsedLineId.current)
oldMarkdownLineKeys.current = newLines
lastUsedLineId.current = newLastUsedLineId
- const transformer = componentReplacers ? buildTransformer(newLines, componentReplacers()) : undefined
+
+ const replacers = baseReplacers()
+ .concat(additionalReplacers ? additionalReplacers() : [])
+ const transformer = replacers.length > 0 ? buildTransformer(newLines, replacers) : undefined
const rendering = ReactHtmlParser(html, { transform: transformer })
if (onAfterRendering) {
onAfterRendering()
}
return rendering
- }, [onBeforeRendering, onAfterRendering, markdownCode, markdownIt, componentReplacers])
+ }, [onBeforeRendering, markdownIt, markdownCode, baseReplacers, additionalReplacers, onAfterRendering])
}
diff --git a/src/components/markdown-renderer/hooks/use-extract-first-headline.ts b/src/components/markdown-renderer/hooks/use-extract-first-headline.ts
index 7b14319e6..7af4bcb58 100644
--- a/src/components/markdown-renderer/hooks/use-extract-first-headline.ts
+++ b/src/components/markdown-renderer/hooks/use-extract-first-headline.ts
@@ -12,12 +12,12 @@ export const useExtractFirstHeadline = (documentElement: React.RefObject 0) {
node.childNodes.forEach((child) => {
innerText += extractInnerText(child)
@@ -37,11 +37,11 @@ export const useExtractFirstHeadline = (documentElement: React.RefObject(reference: MutableRefObject, onChange?: (newValue?: T) => void): void => {
+ const lastValue = useRef()
+ useEffect(() => {
+ if (onChange && !equal(reference, lastValue.current)) {
+ lastValue.current = reference.current
+ onChange(reference.current)
+ }
+ })
+}
diff --git a/src/components/markdown-renderer/hooks/use-post-frontmatter-on-change.ts b/src/components/markdown-renderer/hooks/use-post-frontmatter-on-change.ts
deleted file mode 100644
index 5875f105b..000000000
--- a/src/components/markdown-renderer/hooks/use-post-frontmatter-on-change.ts
+++ /dev/null
@@ -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 { NoteFrontmatter, RawNoteFrontmatter } from '../../editor-page/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()
- const oldFirstHeadingRef = useRef()
-
- 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
- }
- })
-}
diff --git a/src/components/markdown-renderer/hooks/use-post-toc-ast-on-change.ts b/src/components/markdown-renderer/hooks/use-post-toc-ast-on-change.ts
deleted file mode 100644
index 6db684875..000000000
--- a/src/components/markdown-renderer/hooks/use-post-toc-ast-on-change.ts
+++ /dev/null
@@ -1,19 +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 { TocAst } from 'markdown-it-toc-done-right'
-import { RefObject, useEffect, useRef } from 'react'
-
-export const usePostTocAstOnChange = (tocAst: RefObject, onTocChange?: (ast: TocAst) => void): void => {
- const lastTocAst = useRef()
- useEffect(() => {
- if (onTocChange && tocAst.current && !equal(tocAst, lastTocAst.current)) {
- lastTocAst.current = tocAst.current
- onTocChange(tocAst.current)
- }
- })
-}
diff --git a/src/components/markdown-renderer/hooks/use-trimmed-content.ts b/src/components/markdown-renderer/hooks/use-trimmed-content.ts
new file mode 100644
index 000000000..075c77f7f
--- /dev/null
+++ b/src/components/markdown-renderer/hooks/use-trimmed-content.ts
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { useSelector } from 'react-redux'
+import { ApplicationState } from '../../../redux'
+import { useMemo } from 'react'
+
+export const useTrimmedContent = (content: string): [trimmedContent: string, contentExceedsLimit: boolean] => {
+ const maxLength = useSelector((state: ApplicationState) => state.config.maxDocumentLength)
+ const contentExceedsLimit = content.length > maxLength
+
+ const trimmedContent = useMemo(() => contentExceedsLimit ? content.substr(0, maxLength) : content, [content,
+ contentExceedsLimit,
+ maxLength])
+ return [trimmedContent, contentExceedsLimit]
+}
diff --git a/src/components/markdown-renderer/invalid-yaml-alert.tsx b/src/components/markdown-renderer/invalid-yaml-alert.tsx
index 3b7015a42..a0842eff4 100644
--- a/src/components/markdown-renderer/invalid-yaml-alert.tsx
+++ b/src/components/markdown-renderer/invalid-yaml-alert.tsx
@@ -9,16 +9,13 @@ 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 { SimpleAlertProps } from '../common/simple-alert/simple-alert-props'
-export interface InvalidYamlAlertProps {
- showYamlError: boolean
-}
-
-export const InvalidYamlAlert: React.FC = ({ showYamlError }) => {
+export const InvalidYamlAlert: React.FC = ({ show }) => {
useTranslation()
return (
-
+
diff --git a/src/components/markdown-renderer/markdown-it-configurator/BasicMarkdownItConfigurator.tsx b/src/components/markdown-renderer/markdown-it-configurator/BasicMarkdownItConfigurator.tsx
index 9d450ccd2..9633581e5 100644
--- a/src/components/markdown-renderer/markdown-it-configurator/BasicMarkdownItConfigurator.tsx
+++ b/src/components/markdown-renderer/markdown-it-configurator/BasicMarkdownItConfigurator.tsx
@@ -1,7 +1,7 @@
/*
- SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
-
- SPDX-License-Identifier: AGPL-3.0-only
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
import MarkdownIt from 'markdown-it'
@@ -19,11 +19,78 @@ import { MarkdownItParserDebugger } from '../markdown-it-plugins/parser-debugger
import { spoilerContainer } from '../markdown-it-plugins/spoiler-container'
import { tasksLists } from '../markdown-it-plugins/tasks-lists'
import { twitterEmojis } from '../markdown-it-plugins/twitter-emojis'
-import { MarkdownItConfigurator } from './MarkdownItConfigurator'
+import { RawNoteFrontmatter } from '../../editor-page/note-frontmatter/note-frontmatter'
+import { TocAst } from 'markdown-it-toc-done-right'
+import { LineMarkers, lineNumberMarker } from '../replace-components/linemarker/line-number-marker'
+import { plantumlWithError } from '../markdown-it-plugins/plantuml'
+import { headlineAnchors } from '../markdown-it-plugins/headline-anchors'
+import { KatexReplacer } from '../replace-components/katex/katex-replacer'
+import { YoutubeReplacer } from '../replace-components/youtube/youtube-replacer'
+import { VimeoReplacer } from '../replace-components/vimeo/vimeo-replacer'
+import { GistReplacer } from '../replace-components/gist/gist-replacer'
+import { legacyPdfShortCode } from '../regex-plugins/replace-legacy-pdf-short-code'
+import { legacySlideshareShortCode } from '../regex-plugins/replace-legacy-slideshare-short-code'
+import { legacySpeakerdeckShortCode } from '../regex-plugins/replace-legacy-speakerdeck-short-code'
+import { AsciinemaReplacer } from '../replace-components/asciinema/asciinema-replacer'
+import { highlightedCode } from '../markdown-it-plugins/highlighted-code'
+import { quoteExtraColor } from '../markdown-it-plugins/quote-extra-color'
+import { quoteExtra } from '../markdown-it-plugins/quote-extra'
+import { documentTableOfContents } from '../markdown-it-plugins/document-table-of-contents'
+import { frontmatterExtract } from '../markdown-it-plugins/frontmatter'
+
+export interface ConfiguratorDetails {
+ useFrontmatter: boolean,
+ onParseError: (error: boolean) => void,
+ onRawMetaChange: (rawMeta: RawNoteFrontmatter) => void,
+ onToc: (toc: TocAst) => void,
+ onLineMarkers?: (lineMarkers: LineMarkers[]) => void
+ useAlternativeBreaks?: boolean
+}
+
+export class BasicMarkdownItConfigurator {
+ protected readonly options: T
+ protected configurations: MarkdownIt.PluginSimple[] = []
+ protected postConfigurations: MarkdownIt.PluginSimple[] = []
+
+ constructor(options: T) {
+ this.options = options
+ }
+
+ public pushConfig(plugin: MarkdownIt.PluginSimple): this {
+ this.configurations.push(plugin)
+ return this
+ }
+
+ public buildConfiguredMarkdownIt(): MarkdownIt {
+ const markdownIt = new MarkdownIt('default', {
+ html: true,
+ breaks: this.options.useAlternativeBreaks ?? true,
+ langPrefix: '',
+ typographer: true
+ })
+ this.configure(markdownIt)
+ this.configurations.forEach((configuration) => markdownIt.use(configuration))
+ this.postConfigurations.forEach((postConfiguration) => markdownIt.use(postConfiguration))
+ return markdownIt
+ }
-export class BasicMarkdownItConfigurator extends MarkdownItConfigurator {
protected configure(markdownIt: MarkdownIt): void {
this.configurations.push(
+ plantumlWithError,
+ headlineAnchors,
+ KatexReplacer.markdownItPlugin,
+ YoutubeReplacer.markdownItPlugin,
+ VimeoReplacer.markdownItPlugin,
+ GistReplacer.markdownItPlugin,
+ legacyPdfShortCode,
+ legacySlideshareShortCode,
+ legacySpeakerdeckShortCode,
+ AsciinemaReplacer.markdownItPlugin,
+ highlightedCode,
+ quoteExtraColor,
+ quoteExtra('name', 'user'),
+ quoteExtra('time', 'clock-o'),
+ documentTableOfContents(this.options.onToc),
twitterEmojis,
abbreviation,
definitionList,
@@ -35,8 +102,19 @@ export class BasicMarkdownItConfigurator extends MarkdownItConfigurator {
imsize,
tasksLists,
alertContainer,
- spoilerContainer
- )
+ spoilerContainer)
+
+ if (this.options.useFrontmatter) {
+ this.configurations.push(frontmatterExtract({
+ onParseError: this.options.onParseError,
+ onRawMetaChange: this.options.onRawMetaChange
+ }))
+ }
+
+ if (this.options.onLineMarkers) {
+ this.configurations.push(lineNumberMarker(this.options.onLineMarkers))
+ }
+
this.postConfigurations.push(
linkifyExtra,
MarkdownItParserDebugger
diff --git a/src/components/markdown-renderer/markdown-it-configurator/FullMarkdownItConfigurator.tsx b/src/components/markdown-renderer/markdown-it-configurator/FullMarkdownItConfigurator.tsx
deleted file mode 100644
index 52aa7ecd9..000000000
--- a/src/components/markdown-renderer/markdown-it-configurator/FullMarkdownItConfigurator.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
- *
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-
-import MarkdownIt from 'markdown-it'
-import { TocAst } from 'markdown-it-toc-done-right'
-import { RawNoteFrontmatter } from '../../editor-page/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'
-import { highlightedCode } from '../markdown-it-plugins/highlighted-code'
-import { plantumlWithError } from '../markdown-it-plugins/plantuml'
-import { quoteExtra } from '../markdown-it-plugins/quote-extra'
-import { legacySlideshareShortCode } from '../regex-plugins/replace-legacy-slideshare-short-code'
-import { legacySpeakerdeckShortCode } from '../regex-plugins/replace-legacy-speakerdeck-short-code'
-import { AsciinemaReplacer } from '../replace-components/asciinema/asciinema-replacer'
-import { GistReplacer } from '../replace-components/gist/gist-replacer'
-import { KatexReplacer } from '../replace-components/katex/katex-replacer'
-import { LineMarkers, lineNumberMarker } from '../replace-components/linemarker/line-number-marker'
-import { VimeoReplacer } from '../replace-components/vimeo/vimeo-replacer'
-import { YoutubeReplacer } from '../replace-components/youtube/youtube-replacer'
-import { BasicMarkdownItConfigurator } from './BasicMarkdownItConfigurator'
-import { quoteExtraColor } from '../markdown-it-plugins/quote-extra-color'
-import { legacyPdfShortCode } from '../regex-plugins/replace-legacy-pdf-short-code'
-
-export class FullMarkdownItConfigurator extends BasicMarkdownItConfigurator {
- constructor(
- private useFrontmatter: boolean,
- private passYamlErrorState: (error: boolean) => void,
- private onRawMeta: (rawMeta: RawNoteFrontmatter) => void,
- private onToc: (toc: TocAst) => void,
- private onLineMarkers?: (lineMarkers: LineMarkers[]) => void
- ) {
- super()
- }
-
- protected configure(markdownIt: MarkdownIt): void {
- super.configure(markdownIt)
-
- this.configurations.push(
- plantumlWithError,
- (markdownIt) => {
- frontmatterExtract(markdownIt,
- !this.useFrontmatter
- ? undefined
- : {
- onParseError: (hasError: boolean) => this.passYamlErrorState(hasError),
- onRawMeta: (rawMeta: RawNoteFrontmatter) => this.onRawMeta(rawMeta)
- })
- },
- headlineAnchors,
- KatexReplacer.markdownItPlugin,
- YoutubeReplacer.markdownItPlugin,
- VimeoReplacer.markdownItPlugin,
- GistReplacer.markdownItPlugin,
- legacyPdfShortCode,
- legacySlideshareShortCode,
- legacySpeakerdeckShortCode,
- AsciinemaReplacer.markdownItPlugin,
- highlightedCode,
- quoteExtraColor,
- quoteExtra({
- quoteLabel: 'name',
- icon: 'user'
- }),
- quoteExtra({
- quoteLabel: 'time',
- icon: 'clock-o'
- }),
- (markdownIt) => documentToc(markdownIt, this.onToc))
- if (this.onLineMarkers) {
- const callback = this.onLineMarkers
- this.configurations.push(
- (markdownIt) => lineNumberMarker(markdownIt, (lineMarkers) => callback(lineMarkers))
- )
- }
- }
-}
diff --git a/src/components/markdown-renderer/markdown-it-configurator/MarkdownItConfigurator.tsx b/src/components/markdown-renderer/markdown-it-configurator/MarkdownItConfigurator.tsx
deleted file mode 100644
index 51e5e3a1f..000000000
--- a/src/components/markdown-renderer/markdown-it-configurator/MarkdownItConfigurator.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
-
- SPDX-License-Identifier: AGPL-3.0-only
- */
-
-import MarkdownIt from 'markdown-it'
-
-export abstract class MarkdownItConfigurator {
- protected configurations: MarkdownIt.PluginSimple[] = []
- protected postConfigurations: MarkdownIt.PluginSimple[] = []
-
- public pushConfig(plugin: MarkdownIt.PluginSimple): this {
- this.configurations.push(plugin)
- return this
- }
-
- public buildConfiguredMarkdownIt(): MarkdownIt {
- const markdownIt = new MarkdownIt('default', {
- html: true,
- breaks: true,
- langPrefix: '',
- typographer: true
- })
- this.configure(markdownIt)
- this.configurations.forEach((configuration) => markdownIt.use(configuration))
- this.postConfigurations.forEach((postConfiguration) => markdownIt.use(postConfiguration))
- return markdownIt
- }
-
- protected abstract configure(markdownIt: MarkdownIt): void;
-}
diff --git a/src/components/markdown-renderer/markdown-it-plugins/document-table-of-contents.ts b/src/components/markdown-renderer/markdown-it-plugins/document-table-of-contents.ts
new file mode 100644
index 000000000..b7803a030
--- /dev/null
+++ b/src/components/markdown-renderer/markdown-it-plugins/document-table-of-contents.ts
@@ -0,0 +1,13 @@
+/*
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import MarkdownIt from 'markdown-it/lib'
+import { TocAst } from 'markdown-it-toc-done-right'
+import { documentToc } from './document-toc'
+
+export const documentTableOfContents = (onTocChange: ((toc: TocAst) => void)): MarkdownIt.PluginSimple => {
+ return (markdownIt) => documentToc(markdownIt, onTocChange)
+}
diff --git a/src/components/markdown-renderer/markdown-it-plugins/document-toc.ts b/src/components/markdown-renderer/markdown-it-plugins/document-toc.ts
index 197c9ddd2..b09c6acd1 100644
--- a/src/components/markdown-renderer/markdown-it-plugins/document-toc.ts
+++ b/src/components/markdown-renderer/markdown-it-plugins/document-toc.ts
@@ -6,7 +6,7 @@
import MarkdownIt from 'markdown-it'
import toc, { TocAst } from 'markdown-it-toc-done-right'
-import { slugify } from '../../editor-page/table-of-contents/table-of-contents'
+import { tocSlugify } from '../../editor-page/table-of-contents/toc-slugify'
export type DocumentTocPluginOptions = (ast: TocAst) => void
@@ -21,6 +21,6 @@ export const documentToc: MarkdownIt.PluginWithOptions
callback: (code: string, ast: TocAst): void => {
onToc(ast)
},
- slugify: slugify
+ slugify: tocSlugify
})
}
diff --git a/src/components/markdown-renderer/markdown-it-plugins/frontmatter.ts b/src/components/markdown-renderer/markdown-it-plugins/frontmatter.ts
index 621387e5f..509881dde 100644
--- a/src/components/markdown-renderer/markdown-it-plugins/frontmatter.ts
+++ b/src/components/markdown-renderer/markdown-it-plugins/frontmatter.ts
@@ -11,22 +11,20 @@ import { RawNoteFrontmatter } from '../../editor-page/note-frontmatter/note-fron
interface FrontmatterPluginOptions {
onParseError: (error: boolean) => void,
- onRawMeta: (rawMeta: RawNoteFrontmatter) => void,
+ onRawMetaChange: (rawMeta: RawNoteFrontmatter) => void,
}
-export const frontmatterExtract: MarkdownIt.PluginWithOptions = (markdownIt: MarkdownIt, options) => {
- if (!options) {
- return
+export const frontmatterExtract: (options: FrontmatterPluginOptions) => MarkdownIt.PluginSimple = (options) =>
+ (markdownIt) => {
+ frontmatter(markdownIt, (rawMeta: string) => {
+ try {
+ const meta: RawNoteFrontmatter = yaml.load(rawMeta) as RawNoteFrontmatter
+ options.onParseError(false)
+ options.onRawMetaChange(meta)
+ } catch (e) {
+ console.error(e)
+ options.onParseError(true)
+ options.onRawMetaChange({} as RawNoteFrontmatter)
+ }
+ })
}
- frontmatter(markdownIt, (rawMeta: string) => {
- try {
- const meta: RawNoteFrontmatter = yaml.load(rawMeta) as RawNoteFrontmatter
- options.onParseError(false)
- options.onRawMeta(meta)
- } catch (e) {
- console.error(e)
- options.onParseError(true)
- options.onRawMeta({} as RawNoteFrontmatter)
- }
- })
-}
diff --git a/src/components/markdown-renderer/markdown-it-plugins/quote-extra.ts b/src/components/markdown-renderer/markdown-it-plugins/quote-extra.ts
index 685e182c7..af63eb683 100644
--- a/src/components/markdown-renderer/markdown-it-plugins/quote-extra.ts
+++ b/src/components/markdown-renderer/markdown-it-plugins/quote-extra.ts
@@ -8,17 +8,12 @@ import MarkdownIt from 'markdown-it/lib'
import Token from 'markdown-it/lib/token'
import { IconName } from '../../common/fork-awesome/types'
-export interface QuoteExtraOptions {
- quoteLabel: string
- icon: IconName
-}
-
-export const quoteExtra: (pluginOptions: QuoteExtraOptions) => MarkdownIt.PluginSimple =
- (pluginOptions) => (md) => {
- md.inline.ruler.push(`extraQuote_${ pluginOptions.quoteLabel }`, (state) => {
+export const quoteExtra: (quoteLabel: string, icon: IconName) => MarkdownIt.PluginSimple =
+ (quoteLabel: string, icon: IconName) => (md) => {
+ md.inline.ruler.push(`extraQuote_${ quoteLabel }`, (state) => {
const quoteExtraTagValues = parseQuoteExtraTag(state.src, state.pos, state.posMax)
- if (!quoteExtraTagValues || quoteExtraTagValues.label !== pluginOptions.quoteLabel) {
+ if (!quoteExtraTagValues || quoteExtraTagValues.label !== quoteLabel) {
return false
}
state.pos = quoteExtraTagValues.valueEndIndex + 1
@@ -32,7 +27,7 @@ export const quoteExtra: (pluginOptions: QuoteExtraOptions) => MarkdownIt.Plugin
)
const token = state.push('quote-extra', '', 0)
- token.attrSet('icon', pluginOptions.icon)
+ token.attrSet('icon', icon)
token.children = tokens
return true
diff --git a/src/components/markdown-renderer/replace-components/flow/flowchart/flowchart.tsx b/src/components/markdown-renderer/replace-components/flow/flowchart/flowchart.tsx
index d85688012..d24b68f6e 100644
--- a/src/components/markdown-renderer/replace-components/flow/flowchart/flowchart.tsx
+++ b/src/components/markdown-renderer/replace-components/flow/flowchart/flowchart.tsx
@@ -1,7 +1,7 @@
/*
- SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
-
- SPDX-License-Identifier: AGPL-3.0-only
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { useEffect, useRef, useState } from 'react'
@@ -25,26 +25,25 @@ export const FlowChart: React.FC = ({ code }) => {
return
}
const currentDiagramRef = diagramRef.current
- import(/* webpackChunkName: "flowchart.js" */ 'flowchart.js').then((imp) => {
- const parserOutput = imp.parse(code)
- try {
- parserOutput.drawSVG(currentDiagramRef, {
- 'line-width': 2,
- fill: 'none',
- 'font-size': 16,
- 'line-color': darkModeActivated ? '#ffffff' : '#000000',
- 'element-color': darkModeActivated ? '#ffffff' : '#000000',
- 'font-color': darkModeActivated ? '#ffffff' : '#000000',
- 'font-family': 'Source Sans Pro, "Twemoji Mozilla", monospace'
- })
- setError(false)
- } catch (error) {
- setError(true)
- }
- })
- .catch(() => {
- console.error('error while loading flowchart.js')
- })
+ import(/* webpackChunkName: "flowchart.js" */ 'flowchart.js')
+ .then((imp) => {
+ const parserOutput = imp.parse(code)
+ try {
+ parserOutput.drawSVG(currentDiagramRef, {
+ 'line-width': 2,
+ fill: 'none',
+ 'font-size': 16,
+ 'line-color': darkModeActivated ? '#ffffff' : '#000000',
+ 'element-color': darkModeActivated ? '#ffffff' : '#000000',
+ 'font-color': darkModeActivated ? '#ffffff' : '#000000',
+ 'font-family': 'Source Sans Pro, "Twemoji Mozilla", monospace'
+ })
+ setError(false)
+ } catch (error) {
+ setError(true)
+ }
+ })
+ .catch(() => console.error('error while loading flowchart.js'))
return () => {
Array.from(currentDiagramRef.children)
diff --git a/src/components/markdown-renderer/replace-components/graphviz/graphviz-frame.tsx b/src/components/markdown-renderer/replace-components/graphviz/graphviz-frame.tsx
index 5ee7e2203..b3024d2a0 100644
--- a/src/components/markdown-renderer/replace-components/graphviz/graphviz-frame.tsx
+++ b/src/components/markdown-renderer/replace-components/graphviz/graphviz-frame.tsx
@@ -1,7 +1,7 @@
/*
- SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
-
- SPDX-License-Identifier: AGPL-3.0-only
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
@@ -32,7 +32,7 @@ export const GraphvizFrame: React.FC = ({ code }) => {
}
const actualContainer = container.current
- import('@hpcc-js/wasm')
+ import(/* webpackChunkName: "d3-graphviz" */'@hpcc-js/wasm')
.then((wasmPlugin) => {
wasmPlugin.wasmFolder('/static/js')
})
diff --git a/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.scss b/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.scss
index 0f53c417d..cba9bf038 100644
--- a/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.scss
+++ b/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.scss
@@ -1,13 +1,9 @@
-/*
+/*!
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
-.markdown-body {
-
-}
-
.markdown-body {
@import '../../../../../../node_modules/highlight.js/styles/github';
diff --git a/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.tsx b/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.tsx
index a331d1362..a1c389939 100644
--- a/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.tsx
+++ b/src/components/markdown-renderer/replace-components/highlighted-fence/highlighted-code/highlighted-code.tsx
@@ -17,13 +17,16 @@ export interface HighlightedCodeProps {
wrapLines: boolean
}
-export const escapeHtml = (unsafe: string): string => {
+/*
+ TODO: Test method or rewrite code so this is not necessary anymore
+ */
+const escapeHtml = (unsafe: string): string => {
return unsafe
- .replace(/&/g, '&')
- .replace(//g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''')
+ .replaceAll(/&/g, '&')
+ .replaceAll(//g, '>')
+ .replaceAll(/"/g, '"')
+ .replaceAll(/'/g, ''')
}
const replaceCode = (code: string): ReactElement[][] => {
@@ -69,3 +72,5 @@ export const HighlightedCode: React.FC = ({ code, language
)
}
+
+export default HighlightedCode
diff --git a/src/components/markdown-renderer/replace-components/linemarker/line-number-marker.ts b/src/components/markdown-renderer/replace-components/linemarker/line-number-marker.ts
index 99415e2f7..440ea6692 100644
--- a/src/components/markdown-renderer/replace-components/linemarker/line-number-marker.ts
+++ b/src/components/markdown-renderer/replace-components/linemarker/line-number-marker.ts
@@ -18,7 +18,7 @@ export type LineNumberMarkerOptions = (lineMarkers: LineMarkers[]) => void;
* This plugin adds markers to the dom, that are used to map line numbers to dom elements.
* It also provides a list of line numbers for the top level dom elements.
*/
-export const lineNumberMarker: MarkdownIt.PluginWithOptions
= (md: MarkdownIt, options) => {
+export const lineNumberMarker: (options: LineNumberMarkerOptions) => MarkdownIt.PluginSimple = (options) => (md: MarkdownIt) => {
// add app_linemarker token before each opening or self-closing level-0 tag
md.core.ruler.push('line_number_marker', (state) => {
const lineMarkers: LineMarkers[] = []
diff --git a/src/components/markdown-renderer/replace-components/markmap/markmap-frame.tsx b/src/components/markdown-renderer/replace-components/markmap/markmap-frame.tsx
index d22c18738..dfba34126 100644
--- a/src/components/markdown-renderer/replace-components/markmap/markmap-frame.tsx
+++ b/src/components/markdown-renderer/replace-components/markmap/markmap-frame.tsx
@@ -1,7 +1,7 @@
/*
- SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
-
- SPDX-License-Identifier: AGPL-3.0-only
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { Fragment, useEffect, useRef, useState } from 'react'
@@ -45,21 +45,22 @@ export const MarkmapFrame: React.FC = ({ code }) => {
return
}
const actualContainer = diagramContainer.current
- import('./markmap-loader').then(({ markmapLoader }) => {
- try {
- const svg: SVGSVGElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
- svg.setAttribute('width', '100%')
- actualContainer.querySelectorAll('svg')
- .forEach(child => child.remove())
- actualContainer.appendChild(svg)
- markmapLoader(svg, code)
- } catch (error) {
- console.error(error)
- }
- })
- .catch(() => {
- console.error('error while loading markmap')
- })
+ import(/* webpackChunkName: "markmap" */'./markmap-loader')
+ .then(({ markmapLoader }) => {
+ try {
+ const svg: SVGSVGElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
+ svg.setAttribute('width', '100%')
+ actualContainer.querySelectorAll('svg')
+ .forEach(child => child.remove())
+ actualContainer.appendChild(svg)
+ markmapLoader(svg, code)
+ } catch (error) {
+ console.error(error)
+ }
+ })
+ .catch(() => {
+ console.error('error while loading markmap')
+ })
}, [code])
return (
diff --git a/src/components/markdown-renderer/replace-components/mermaid/mermaid-chart.tsx b/src/components/markdown-renderer/replace-components/mermaid/mermaid-chart.tsx
index 4c53cf7ce..5c31ae6f7 100644
--- a/src/components/markdown-renderer/replace-components/mermaid/mermaid-chart.tsx
+++ b/src/components/markdown-renderer/replace-components/mermaid/mermaid-chart.tsx
@@ -1,7 +1,7 @@
/*
- SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
-
- SPDX-License-Identifier: AGPL-3.0-only
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
@@ -27,13 +27,14 @@ export const MermaidChart: React.FC = ({ code }) => {
useEffect(() => {
if (!mermaidInitialized) {
- import('mermaid').then((mermaid) => {
- mermaid.default.initialize({ startOnLoad: false })
- mermaidInitialized = true
- })
- .catch(() => {
- console.error('error while loading mermaid')
- })
+ import(/* webpackChunkName: "mermaid" */'mermaid')
+ .then((mermaid) => {
+ mermaid.default.initialize({ startOnLoad: false })
+ mermaidInitialized = true
+ })
+ .catch(() => {
+ console.error('error while loading mermaid')
+ })
}
}, [])
@@ -51,22 +52,23 @@ export const MermaidChart: React.FC = ({ code }) => {
if (!diagramContainer.current) {
return
}
- import('mermaid').then((mermaid) => {
- try {
- if (!diagramContainer.current) {
- return
+ import(/* webpackChunkName: "mermaid" */'mermaid')
+ .then((mermaid) => {
+ try {
+ if (!diagramContainer.current) {
+ return
+ }
+ mermaid.default.parse(code)
+ delete diagramContainer.current.dataset.processed
+ diagramContainer.current.textContent = code
+ mermaid.default.init(diagramContainer.current)
+ setError(undefined)
+ } catch (error) {
+ const message = (error as MermaidParseError).str
+ showError(message || t('renderer.mermaid.unknownError'))
}
- mermaid.default.parse(code)
- delete diagramContainer.current.dataset.processed
- diagramContainer.current.textContent = code
- mermaid.default.init(diagramContainer.current)
- setError(undefined)
- } catch (error) {
- const message = (error as MermaidParseError).str
- showError(message || t('renderer.mermaid.unknownError'))
- }
- })
- .catch(() => showError('Error while loading mermaid'))
+ })
+ .catch(() => showError('Error while loading mermaid'))
}, [code, showError, t])
return
diff --git a/src/components/markdown-renderer/replace-components/task-list/task-list-replacer.tsx b/src/components/markdown-renderer/replace-components/task-list/task-list-replacer.tsx
index 5ca470d57..c0206a60d 100644
--- a/src/components/markdown-renderer/replace-components/task-list/task-list-replacer.tsx
+++ b/src/components/markdown-renderer/replace-components/task-list/task-list-replacer.tsx
@@ -8,10 +8,12 @@ import { DomElement } from 'domhandler'
import React, { ReactElement } from 'react'
import { ComponentReplacer } from '../ComponentReplacer'
+export type TaskCheckedChangeHandler = (lineInMarkdown: number, checked: boolean) => void
+
export class TaskListReplacer extends ComponentReplacer {
onTaskCheckedChange?: (lineInMarkdown: number, checked: boolean) => void
- constructor(onTaskCheckedChange?: (lineInMarkdown: number, checked: boolean) => void) {
+ constructor(onTaskCheckedChange?: TaskCheckedChangeHandler) {
super()
this.onTaskCheckedChange = onTaskCheckedChange
}
diff --git a/src/components/markdown-renderer/replace-components/vega-lite/vega-chart.tsx b/src/components/markdown-renderer/replace-components/vega-lite/vega-chart.tsx
index 1192513e5..420432a16 100644
--- a/src/components/markdown-renderer/replace-components/vega-lite/vega-chart.tsx
+++ b/src/components/markdown-renderer/replace-components/vega-lite/vega-chart.tsx
@@ -1,7 +1,7 @@
/*
- SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
-
- SPDX-License-Identifier: AGPL-3.0-only
+ * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
@@ -31,34 +31,35 @@ export const VegaChart: React.FC = ({ code }) => {
if (!diagramContainer.current) {
return
}
- import(/* webpackChunkName: "vega" */ 'vega-embed').then((embed) => {
- try {
- if (!diagramContainer.current) {
- return
- }
-
- const spec = JSON.parse(code) as VisualizationSpec
- embed.default(diagramContainer.current, spec, {
- actions: {
- export: true,
- source: false,
- compiled: false,
- editor: false
- },
- i18n: {
- PNG_ACTION: t('renderer.vega-lite.png'),
- SVG_ACTION: t('renderer.vega-lite.svg')
+ import(/* webpackChunkName: "vega" */ 'vega-embed')
+ .then((embed) => {
+ try {
+ if (!diagramContainer.current) {
+ return
}
- })
- .then(() => setError(undefined))
- .catch(err => showError(err))
- } catch (err) {
- showError(t('renderer.vega-lite.errorJson'))
- }
- })
- .catch(() => {
- console.error('error while loading vega-light')
- })
+
+ const spec = JSON.parse(code) as VisualizationSpec
+ embed.default(diagramContainer.current, spec, {
+ actions: {
+ export: true,
+ source: false,
+ compiled: false,
+ editor: false
+ },
+ i18n: {
+ PNG_ACTION: t('renderer.vega-lite.png'),
+ SVG_ACTION: t('renderer.vega-lite.svg')
+ }
+ })
+ .then(() => setError(undefined))
+ .catch(err => showError(err))
+ } catch (err) {
+ showError(t('renderer.vega-lite.errorJson'))
+ }
+ })
+ .catch(() => {
+ console.error('error while loading vega-light')
+ })
}, [code, showError, t])
return
diff --git a/src/components/render-page/markdown-document.tsx b/src/components/render-page/markdown-document.tsx
index 149e43ea7..7b8cdd5c0 100644
--- a/src/components/render-page/markdown-document.tsx
+++ b/src/components/render-page/markdown-document.tsx
@@ -15,9 +15,11 @@ import { YamlArrayDeprecationAlert } from '../editor-page/renderer-pane/yaml-arr
import { useSyncedScrolling } from '../editor-page/synced-scroll/hooks/use-synced-scrolling'
import { ScrollProps } from '../editor-page/synced-scroll/scroll-props'
import { TableOfContents } from '../editor-page/table-of-contents/table-of-contents'
-import { FullMarkdownRenderer } from '../markdown-renderer/full-markdown-renderer'
+import { BasicMarkdownRenderer } from '../markdown-renderer/basic-markdown-renderer'
import { ImageClickHandler } from '../markdown-renderer/replace-components/image/image-replacer'
import './markdown-document.scss'
+import { useSelector } from 'react-redux'
+import { ApplicationState } from '../../redux'
export interface RendererProps extends ScrollProps {
onFirstHeadingChange?: (firstHeading: string | undefined) => void
@@ -53,14 +55,16 @@ export const MarkdownDocument: React.FC = (
disableToc
}) => {
const rendererRef = useRef(null)
- const internalDocumentRenderPaneRef = useRef(null)
- const [tocAst, setTocAst] = useState()
-
- const internalDocumentRenderPaneSize = useResizeObserver({ ref: internalDocumentRenderPaneRef.current })
const rendererSize = useResizeObserver({ ref: rendererRef.current })
+ const internalDocumentRenderPaneRef = useRef(null)
+ const internalDocumentRenderPaneSize = useResizeObserver({ ref: internalDocumentRenderPaneRef.current })
const containerWidth = internalDocumentRenderPaneSize.width ?? 0
+ const [tocAst, setTocAst] = useState()
+
+ const useAlternativeBreaks = useSelector((state: ApplicationState) => state.noteDetails.frontmatter.breaks)
+
useEffect(() => {
if (!onHeightChange) {
return
@@ -77,9 +81,9 @@ export const MarkdownDocument: React.FC = (
- = (
onTaskCheckedChange={ onTaskCheckedChange }
onTocChange={ setTocAst }
baseUrl={ baseUrl }
- onImageClick={ onImageClick }/>
+ onImageClick={ onImageClick }
+ useAlternativeBreaks={ useAlternativeBreaks }/>
diff --git a/src/components/render-page/render-page.tsx b/src/components/render-page/render-page.tsx
index d0e6d670a..9424311b6 100644
--- a/src/components/render-page/render-page.tsx
+++ b/src/components/render-page/render-page.tsx
@@ -78,7 +78,6 @@ export const RenderPage: React.FC = () => {
return (
import(/* webpackPrefetch: true */ './components/editor-page/editor-page'))
-const RenderPage = React.lazy(() => import (/* webpackPrefetch: true */ './components/render-page/render-page'))
+const EditorPage = React.lazy(() => import(/* webpackPrefetch: true *//* webpackChunkName: "editor" */ './components/editor-page/editor-page'))
+const RenderPage = React.lazy(() => import (/* webpackPrefetch: true *//* webpackChunkName: "renderPage" */ './components/render-page/render-page'))
+const DocumentReadOnlyPage = React.lazy(() => import (/* webpackPrefetch: true *//* webpackChunkName: "documentReadOnly" */ './components/document-read-only-page/document-read-only-page'))
ReactDOM.render(
diff --git a/src/redux/note-details/methods.ts b/src/redux/note-details/methods.ts
index 294768086..ec42f8b61 100644
--- a/src/redux/note-details/methods.ts
+++ b/src/redux/note-details/methods.ts
@@ -34,7 +34,7 @@ export const setNoteDataFromServer = (apiResponse: Note): void => {
export const updateNoteTitleByFirstHeading = (firstHeading?: string): void => {
store.dispatch({
type: NoteDetailsActionType.UPDATE_NOTE_TITLE_BY_FIRST_HEADING,
- firstHeading: firstHeading ?? ''
+ firstHeading: firstHeading
} as UpdateNoteTitleByFirstHeadingAction)
}
diff --git a/src/redux/note-details/reducers.ts b/src/redux/note-details/reducers.ts
index a2a6a0aab..6b75fa21d 100644
--- a/src/redux/note-details/reducers.ts
+++ b/src/redux/note-details/reducers.ts
@@ -7,7 +7,11 @@
import { DateTime } from 'luxon'
import { Reducer } from 'redux'
import { Note } from '../../api/notes'
-import { NoteFrontmatter } from '../../components/editor-page/note-frontmatter/note-frontmatter'
+import {
+ NoteFrontmatter,
+ NoteTextDirection,
+ NoteType
+} from '../../components/editor-page/note-frontmatter/note-frontmatter'
import {
NoteDetails,
NoteDetailsAction,
@@ -40,11 +44,11 @@ export const initialState: NoteDetails = {
deprecatedTagsSyntax: false,
robots: '',
lang: 'en',
- dir: 'ltr',
+ dir: NoteTextDirection.LTR,
breaks: true,
GA: '',
disqus: '',
- type: '',
+ type: NoteType.DOCUMENT,
opengraph: new Map()
}
}
diff --git a/src/redux/note-details/types.ts b/src/redux/note-details/types.ts
index 14eb57e61..313c50202 100644
--- a/src/redux/note-details/types.ts
+++ b/src/redux/note-details/types.ts
@@ -32,7 +32,7 @@ export interface NoteDetails {
alias: string
authorship: number[]
noteTitle: string
- firstHeading: string
+ firstHeading?: string
frontmatter: NoteFrontmatter
}
@@ -52,7 +52,7 @@ export interface SetNoteDetailsFromServerAction extends NoteDetailsAction {
export interface UpdateNoteTitleByFirstHeadingAction extends NoteDetailsAction {
type: NoteDetailsActionType.UPDATE_NOTE_TITLE_BY_FIRST_HEADING
- firstHeading: string
+ firstHeading?: string
}
export interface SetNoteFrontmatterFromRenderingAction extends NoteDetailsAction {
diff --git a/src/style/index.scss b/src/style/index.scss
index 516642efd..1220c63d8 100644
--- a/src/style/index.scss
+++ b/src/style/index.scss
@@ -8,7 +8,7 @@
@import "variables.light";
@import "../../node_modules/bootstrap/scss/bootstrap";
@import '../../node_modules/react-bootstrap-typeahead/css/Typeahead';
-@import "~@fontsource/source-sans-pro/index";
+@import "../../node_modules/@fontsource/source-sans-pro/index";
@import "fonts/twemoji/twemoji";
@import '../../node_modules/fork-awesome/css/fork-awesome.min';
@@ -24,6 +24,10 @@ body {
background-color: $dark;
}
+#root {
+ height: 100vh;
+}
+
html {
height: 100%;
}