mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-15 07:34:42 -04:00
feat: add priorities for replacers
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
4a2cfe225c
commit
a95b2d7d7d
4 changed files with 86 additions and 4 deletions
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import type { NodeReplacement } from '../../replace-components/component-replacer'
|
import type { NodeReplacement } from '../../replace-components/component-replacer'
|
||||||
import { ComponentReplacer, DO_NOT_REPLACE } from '../../replace-components/component-replacer'
|
import { ComponentReplacer, DO_NOT_REPLACE, ReplacerPriority } from '../../replace-components/component-replacer'
|
||||||
import { NodeToReactTransformer } from './node-to-react-transformer'
|
import { NodeToReactTransformer } from './node-to-react-transformer'
|
||||||
import { Element } from 'domhandler'
|
import { Element } from 'domhandler'
|
||||||
import type { ReactElement, ReactHTMLElement } from 'react'
|
import type { ReactElement, ReactHTMLElement } from 'react'
|
||||||
|
@ -37,6 +37,56 @@ describe('node to react transformer', () => {
|
||||||
expect(translation).toEqual(null)
|
expect(translation).toEqual(null)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('will prioritize a high priority replacer over a normal priority replacer', () => {
|
||||||
|
nodeToReactTransformer.setReplacers([
|
||||||
|
new (class extends ComponentReplacer {
|
||||||
|
getPriority(): ReplacerPriority {
|
||||||
|
return ReplacerPriority.NORMAL
|
||||||
|
}
|
||||||
|
|
||||||
|
replace(): NodeReplacement {
|
||||||
|
return <span>Replacer O</span>
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
new (class extends ComponentReplacer {
|
||||||
|
getPriority(): ReplacerPriority {
|
||||||
|
return ReplacerPriority.HIGHER
|
||||||
|
}
|
||||||
|
|
||||||
|
replace(): NodeReplacement {
|
||||||
|
return <span>Replacer X</span>
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
])
|
||||||
|
const translation = nodeToReactTransformer.translateNodeToReactElement(defaultTestSpanElement, 1) as ReactElement
|
||||||
|
expect(translation).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('will prioritize a normal priority replacer over a low priority replacer', () => {
|
||||||
|
nodeToReactTransformer.setReplacers([
|
||||||
|
new (class extends ComponentReplacer {
|
||||||
|
getPriority(): ReplacerPriority {
|
||||||
|
return ReplacerPriority.LOWER
|
||||||
|
}
|
||||||
|
|
||||||
|
replace(): NodeReplacement {
|
||||||
|
return <span>Replacer M</span>
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
new (class extends ComponentReplacer {
|
||||||
|
getPriority(): ReplacerPriority {
|
||||||
|
return ReplacerPriority.NORMAL
|
||||||
|
}
|
||||||
|
|
||||||
|
replace(): NodeReplacement {
|
||||||
|
return <span>Replacer Y</span>
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
])
|
||||||
|
const translation = nodeToReactTransformer.translateNodeToReactElement(defaultTestSpanElement, 1) as ReactElement
|
||||||
|
expect(translation).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
it('can translate an element with no matching replacer', () => {
|
it('can translate an element with no matching replacer', () => {
|
||||||
nodeToReactTransformer.setReplacers([
|
nodeToReactTransformer.setReplacers([
|
||||||
new (class extends ComponentReplacer {
|
new (class extends ComponentReplacer {
|
||||||
|
|
|
@ -31,7 +31,19 @@ export class NodeToReactTransformer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public setReplacers(replacers: ComponentReplacer[]): void {
|
public setReplacers(replacers: ComponentReplacer[]): void {
|
||||||
this.replacers = replacers
|
this.replacers = new Array(...replacers).sort(this.compareReplacers.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
private compareReplacers(replacerA: ComponentReplacer, replacerB: ComponentReplacer): number {
|
||||||
|
const priorityA = replacerA.getPriority()
|
||||||
|
const priorityB = replacerB.getPriority()
|
||||||
|
if (priorityA === priorityB) {
|
||||||
|
return 0
|
||||||
|
} else if (priorityA < priorityB) {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,6 +17,12 @@ export const DO_NOT_REPLACE = Symbol()
|
||||||
|
|
||||||
export type NodeReplacement = ValidReactDomElement | typeof DO_NOT_REPLACE
|
export type NodeReplacement = ValidReactDomElement | typeof DO_NOT_REPLACE
|
||||||
|
|
||||||
|
export enum ReplacerPriority {
|
||||||
|
LOWER = 1,
|
||||||
|
NORMAL = 0,
|
||||||
|
HIGHER = -1
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all component replacers.
|
* Base class for all component replacers.
|
||||||
* Component replacers detect structures in the HTML DOM from markdown it
|
* Component replacers detect structures in the HTML DOM from markdown it
|
||||||
|
@ -65,4 +71,13 @@ export abstract class ComponentReplacer {
|
||||||
subNodeTransform: SubNodeTransform,
|
subNodeTransform: SubNodeTransform,
|
||||||
nativeRenderer: NativeRenderer
|
nativeRenderer: NativeRenderer
|
||||||
): NodeReplacement
|
): NodeReplacement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines that a replacer should be preferred more or less than other replacers.
|
||||||
|
*
|
||||||
|
* @return the replacer priority that gets compared to others.
|
||||||
|
*/
|
||||||
|
public getPriority(): ReplacerPriority {
|
||||||
|
return ReplacerPriority.NORMAL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import HighlightedCode from '../../../components/common/highlighted-code/highlighted-code'
|
import HighlightedCode from '../../../components/common/highlighted-code/highlighted-code'
|
||||||
|
import type { NodeReplacement } from '../../../components/markdown-renderer/replace-components/component-replacer'
|
||||||
import {
|
import {
|
||||||
ComponentReplacer,
|
ComponentReplacer,
|
||||||
DO_NOT_REPLACE
|
DO_NOT_REPLACE,
|
||||||
|
ReplacerPriority
|
||||||
} from '../../../components/markdown-renderer/replace-components/component-replacer'
|
} from '../../../components/markdown-renderer/replace-components/component-replacer'
|
||||||
import type { NodeReplacement } from '../../../components/markdown-renderer/replace-components/component-replacer'
|
|
||||||
import type { Element } from 'domhandler'
|
import type { Element } from 'domhandler'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
|
@ -56,4 +57,8 @@ export class HighlightedCodeReplacer extends ComponentReplacer {
|
||||||
reset() {
|
reset() {
|
||||||
this.lastLineNumber = 0
|
this.lastLineNumber = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPriority(): ReplacerPriority {
|
||||||
|
return ReplacerPriority.LOWER
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue