83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
|
|
/* eslint-disable no-underscore-dangle -- Lexical nodes use protected __ fields by convention. */
|
||
|
|
|
||
|
|
import { $isTextNode, TextNode } from "lexical"
|
||
|
|
import type {
|
||
|
|
DOMConversionMap,
|
||
|
|
DOMConversionOutput,
|
||
|
|
DOMConversionProp,
|
||
|
|
SerializedTextNode,
|
||
|
|
} from "lexical"
|
||
|
|
|
||
|
|
function patchTextStyleConversion(
|
||
|
|
originalDOMConverter?: DOMConversionProp<HTMLElement>
|
||
|
|
) {
|
||
|
|
return (node: HTMLElement): DOMConversionOutput | null => {
|
||
|
|
const original = originalDOMConverter?.(node)
|
||
|
|
const output = original?.conversion(node)
|
||
|
|
if (!output) return null
|
||
|
|
|
||
|
|
const color = node.style.color
|
||
|
|
const backgroundColor = node.style.backgroundColor
|
||
|
|
const textDecoration = node.style.textDecoration
|
||
|
|
const style = [
|
||
|
|
color ? `color: ${color}` : null,
|
||
|
|
backgroundColor ? `background-color: ${backgroundColor}` : null,
|
||
|
|
textDecoration ? `text-decoration: ${textDecoration}` : null,
|
||
|
|
]
|
||
|
|
.filter(Boolean)
|
||
|
|
.join("; ")
|
||
|
|
|
||
|
|
return {
|
||
|
|
...output,
|
||
|
|
forChild: (lexicalNode, parent) => {
|
||
|
|
const converted = output.forChild
|
||
|
|
? output.forChild(lexicalNode, parent)
|
||
|
|
: lexicalNode
|
||
|
|
if ($isTextNode(converted) && style) converted.setStyle(style)
|
||
|
|
return converted
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export class LexicalTextNode extends TextNode {
|
||
|
|
static getType(): string {
|
||
|
|
return "lexical-text"
|
||
|
|
}
|
||
|
|
|
||
|
|
static clone(node: LexicalTextNode): LexicalTextNode {
|
||
|
|
return new LexicalTextNode(node.__text, node.__key)
|
||
|
|
}
|
||
|
|
|
||
|
|
static importJSON(node: SerializedTextNode): LexicalTextNode {
|
||
|
|
return new LexicalTextNode().updateFromJSON(node)
|
||
|
|
}
|
||
|
|
|
||
|
|
static importDOM(): DOMConversionMap | null {
|
||
|
|
const importers = TextNode.importDOM()
|
||
|
|
return {
|
||
|
|
...importers,
|
||
|
|
code: () => ({
|
||
|
|
conversion: patchTextStyleConversion(importers?.code),
|
||
|
|
priority: 1,
|
||
|
|
}),
|
||
|
|
em: () => ({
|
||
|
|
conversion: patchTextStyleConversion(importers?.em),
|
||
|
|
priority: 1,
|
||
|
|
}),
|
||
|
|
span: () => ({
|
||
|
|
conversion: patchTextStyleConversion(importers?.span),
|
||
|
|
priority: 1,
|
||
|
|
}),
|
||
|
|
strong: () => ({
|
||
|
|
conversion: patchTextStyleConversion(importers?.strong),
|
||
|
|
priority: 1,
|
||
|
|
}),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
isSimpleText(): boolean {
|
||
|
|
return this.__type === "lexical-text" && this.__mode === 0
|
||
|
|
}
|
||
|
|
}
|