86 lines
2.7 KiB
JavaScript
86 lines
2.7 KiB
JavaScript
/* eslint-disable ghost/filenames/match-exported-class */
|
|
import {QuoteNode} from '@lexical/rich-text';
|
|
import {$createLineBreakNode, $isParagraphNode} from 'lexical';
|
|
|
|
// Since the QuoteNode is foundational to Lexical rich-text, only using a
|
|
// custom QuoteNode is undesirable as it means every package would need to
|
|
// be updated to work with the custom node. Instead we can use Lexical's node
|
|
// override/replacement mechanism to extend the default with our custom parsing
|
|
// logic.
|
|
//
|
|
// https://lexical.dev/docs/concepts/serialization#handling-extended-html-styling
|
|
|
|
export const extendedQuoteNodeReplacement = {replace: QuoteNode, with: () => new ExtendedQuoteNode()};
|
|
|
|
export class ExtendedQuoteNode extends QuoteNode {
|
|
constructor(key) {
|
|
super(key);
|
|
}
|
|
|
|
static getType() {
|
|
return 'extended-quote';
|
|
}
|
|
|
|
static clone(node) {
|
|
return new ExtendedQuoteNode(node.__key);
|
|
}
|
|
|
|
static importDOM() {
|
|
const importers = QuoteNode.importDOM();
|
|
return {
|
|
...importers,
|
|
blockquote: convertBlockquoteElement
|
|
};
|
|
}
|
|
|
|
static importJSON(serializedNode) {
|
|
return QuoteNode.importJSON(serializedNode);
|
|
}
|
|
|
|
exportJSON() {
|
|
const json = super.exportJSON();
|
|
json.type = 'extended-quote';
|
|
return json;
|
|
}
|
|
|
|
/* c8 ignore start */
|
|
extractWithChild() {
|
|
return true;
|
|
}
|
|
/* c8 ignore end */
|
|
}
|
|
|
|
function convertBlockquoteElement() {
|
|
return {
|
|
conversion: () => {
|
|
const node = new ExtendedQuoteNode();
|
|
return {
|
|
node,
|
|
after: (childNodes) => {
|
|
// Blockquotes can have nested paragraphs. In our original mobiledoc
|
|
// editor we parsed all of the nested paragraphs into a single blockquote
|
|
// separating each paragraph with two line breaks. We replicate that
|
|
// here so we don't have a breaking change in conversion behaviour.
|
|
const newChildNodes = [];
|
|
|
|
childNodes.forEach((child) => {
|
|
if ($isParagraphNode(child)) {
|
|
if (newChildNodes.length > 0) {
|
|
newChildNodes.push($createLineBreakNode());
|
|
newChildNodes.push($createLineBreakNode());
|
|
}
|
|
|
|
newChildNodes.push(...child.getChildren());
|
|
} else {
|
|
newChildNodes.push(child);
|
|
}
|
|
});
|
|
|
|
return newChildNodes;
|
|
}
|
|
};
|
|
},
|
|
priority: 1
|
|
};
|
|
}
|