Remove keys from replacers (#539)

This commit is contained in:
mrdrogdrog 2020-09-05 10:34:43 +02:00 committed by GitHub
parent 63b24fa5bf
commit e58e53a116
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 77 additions and 78 deletions

View file

@ -1,10 +1,9 @@
import { diffArrays } from 'diff'
import { DomElement } from 'domhandler'
import { ReactElement } from 'react'
import React, { Fragment, ReactElement } from 'react'
import { convertNodeToElement, Transform } from 'react-html-parser'
import {
ComponentReplacer,
NativeRenderer,
SubNodeTransform
} from './replace-components/ComponentReplacer'
@ -75,9 +74,9 @@ export const calculateKeyFromLineMarker = (node: DomElement, lineKeys?: LineKeys
return lineKeys[line].id
}
export const findNodeReplacement = (node: DomElement, index: number, allReplacers: ComponentReplacer[], transform: SubNodeTransform, nativeRenderer: NativeRenderer): ReactElement|null|undefined => {
export const findNodeReplacement = (node: DomElement, index: number, allReplacers: ComponentReplacer[], subNodeTransform: SubNodeTransform): ReactElement|null|undefined => {
return allReplacers
.map((componentReplacer) => componentReplacer.getReplacement(node, index, transform, nativeRenderer))
.map((componentReplacer) => componentReplacer.getReplacement(node, subNodeTransform))
.find((replacement) => replacement !== undefined)
}
@ -96,13 +95,13 @@ export const buildTransformer = (lineKeys: (LineKeys[] | undefined), allReplacer
const subNodeTransform:SubNodeTransform = (subNode, subIndex) => transform(subNode, subIndex, transform)
const key = calculateKeyFromLineMarker(node, lineKeys) ?? -index
const tryReplacement = findNodeReplacement(node, key, allReplacers, subNodeTransform, nativeRenderer)
const tryReplacement = findNodeReplacement(node, key, allReplacers, subNodeTransform)
if (tryReplacement === null) {
return null
} else if (tryReplacement === undefined) {
return nativeRenderer(node, key)
} else {
return tryReplacement
return <Fragment key={key}>{tryReplacement}</Fragment>
}
}
return transform

View file

@ -1,10 +1,10 @@
import { DomElement } from 'domhandler'
import { ReactElement } from 'react'
export type SubNodeTransform = (node: DomElement, index: number) => ReactElement | void | null
export type SubNodeTransform = (node: DomElement, subIndex: number) => ReactElement | void | null
export type NativeRenderer = (node: DomElement, key: number) => ReactElement
export abstract class ComponentReplacer {
public abstract getReplacement(node: DomElement, index: number, subNodeTransform: SubNodeTransform, nativeRenderer: NativeRenderer): (ReactElement | null | undefined);
public abstract getReplacement(node: DomElement, subNodeTransform: SubNodeTransform): (ReactElement | null | undefined);
}

View file

@ -4,13 +4,13 @@ import { ComponentReplacer } from '../ComponentReplacer'
import { AbcFrame } from './abc-frame'
export class AbcReplacer implements ComponentReplacer {
getReplacement (codeNode: DomElement, index: number): React.ReactElement | undefined {
getReplacement (codeNode: DomElement): React.ReactElement | undefined {
if (codeNode.name !== 'code' || !codeNode.attribs || !codeNode.attribs['data-highlight-language'] || codeNode.attribs['data-highlight-language'] !== 'abc' || !codeNode.children || !codeNode.children[0]) {
return
}
const code = codeNode.children[0].data as string
return <AbcFrame key={'index'} code={code}/>
return <AbcFrame code={code}/>
}
}

View file

@ -7,14 +7,14 @@ import { AsciinemaFrame } from './asciinema-frame'
export class AsciinemaReplacer extends ComponentReplacer {
private counterMap: Map<string, number> = new Map<string, number>()
public getReplacement (node: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (node: DomElement): React.ReactElement | undefined {
const attributes = getAttributesFromHedgeDocTag(node, 'asciinema')
if (attributes && attributes.id) {
const asciinemaId = attributes.id
const count = (this.counterMap.get(asciinemaId) || 0) + 1
this.counterMap.set(asciinemaId, count)
return (
<AsciinemaFrame key={index} id={asciinemaId}/>
<AsciinemaFrame id={asciinemaId}/>
)
}
}

View file

@ -4,7 +4,7 @@ import { ComponentReplacer } from '../ComponentReplacer'
import { CsvTable } from './csv-table'
export class CsvReplacer extends ComponentReplacer {
public getReplacement (codeNode: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (codeNode: DomElement): React.ReactElement | undefined {
if (codeNode.name !== 'code' || !codeNode.attribs || !codeNode.attribs['data-highlight-language'] || codeNode.attribs['data-highlight-language'] !== 'csv' || !codeNode.children || !codeNode.children[0]) {
return
}
@ -23,6 +23,6 @@ export class CsvReplacer extends ComponentReplacer {
showHeader = extraInfos[3] !== undefined
}
return <CsvTable key={`csv-${index}`} code={code} delimiter={delimiter} showHeader={showHeader}/>
return <CsvTable code={code} delimiter={delimiter} showHeader={showHeader}/>
}
}

View file

@ -4,13 +4,13 @@ import { ComponentReplacer } from '../ComponentReplacer'
import { FlowChart } from './flowchart/flowchart'
export class FlowchartReplacer extends ComponentReplacer {
public getReplacement (codeNode: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (codeNode: DomElement): React.ReactElement | undefined {
if (codeNode.name !== 'code' || !codeNode.attribs || !codeNode.attribs['data-highlight-language'] || codeNode.attribs['data-highlight-language'] !== 'flow' || !codeNode.children || !codeNode.children[0]) {
return
}
const code = codeNode.children[0].data as string
return <FlowChart key={`flowchart-${index}`} code={code}/>
return <FlowChart code={code}/>
}
}

View file

@ -9,14 +9,14 @@ import preview from './gist-preview.png'
export class GistReplacer extends ComponentReplacer {
private counterMap: Map<string, number> = new Map<string, number>()
public getReplacement (node: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (node: DomElement): React.ReactElement | undefined {
const attributes = getAttributesFromHedgeDocTag(node, 'gist')
if (attributes && attributes.id) {
const gistId = attributes.id
const count = (this.counterMap.get(gistId) || 0) + 1
this.counterMap.set(gistId, count)
return (
<OneClickEmbedding previewContainerClassName={'gist-frame'} key={index} loadingImageUrl={preview} hoverIcon={'github'} tooltip={'click to load gist'}>
<OneClickEmbedding previewContainerClassName={'gist-frame'} loadingImageUrl={preview} hoverIcon={'github'} tooltip={'click to load gist'}>
<GistFrame id={gistId}/>
</OneClickEmbedding>
)

View file

@ -6,7 +6,7 @@ import { HighlightedCode } from './highlighted-code/highlighted-code'
export class HighlightedCodeReplacer extends ComponentReplacer {
private lastLineNumber = 0;
public getReplacement (codeNode: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (codeNode: DomElement): React.ReactElement | undefined {
if (codeNode.name !== 'code' || !codeNode.attribs || !codeNode.attribs['data-highlight-language'] || !codeNode.children || !codeNode.children[0]) {
return
}
@ -33,6 +33,6 @@ export class HighlightedCodeReplacer extends ComponentReplacer {
.filter(line => !!line).length
}
return <HighlightedCode key={index} language={language} startLineNumber={showLineNumbers ? startLineNumber : undefined} wrapLines={wrapLines} code={code}/>
return <HighlightedCode language={language} startLineNumber={showLineNumbers ? startLineNumber : undefined} wrapLines={wrapLines} code={code}/>
}
}

View file

@ -4,10 +4,10 @@ import { ComponentReplacer } from '../ComponentReplacer'
import { ImageFrame } from './image-frame'
export class ImageReplacer extends ComponentReplacer {
public getReplacement (node: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (node: DomElement): React.ReactElement | undefined {
if (node.name === 'img' && node.attribs) {
return <ImageFrame
key={index}
id={node.attribs.id}
className={node.attribs.class}
src={node.attribs.src}

View file

@ -18,12 +18,12 @@ const getNodeIfInlineKatex = (node: DomElement): (DomElement|undefined) => {
}
export class KatexReplacer extends ComponentReplacer {
public getReplacement (node: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (node: DomElement): React.ReactElement | undefined {
const katex = getNodeIfKatexBlock(node) || getNodeIfInlineKatex(node)
if (katex?.children && katex.children[0]) {
const mathJaxContent = katex.children[0]?.data as string
const isInline = (katex.attribs?.inline) !== undefined
return <TeX key={index} block={!isInline} math={mathJaxContent} errorColor={'#cc0000'}/>
return <TeX block={!isInline} math={mathJaxContent} errorColor={'#cc0000'}/>
}
}
}

View file

@ -2,7 +2,7 @@ import { DomElement } from 'domhandler'
import { ComponentReplacer } from '../ComponentReplacer'
export class LinemarkerReplacer extends ComponentReplacer {
public getReplacement (codeNode: DomElement, index: number): null | undefined {
public getReplacement (codeNode: DomElement): null | undefined {
return codeNode.name === 'app-linemarker' ? null : undefined
}
}

View file

@ -4,13 +4,13 @@ import { ComponentReplacer } from '../ComponentReplacer'
import { MermaidChart } from './mermaid-chart'
export class MermaidReplacer implements ComponentReplacer {
getReplacement (codeNode: DomElement, index: number): React.ReactElement | undefined {
getReplacement (codeNode: DomElement): React.ReactElement | undefined {
if (codeNode.name !== 'code' || !codeNode.attribs || !codeNode.attribs['data-highlight-language'] || codeNode.attribs['data-highlight-language'] !== 'mermaid' || !codeNode.children || !codeNode.children[0]) {
return
}
const code = codeNode.children[0].data as string
return <MermaidChart key={`flowchart-${index}`} code={code}/>
return <MermaidChart code={code}/>
}
}

View file

@ -7,13 +7,13 @@ import { PdfFrame } from './pdf-frame'
export class PdfReplacer extends ComponentReplacer {
private counterMap: Map<string, number> = new Map<string, number>()
public getReplacement (node: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (node: DomElement): React.ReactElement | undefined {
const attributes = getAttributesFromHedgeDocTag(node, 'pdf')
if (attributes && attributes.url) {
const pdfUrl = attributes.url
const count = (this.counterMap.get(pdfUrl) || 0) + 1
this.counterMap.set(pdfUrl, count)
return <PdfFrame key={index} url={pdfUrl}/>
return <PdfFrame url={pdfUrl}/>
}
}
}

View file

@ -1,5 +1,5 @@
import { DomElement } from 'domhandler'
import { ComponentReplacer, NativeRenderer, SubNodeTransform } from '../ComponentReplacer'
import { ComponentReplacer } from '../ComponentReplacer'
import './possible-wider-replacer.scss'
const enabledTags = ['img', 'app-youtube', 'app-vimeo', 'app-asciinema', 'app-pdf']
@ -10,7 +10,7 @@ const enabledTags = ['img', 'app-youtube', 'app-vimeo', 'app-asciinema', 'app-pd
* appends the "wider-possible" class to paragraphs with special content.
*/
export class PossibleWiderReplacer extends ComponentReplacer {
public getReplacement (node: DomElement, index: number, subNodeTransformer: SubNodeTransform, nativeRenderer: NativeRenderer): (undefined) {
public getReplacement (node: DomElement): (undefined) {
if (node.name !== 'p') {
return
}

View file

@ -1,6 +1,6 @@
import { DomElement } from 'domhandler'
import { ReactElement } from 'react'
import { ComponentReplacer, NativeRenderer, SubNodeTransform } from '../ComponentReplacer'
import { ComponentReplacer } from '../ComponentReplacer'
const isColorExtraElement = (node: DomElement | undefined): boolean => {
if (!node || !node.attribs || !node.attribs.class || !node.attribs['data-color']) {
@ -19,7 +19,7 @@ const findQuoteOptionsParent = (nodes: DomElement[]): DomElement | undefined =>
}
export class QuoteOptionsReplacer extends ComponentReplacer {
public getReplacement (node: DomElement, index: number, subNodeTransform: SubNodeTransform, nativeRenderer: NativeRenderer):ReactElement|undefined {
public getReplacement (node: DomElement):ReactElement|undefined {
if (node.name !== 'blockquote' || !node.children || node.children.length < 1) {
return
}
@ -38,6 +38,5 @@ export class QuoteOptionsReplacer extends ComponentReplacer {
return
}
node.attribs = Object.assign(node.attribs || {}, { style: `border-left-color: ${attributes['data-color']};` })
return nativeRenderer(node, index)
}
}

View file

@ -5,14 +5,14 @@ import { MermaidChart } from '../mermaid/mermaid-chart'
import { DeprecationWarning } from './deprecation-warning'
export class SequenceDiagramReplacer implements ComponentReplacer {
getReplacement (codeNode: DomElement, index: number): React.ReactElement | undefined {
getReplacement (codeNode: DomElement): React.ReactElement | undefined {
if (codeNode.name !== 'code' || !codeNode.attribs || !codeNode.attribs['data-highlight-language'] || codeNode.attribs['data-highlight-language'] !== 'sequence' || !codeNode.children || !codeNode.children[0]) {
return
}
const code = codeNode.children[0].data as string
return <Fragment key={index} >
return <Fragment>
<DeprecationWarning/>
<MermaidChart code={'sequenceDiagram\n' + code}/>
</Fragment>

View file

@ -15,7 +15,7 @@ export class TaskListReplacer extends ComponentReplacer {
this.onTaskCheckedChange(lineNum, event.currentTarget.checked)
}
public getReplacement (node: DomElement, index:number): (ReactElement|undefined) {
public getReplacement (node: DomElement): (ReactElement|undefined) {
if (node.attribs?.class === 'task-list-item-checkbox') {
return (
<input
@ -24,7 +24,6 @@ export class TaskListReplacer extends ComponentReplacer {
checked={node.attribs.checked !== undefined}
onChange={this.handleCheckboxChange}
data-line={node.attribs['data-line']}
key={`task-list-item-checkbox${node.attribs['data-line']}`}
/>
)
}

View file

@ -7,13 +7,13 @@ import { VimeoFrame } from './vimeo-frame'
export class VimeoReplacer extends ComponentReplacer {
private counterMap: Map<string, number> = new Map<string, number>()
public getReplacement (node: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (node: DomElement): React.ReactElement | undefined {
const attributes = getAttributesFromHedgeDocTag(node, 'vimeo')
if (attributes && attributes.id) {
const videoId = attributes.id
const count = (this.counterMap.get(videoId) || 0) + 1
this.counterMap.set(videoId, count)
return <VimeoFrame key={index} id={videoId}/>
return <VimeoFrame id={videoId}/>
}
}
}

View file

@ -7,13 +7,13 @@ import { YouTubeFrame } from './youtube-frame'
export class YoutubeReplacer extends ComponentReplacer {
private counterMap: Map<string, number> = new Map<string, number>()
public getReplacement (node: DomElement, index: number): React.ReactElement | undefined {
public getReplacement (node: DomElement): React.ReactElement | undefined {
const attributes = getAttributesFromHedgeDocTag(node, 'youtube')
if (attributes && attributes.id) {
const videoId = attributes.id
const count = (this.counterMap.get(videoId) || 0) + 1
this.counterMap.set(videoId, count)
return <YouTubeFrame key={index} id={videoId}/>
return <YouTubeFrame id={videoId}/>
}
}
}