]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/nodes/custom-quote.ts
Lexical: Added custom alignment handling for blocks
[bookstack] / resources / js / wysiwyg / nodes / custom-quote.ts
1 import {
2     DOMConversionMap,
3     DOMConversionOutput,
4     LexicalNode,
5     Spread
6 } from "lexical";
7 import {EditorConfig} from "lexical/LexicalEditor";
8 import {QuoteNode, SerializedQuoteNode} from "@lexical/rich-text";
9 import {
10     CommonBlockAlignment, commonPropertiesDifferent,
11     SerializedCommonBlockNode,
12     setCommonBlockPropsFromElement,
13     updateElementWithCommonBlockProps
14 } from "./_common";
15
16
17 export type SerializedCustomQuoteNode = Spread<SerializedCommonBlockNode, SerializedQuoteNode>
18
19 export class CustomQuoteNode extends QuoteNode {
20     __id: string = '';
21     __alignment: CommonBlockAlignment = '';
22
23     static getType() {
24         return 'custom-quote';
25     }
26
27     setId(id: string) {
28         const self = this.getWritable();
29         self.__id = id;
30     }
31
32     getId(): string {
33         const self = this.getLatest();
34         return self.__id;
35     }
36
37     setAlignment(alignment: CommonBlockAlignment) {
38         const self = this.getWritable();
39         self.__alignment = alignment;
40     }
41
42     getAlignment(): CommonBlockAlignment {
43         const self = this.getLatest();
44         return self.__alignment;
45     }
46
47     static clone(node: CustomQuoteNode) {
48         const newNode = new CustomQuoteNode(node.__key);
49         newNode.__id = node.__id;
50         newNode.__alignment = node.__alignment;
51         return newNode;
52     }
53
54     createDOM(config: EditorConfig): HTMLElement {
55         const dom = super.createDOM(config);
56         updateElementWithCommonBlockProps(dom, this);
57         return dom;
58     }
59
60     updateDOM(prevNode: CustomQuoteNode): boolean {
61         return commonPropertiesDifferent(prevNode, this);
62     }
63
64     exportJSON(): SerializedCustomQuoteNode {
65         return {
66             ...super.exportJSON(),
67             type: 'custom-quote',
68             version: 1,
69             id: this.__id,
70             alignment: this.__alignment,
71         };
72     }
73
74     static importJSON(serializedNode: SerializedCustomQuoteNode): CustomQuoteNode {
75         const node = $createCustomQuoteNode();
76         node.setId(serializedNode.id);
77         node.setAlignment(serializedNode.alignment);
78         return node;
79     }
80
81     static importDOM(): DOMConversionMap | null {
82         return {
83             blockquote: (node: Node) => ({
84                 conversion: $convertBlockquoteElement,
85                 priority: 0,
86             }),
87         };
88     }
89 }
90
91 function $convertBlockquoteElement(element: HTMLElement): DOMConversionOutput {
92     const node = $createCustomQuoteNode();
93     setCommonBlockPropsFromElement(element, node);
94     return {node};
95 }
96
97 export function $createCustomQuoteNode() {
98     return new CustomQuoteNode();
99 }
100
101 export function $isCustomQuoteNode(node: LexicalNode | null | undefined): node is CustomQuoteNode {
102     return node instanceof CustomQuoteNode;
103 }