mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-21 18:55:19 -04:00
Switch the base framework from Create React App to Next.JS
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
a979b6ffdd
commit
77a60c6c48
361 changed files with 5130 additions and 9605 deletions
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import './abc.scss'
|
||||
import styles from './abc.module.scss'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import type { CodeProps } from '../../replace-components/code-block-component-replacer'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
@ -29,5 +29,11 @@ export const AbcFrame: React.FC<CodeProps> = ({ code }) => {
|
|||
})
|
||||
}, [code])
|
||||
|
||||
return <div ref={container} className={'abcjs-score bg-white text-black svg-container'} {...cypressId('abcjs')} />
|
||||
return (
|
||||
<div
|
||||
ref={container}
|
||||
className={`${styles['abcjs-score']} bg-white text-black svg-container`}
|
||||
{...cypressId('abcjs')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
@ -6,9 +6,9 @@
|
|||
|
||||
|
||||
.abcjs-score {
|
||||
@import "../../../../style/variables";
|
||||
@import "../../../../../global-styles/variables";
|
||||
|
||||
.markdown-body & {
|
||||
:global(.markdown-body) & {
|
||||
overflow-x: auto !important;
|
||||
}
|
||||
|
|
@ -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 from 'react'
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NativeRenderer, NodeReplacement, SubNodeTransform } from '../../replace-components/component-replacer'
|
||||
import type { NodeReplacement } from '../../replace-components/component-replacer'
|
||||
import { ComponentReplacer, DO_NOT_REPLACE } from '../../replace-components/component-replacer'
|
||||
import type { Element } from 'domhandler'
|
||||
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
|
||||
import { isText } from 'domhandler'
|
||||
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
|
||||
import { cssColor } from './blockquote-border-color-node-preprocessor'
|
||||
import Optional from 'optional-js'
|
||||
import type { Text } from 'domhandler/lib/node'
|
||||
|
@ -21,18 +21,19 @@ import { BlockquoteExtraTagMarkdownExtension } from './blockquote-extra-tag-mark
|
|||
* @see BlockquoteTagMarkdownItPlugin
|
||||
*/
|
||||
export class BlockquoteColorExtraTagReplacer extends ComponentReplacer {
|
||||
replace(element: Element, subNodeTransform: SubNodeTransform, nativeRenderer: NativeRenderer): NodeReplacement {
|
||||
replace(element: Element): NodeReplacement {
|
||||
if (
|
||||
element.tagName === BlockquoteExtraTagMarkdownExtension.tagName &&
|
||||
element.attribs?.['data-label'] === 'color' &&
|
||||
element.children !== undefined
|
||||
) {
|
||||
let index = 0
|
||||
return Optional.ofNullable(element.children[0])
|
||||
.filter(isText)
|
||||
.map((child) => (child as Text).data)
|
||||
.filter((content) => cssColor.test(content))
|
||||
.map<NodeReplacement>((color) => (
|
||||
<span className={'blockquote-extra'} style={{ color: color }}>
|
||||
<span className={'blockquote-extra'} key={(index += 1)} style={{ color: color }}>
|
||||
<ForkAwesomeIcon key='icon' className={'mx-1'} icon={'tag'} />
|
||||
</span>
|
||||
))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NativeRenderer, NodeReplacement, SubNodeTransform } from '../../replace-components/component-replacer'
|
||||
import type { NodeReplacement, SubNodeTransform } from '../../replace-components/component-replacer'
|
||||
import { ComponentReplacer, DO_NOT_REPLACE } from '../../replace-components/component-replacer'
|
||||
import type { Element } from 'domhandler'
|
||||
import type { ForkAwesomeIconProps } from '../../../common/fork-awesome/fork-awesome-icon'
|
||||
|
@ -22,7 +22,7 @@ import { BlockquoteExtraTagMarkdownExtension } from './blockquote-extra-tag-mark
|
|||
* @see ColoredBlockquoteNodePreprocessor
|
||||
*/
|
||||
export class BlockquoteExtraTagReplacer extends ComponentReplacer {
|
||||
replace(element: Element, subNodeTransform: SubNodeTransform, nativeRenderer: NativeRenderer): NodeReplacement {
|
||||
replace(element: Element, subNodeTransform: SubNodeTransform): NodeReplacement {
|
||||
if (element.tagName !== BlockquoteExtraTagMarkdownExtension.tagName || !element.attribs) {
|
||||
return DO_NOT_REPLACE
|
||||
}
|
||||
|
|
|
@ -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, { useMemo } from 'react'
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
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, { useCallback } from 'react'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import './gist-frame.scss'
|
||||
import styles from './gist-frame.module.scss'
|
||||
import { useResizeGistFrame } from './use-resize-gist-frame'
|
||||
import type { IdProps } from '../../replace-components/custom-tag-with-id-component-replacer'
|
||||
import { ClickShield } from '../../replace-components/click-shield/click-shield'
|
||||
|
@ -41,8 +41,8 @@ export const GistFrame: React.FC<IdProps> = ({ id }) => {
|
|||
title={`gist ${id}`}
|
||||
src={`https://gist.github.com/${id}.pibb`}
|
||||
/>
|
||||
<span className={'gist-resizer-row'}>
|
||||
<span className={'gist-resizer'} onMouseDown={onStart} onTouchStart={onStart} />
|
||||
<span className={styles['gist-resizer-row']}>
|
||||
<span className={styles['gist-resizer']} onMouseDown={onStart} onTouchStart={onStart} />
|
||||
</span>
|
||||
</ClickShield>
|
||||
)
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Alert } from 'react-bootstrap'
|
||||
import { ShowIf } from '../../../common/show-if/show-if'
|
||||
import { useFrontendBaseUrl } from '../../../../hooks/common/use-frontend-base-url'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import type { CodeProps } from '../../replace-components/code-block-component-replacer'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
const log = new Logger('GraphvizFrame')
|
||||
|
||||
|
@ -27,7 +27,7 @@ export const GraphvizFrame: React.FC<CodeProps> = ({ code }) => {
|
|||
container.current.querySelectorAll('svg').forEach((child) => child.remove())
|
||||
}, [])
|
||||
|
||||
const frontendBaseUrl = useFrontendBaseUrl()
|
||||
const { basePath } = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
if (!container.current) {
|
||||
|
@ -37,7 +37,7 @@ export const GraphvizFrame: React.FC<CodeProps> = ({ code }) => {
|
|||
|
||||
import(/* webpackChunkName: "d3-graphviz" */ '@hpcc-js/wasm')
|
||||
.then((wasmPlugin) => {
|
||||
wasmPlugin.wasmFolder(`${frontendBaseUrl}/static/js`)
|
||||
wasmPlugin.wasmFolder(`${basePath}/_next/static/js`)
|
||||
})
|
||||
.then(() => import(/* webpackChunkName: "d3-graphviz" */ 'd3-graphviz'))
|
||||
.then((graphvizImport) => {
|
||||
|
@ -57,7 +57,7 @@ export const GraphvizFrame: React.FC<CodeProps> = ({ code }) => {
|
|||
.catch((error: Error) => {
|
||||
log.error('Error while loading graphviz', error)
|
||||
})
|
||||
}, [code, error, frontendBaseUrl, showError])
|
||||
}, [code, error, basePath, showError])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
|
|
@ -57,4 +57,8 @@ export class HighlightedCodeReplacer extends ComponentReplacer {
|
|||
/>
|
||||
)
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.lastLineNumber = 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
.code-highlighter {
|
||||
position: relative;
|
||||
|
||||
:global(code.hljs) {
|
||||
overflow-x: auto;
|
||||
background-color: rgba(27, 31, 35, .05);
|
||||
padding: 16px;
|
||||
display: grid !important;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
|
||||
:global(body.dark) & {
|
||||
background-color: rgb(27, 31, 35);
|
||||
}
|
||||
|
||||
.codeline {
|
||||
grid-column: 2;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.linenumber {
|
||||
grid-column: 1;
|
||||
position: relative;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
padding: 0 8px 0 0;
|
||||
min-width: 20px;
|
||||
box-sizing: content-box;
|
||||
color: #afafaf;
|
||||
border-right: 3px solid #6ce26c;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
align-items: flex-end;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.showGutter {
|
||||
.linenumber {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.codeline {
|
||||
margin: 0 0 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapLines .codeline {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
.code-highlighter {
|
||||
@import '../../../../../node_modules/highlight.js/styles/github';
|
||||
|
||||
body.dark & {
|
||||
@import '../../../../../node_modules/highlight.js/styles/github-dark';
|
||||
}
|
||||
|
||||
position: relative;
|
||||
|
||||
code.hljs {
|
||||
overflow-x: auto;
|
||||
background-color: rgba(27, 31, 35, .05);
|
||||
|
||||
body.dark & {
|
||||
background-color: rgb(27, 31, 35);
|
||||
}
|
||||
|
||||
body.dark &, & {
|
||||
padding: 16px;
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
|
||||
.codeline {
|
||||
grid-column: 2;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.linenumber {
|
||||
grid-column: 1;
|
||||
position: relative;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
padding: 0 8px 0 0;
|
||||
min-width: 20px;
|
||||
box-sizing: content-box;
|
||||
color: #afafaf;
|
||||
border-right: 3px solid #6ce26c;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
align-items: flex-end;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.showGutter {
|
||||
.linenumber {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.codeline {
|
||||
margin: 0 0 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.wrapLines .codeline {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,10 +8,9 @@ import type { ReactElement } from 'react'
|
|||
import React, { Fragment, useEffect, useState } from 'react'
|
||||
import convertHtmlToReact from '@hedgedoc/html-to-react'
|
||||
import { CopyToClipboardButton } from '../../../common/copyable/copy-to-clipboard-button/copy-to-clipboard-button'
|
||||
import '../../utils/button-inside.scss'
|
||||
import './highlighted-code.scss'
|
||||
import styles from './highlighted-code.module.scss'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import { cypressAttribute, cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('HighlightedCode')
|
||||
|
||||
|
@ -54,8 +53,12 @@ export const HighlightedCode: React.FC<HighlightedCodeProps> = ({ code, language
|
|||
: escapeHtml(code)
|
||||
const replacedDom = replaceCode(unreplacedCode).map((line, index) => (
|
||||
<Fragment key={index}>
|
||||
<span className={'linenumber'}>{(startLineNumber || 1) + index}</span>
|
||||
<div className={'codeline'}>{line}</div>
|
||||
<span {...cypressId('linenumber')} className={styles['linenumber']}>
|
||||
{(startLineNumber || 1) + index}
|
||||
</span>
|
||||
<div {...cypressId('codeline')} className={styles['codeline']}>
|
||||
{line}
|
||||
</div>
|
||||
</Fragment>
|
||||
))
|
||||
setDom(replacedDom)
|
||||
|
@ -65,9 +68,15 @@ export const HighlightedCode: React.FC<HighlightedCodeProps> = ({ code, language
|
|||
})
|
||||
}, [code, language, startLineNumber])
|
||||
|
||||
const showGutter = startLineNumber !== undefined
|
||||
|
||||
return (
|
||||
<div className={'code-highlighter'} {...cypressId('highlighted-code-block')}>
|
||||
<code className={`hljs ${startLineNumber !== undefined ? 'showGutter' : ''} ${wrapLines ? 'wrapLines' : ''}`}>
|
||||
<div className={styles['code-highlighter']} {...cypressId('highlighted-code-block')}>
|
||||
<code
|
||||
{...cypressId('code-highlighter')}
|
||||
{...cypressAttribute('showgutter', showGutter ? 'true' : 'false')}
|
||||
{...cypressAttribute('wraplines', wrapLines ? 'true' : 'false')}
|
||||
className={`hljs ${showGutter ? styles['showGutter'] : ''} ${wrapLines ? styles['wrapLines'] : ''}`}>
|
||||
{dom}
|
||||
</code>
|
||||
<div className={'text-right button-inside'}>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NativeRenderer, NodeReplacement, SubNodeTransform } from '../../replace-components/component-replacer'
|
||||
import type { NodeReplacement } from '../../replace-components/component-replacer'
|
||||
import { ComponentReplacer } from '../../replace-components/component-replacer'
|
||||
import type { Element } from 'domhandler'
|
||||
import { ImagePlaceholder } from './image-placeholder'
|
||||
|
@ -24,7 +24,7 @@ export class ImagePlaceholderReplacer extends ComponentReplacer {
|
|||
this.countPerSourceLine = new Map<number, number>()
|
||||
}
|
||||
|
||||
replace(node: Element, subNodeTransform: SubNodeTransform, nativeRenderer: NativeRenderer): NodeReplacement {
|
||||
replace(node: Element): NodeReplacement {
|
||||
if (node.name === 'img' && node.attribs && node.attribs.src === ImagePlaceholderMarkdownExtension.PLACEHOLDER_URL) {
|
||||
const lineIndex = Number(node.attribs['data-line'])
|
||||
const indexInLine = this.countPerSourceLine.get(lineIndex) ?? 0
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
.image-drop {
|
||||
@import "../../../../style/variables.light.scss";
|
||||
@import "../../../../../global-styles/variables.light.scss";
|
||||
border: 3px dashed $dark;
|
||||
|
||||
body.dark & {
|
||||
@import "../../../../style/variables.dark.scss";
|
||||
:global(body.dark) & {
|
||||
@import "../../../../../global-styles/variables.dark.scss";
|
||||
border-color: $dark;
|
||||
}
|
||||
|
|
@ -8,10 +8,11 @@ import React, { useCallback, useMemo, useRef, useState } from 'react'
|
|||
import { Button } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
|
||||
import './image-placeholder.scss'
|
||||
import styles from './image-placeholder.module.scss'
|
||||
import { acceptedMimeTypes } from '../../../common/upload-image-mimetypes'
|
||||
import { useOnImageUpload } from './hooks/use-on-image-upload'
|
||||
import { usePlaceholderSizeStyle } from './hooks/use-placeholder-size-style'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface PlaceholderImageFrameProps {
|
||||
alt?: string
|
||||
|
@ -83,7 +84,8 @@ export const ImagePlaceholder: React.FC<PlaceholderImageFrameProps> = ({
|
|||
|
||||
return (
|
||||
<span
|
||||
className={`image-drop d-inline-flex flex-column align-items-center ${containerDragClasses} p-1`}
|
||||
{...cypressId('image-placeholder-image-drop')}
|
||||
className={`${styles['image-drop']} d-inline-flex flex-column align-items-center ${containerDragClasses} p-1`}
|
||||
style={containerStyle}
|
||||
onDrop={onDropHandler}
|
||||
onDragOver={onDragOverHandler}
|
||||
|
@ -100,7 +102,7 @@ export const ImagePlaceholder: React.FC<PlaceholderImageFrameProps> = ({
|
|||
<span className='my-2'>
|
||||
<Trans i18nKey={'editor.embeddings.placeholderImage.placeholderText'} />
|
||||
</span>
|
||||
<span className={'altText'}>{alt ?? title ?? ''}</span>
|
||||
<span className={styles['altText']}>{alt ?? title ?? ''}</span>
|
||||
</div>
|
||||
</div>
|
||||
<Button size={'sm'} variant={'primary'} onClick={uploadButtonClicked}>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react'
|
||||
import './lightbox.scss'
|
||||
import styles from './lightbox.module.scss'
|
||||
import { ProxyImageFrame } from './proxy-image-frame'
|
||||
import type { ModalVisibilityProps } from '../../../common/modals/common-modal'
|
||||
import { CommonModal } from '../../../common/modals/common-modal'
|
||||
|
@ -23,7 +23,7 @@ export const ImageLightboxModal: React.FC<ImageLightboxModalProps> = ({ show, on
|
|||
show={show && !!src}
|
||||
onHide={onHide}
|
||||
showCloseButton={true}
|
||||
additionalClasses={'lightbox'}
|
||||
additionalClasses={styles.lightbox}
|
||||
title={alt ?? title ?? ''}
|
||||
titleIsI18nKey={false}>
|
||||
<ProxyImageFrame alt={alt} src={src} title={title} className={'w-100 cursor-zoom-out'} onClick={onHide} />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
@ -24,5 +24,7 @@ export const ProxyImageFrame: React.FC<React.ImgHTMLAttributes<HTMLImageElement>
|
|||
.catch((err) => log.error(err))
|
||||
}, [imageProxyEnabled, src])
|
||||
|
||||
// The next image processor works with a whitelist of origins. Therefore we can't use it for general images.
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
return <img src={imageProxyEnabled ? imageUrl : src ?? ''} title={title ?? alt ?? ''} alt={alt} {...props} />
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import type { Element } from 'domhandler'
|
|||
import { isTag } from 'domhandler'
|
||||
import React from 'react'
|
||||
import { ComponentReplacer, DO_NOT_REPLACE } from '../../replace-components/component-replacer'
|
||||
import './katex.scss'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import { KatexMarkdownExtension } from './katex-markdown-extension'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@import '../../../../../node_modules/katex/dist/katex.min.css';
|
|
@ -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 type { Element } from 'domhandler'
|
||||
|
|
|
@ -9,10 +9,12 @@ import type { NodeProcessor } from '../node-preprocessors/node-processor'
|
|||
import type { ComponentReplacer } from '../replace-components/component-replacer'
|
||||
|
||||
export abstract class MarkdownExtension {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public configureMarkdownIt(markdownIt: MarkdownIt): void {
|
||||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public configureMarkdownItPost(markdownIt: MarkdownIt): void {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { LockButton } from '../../../common/lock-button/lock-button'
|
||||
import '../../utils/button-inside.scss'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
import type { CodeProps } from '../../replace-components/code-block-component-replacer'
|
||||
|
|
|
@ -8,9 +8,10 @@ import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react
|
|||
import { Alert } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ShowIf } from '../../../common/show-if/show-if'
|
||||
import './mermaid.scss'
|
||||
import styles from './mermaid.module.scss'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import type { CodeProps } from '../../replace-components/code-block-component-replacer'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('MermaidChart')
|
||||
|
||||
|
@ -78,7 +79,11 @@ export const MermaidChart: React.FC<CodeProps> = ({ code }) => {
|
|||
<ShowIf condition={!!error}>
|
||||
<Alert variant={'warning'}>{error}</Alert>
|
||||
</ShowIf>
|
||||
<div className={'text-center mermaid text-black'} ref={diagramContainer} />
|
||||
<div
|
||||
{...cypressId('mermaid-frame')}
|
||||
className={`text-center ${styles['mermaid']} text-black`}
|
||||
ref={diagramContainer}
|
||||
/>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NativeRenderer, NodeReplacement, SubNodeTransform } from '../../replace-components/component-replacer'
|
||||
import type { NodeReplacement } from '../../replace-components/component-replacer'
|
||||
import { ComponentReplacer, DO_NOT_REPLACE } from '../../replace-components/component-replacer'
|
||||
import { PlantumlNotConfiguredAlert } from './plantuml-not-configured-alert'
|
||||
import type { Element } from 'domhandler'
|
||||
|
||||
export class PlantumlNotConfiguredComponentReplacer extends ComponentReplacer {
|
||||
replace(node: Element, subNodeTransform: SubNodeTransform, nativeRenderer: NativeRenderer): NodeReplacement {
|
||||
replace(node: Element): NodeReplacement {
|
||||
return node.tagName === 'plantuml-not-configured' ? <PlantumlNotConfiguredAlert /> : DO_NOT_REPLACE
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ const processCommentNode = (node: DataNode): void => {
|
|||
return
|
||||
}
|
||||
|
||||
for (const dataAttribute of regexResult[2].matchAll(dataAttributesSyntax)) {
|
||||
for (const dataAttribute of [...regexResult[2].matchAll(dataAttributesSyntax)]) {
|
||||
const attributeName = dataAttribute[1]
|
||||
const attributeValue = dataAttribute[2] ?? dataAttribute[3]
|
||||
if (attributeValue) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { NativeRenderer, NodeReplacement, SubNodeTransform } from '../../replace-components/component-replacer'
|
||||
import type { NodeReplacement } from '../../replace-components/component-replacer'
|
||||
import { ComponentReplacer } from '../../replace-components/component-replacer'
|
||||
import type { Element } from 'domhandler'
|
||||
import { UploadIndicatingFrame } from './upload-indicating-frame'
|
||||
|
@ -15,7 +15,7 @@ const uploadIdRegex = /^upload-(.+)$/
|
|||
* Replaces an image tag whose url is an upload-id with the {@link UploadIndicatingFrame upload indicating frame}.
|
||||
*/
|
||||
export class UploadIndicatingImageFrameReplacer extends ComponentReplacer {
|
||||
replace(node: Element, subNodeTransform: SubNodeTransform, nativeRenderer: NativeRenderer): NodeReplacement {
|
||||
replace(node: Element): NodeReplacement {
|
||||
if (node.name === 'img' && uploadIdRegex.test(node.attribs.src)) {
|
||||
return <UploadIndicatingFrame width={node.attribs.width} height={node.attribs.height} />
|
||||
}
|
||||
|
|
|
@ -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, { useCallback } from 'react'
|
||||
|
|
|
@ -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 from 'react'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue