Replace react-html-parser with html-to-react (#1327)

* Replace react-html-parser with html-to-react

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2021-06-18 23:26:36 +02:00 committed by GitHub
parent b13c1ce8a0
commit 82472227f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 329 additions and 167 deletions

View file

@ -4,18 +4,24 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { DomElement } from 'domhandler'
import React, { ReactElement, Suspense } from 'react'
import { convertNodeToElement, Transform } from 'react-html-parser'
import { ComponentReplacer, NativeRenderer, SubNodeTransform } from '../replace-components/ComponentReplacer'
import { Element, isTag } from 'domhandler'
import React, { Suspense } from 'react'
import { convertNodeToReactElement } from '@hedgedoc/html-to-react/dist/convertNodeToReactElement'
import {
ComponentReplacer,
NativeRenderer,
SubNodeTransform,
ValidReactDomElement
} from '../replace-components/ComponentReplacer'
import { LineKeys } from '../types'
import { NodeToReactElementTransformer } from '@hedgedoc/html-to-react/dist/NodeToReactElementTransformer'
export interface TextDifferenceResult {
lines: LineKeys[]
lastUsedLineId: number
}
export const calculateKeyFromLineMarker = (node: DomElement, lineKeys?: LineKeys[]): string | undefined => {
export const calculateKeyFromLineMarker = (node: Element, lineKeys?: LineKeys[]): string | undefined => {
if (!node.attribs || lineKeys === undefined) {
return
}
@ -26,7 +32,7 @@ export const calculateKeyFromLineMarker = (node: DomElement, lineKeys?: LineKeys
}
const lineMarker = node.prev
if (!lineMarker || !lineMarker.attribs) {
if (!lineMarker || !isTag(lineMarker) || !lineMarker.attribs) {
return
}
@ -48,29 +54,49 @@ export const calculateKeyFromLineMarker = (node: DomElement, lineKeys?: LineKeys
}
export const findNodeReplacement = (
node: DomElement,
node: Element,
allReplacers: ComponentReplacer[],
subNodeTransform: SubNodeTransform,
nativeRenderer: NativeRenderer
): ReactElement | null | undefined => {
return allReplacers
.map((componentReplacer) => componentReplacer.getReplacement(node, subNodeTransform, nativeRenderer))
.find((replacement) => replacement !== undefined)
): ValidReactDomElement | undefined => {
for (const componentReplacer of allReplacers) {
const replacement = componentReplacer.getReplacement(node, subNodeTransform, nativeRenderer)
if (replacement !== undefined) {
return replacement
}
}
}
export const renderNativeNode = (node: DomElement, key: string, transform: Transform): ReactElement => {
/**
* Renders the given node without any replacement
*
* @param node The node to render
* @param key The unique key for the node
* @param transform The transform function that should be applied to the child nodes
*/
export const renderNativeNode = (
node: Element,
key: string,
transform: NodeToReactElementTransformer
): ValidReactDomElement => {
if (node.attribs === undefined) {
node.attribs = {}
}
delete node.attribs['data-key']
return convertNodeToElement(node, key as unknown as number, transform)
return convertNodeToReactElement(node, key, transform)
}
export const buildTransformer = (lineKeys: LineKeys[] | undefined, allReplacers: ComponentReplacer[]): Transform => {
const transform: Transform = (node, index) => {
export const buildTransformer = (
lineKeys: LineKeys[] | undefined,
allReplacers: ComponentReplacer[]
): NodeToReactElementTransformer => {
const transform: NodeToReactElementTransformer = (node, index) => {
if (!isTag(node)) {
return convertNodeToReactElement(node, index)
}
const nativeRenderer: NativeRenderer = () => renderNativeNode(node, key, transform)
const subNodeTransform: SubNodeTransform = (subNode, subIndex) => transform(subNode, subIndex, transform)
const subNodeTransform: SubNodeTransform = (subNode, subKey) => transform(subNode, subKey, transform)
const key = calculateKeyFromLineMarker(node, lineKeys) ?? (-index).toString()
const tryReplacement = findNodeReplacement(node, allReplacers, subNodeTransform, nativeRenderer)