Add dom purify (#1609)

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2021-11-02 08:15:33 +01:00 committed by GitHub
parent 994d22eb35
commit 84ee1d9cd9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 103 additions and 81 deletions

View file

@ -9,7 +9,7 @@ import { isTag } from 'domhandler'
import type MarkdownIt from 'markdown-it'
import mathJax from 'markdown-it-mathjax'
import React from 'react'
import { ComponentReplacer } from '../component-replacer'
import { ComponentReplacer, DO_NOT_REPLACE } from '../component-replacer'
import './katex.scss'
/**
@ -18,23 +18,24 @@ import './katex.scss'
* @param node the node to check
* @return The given node if it is a KaTeX block element, undefined otherwise.
*/
const getNodeIfKatexBlock = (node: Element): Element | undefined => {
const containsKatexBlock = (node: Element): Element | undefined => {
if (node.name !== 'p' || !node.children || node.children.length === 0) {
return
}
return node.children.filter(isTag).find((subnode) => {
return subnode.name === 'app-katex' && subnode.attribs?.inline === undefined
return isKatexTag(subnode, false) ? subnode : undefined
})
}
/**
* Checks if the given node is a KaTeX inline element.
* Checks if the given node is a KaTeX element.
*
* @param node the node to check
* @return The given node if it is a KaTeX inline element, undefined otherwise.
* @param expectedInline defines if the found katex element is expected to be an inline or block element.
* @return {@code true} if the given node is a katex element.
*/
const getNodeIfInlineKatex = (node: Element): Element | undefined => {
return node.name === 'app-katex' && node.attribs?.inline !== undefined ? node : undefined
const isKatexTag = (node: Element, expectedInline: boolean) => {
return node.name === 'app-katex' && (node.attribs?.['data-inline'] !== undefined) === expectedInline
}
const KaTeX = React.lazy(() => import(/* webpackChunkName: "katex" */ '@matejmazur/react-katex'))
@ -46,18 +47,18 @@ export class KatexReplacer extends ComponentReplacer {
public static readonly markdownItPlugin: MarkdownIt.PluginSimple = mathJax({
beforeMath: '<app-katex>',
afterMath: '</app-katex>',
beforeInlineMath: '<app-katex inline>',
beforeInlineMath: '<app-katex data-inline="true">',
afterInlineMath: '</app-katex>',
beforeDisplayMath: '<app-katex>',
afterDisplayMath: '</app-katex>'
})
public replace(node: Element): React.ReactElement | undefined {
const katex = getNodeIfKatexBlock(node) || getNodeIfInlineKatex(node)
if (katex?.children && katex.children[0]) {
const mathJaxContent = ComponentReplacer.extractTextChildContent(katex)
const isInline = katex.attribs?.inline !== undefined
return <KaTeX block={!isInline} math={mathJaxContent} errorColor={'#cc0000'} />
if (!(isKatexTag(node, true) || containsKatexBlock(node)) || node.children?.[0] === undefined) {
return DO_NOT_REPLACE
}
const latexContent = ComponentReplacer.extractTextChildContent(node)
const isInline = !!node.attribs?.['data-inline']
return <KaTeX block={!isInline} math={latexContent} errorColor={'#cc0000'} />
}
}

View file

@ -35,14 +35,7 @@ export class LinkReplacer extends ComponentReplacer {
}
const url = node.attribs.href.trim()
// eslint-disable-next-line no-script-url
if (url.startsWith('data:') || url.startsWith('javascript:') || url.startsWith('vbscript:')) {
return <span>{node.attribs.href}</span>
}
const isJumpMark = url.substr(0, 1) === '#'
const id = url.substr(1)
try {