]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/nodes/custom-quote.ts
39ae7bf8af3b6f3f1728c016db4b8766d9f44bcd
[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, deserializeCommonBlockNode,
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     __inset: number = 0;
23
24     static getType() {
25         return 'custom-quote';
26     }
27
28     setId(id: string) {
29         const self = this.getWritable();
30         self.__id = id;
31     }
32
33     getId(): string {
34         const self = this.getLatest();
35         return self.__id;
36     }
37
38     setAlignment(alignment: CommonBlockAlignment) {
39         const self = this.getWritable();
40         self.__alignment = alignment;
41     }
42
43     getAlignment(): CommonBlockAlignment {
44         const self = this.getLatest();
45         return self.__alignment;
46     }
47
48     setInset(size: number) {
49         const self = this.getWritable();
50         self.__inset = size;
51     }
52
53     getInset(): number {
54         const self = this.getLatest();
55         return self.__inset;
56     }
57
58     static clone(node: CustomQuoteNode) {
59         const newNode = new CustomQuoteNode(node.__key);
60         newNode.__id = node.__id;
61         newNode.__alignment = node.__alignment;
62         newNode.__inset = node.__inset;
63         return newNode;
64     }
65
66     createDOM(config: EditorConfig): HTMLElement {
67         const dom = super.createDOM(config);
68         updateElementWithCommonBlockProps(dom, this);
69         return dom;
70     }
71
72     updateDOM(prevNode: CustomQuoteNode): boolean {
73         return commonPropertiesDifferent(prevNode, this);
74     }
75
76     exportJSON(): SerializedCustomQuoteNode {
77         return {
78             ...super.exportJSON(),
79             type: 'custom-quote',
80             version: 1,
81             id: this.__id,
82             alignment: this.__alignment,
83             inset: this.__inset,
84         };
85     }
86
87     static importJSON(serializedNode: SerializedCustomQuoteNode): CustomQuoteNode {
88         const node = $createCustomQuoteNode();
89         deserializeCommonBlockNode(serializedNode, node);
90         return node;
91     }
92
93     static importDOM(): DOMConversionMap | null {
94         return {
95             blockquote: (node: Node) => ({
96                 conversion: $convertBlockquoteElement,
97                 priority: 0,
98             }),
99         };
100     }
101 }
102
103 function $convertBlockquoteElement(element: HTMLElement): DOMConversionOutput {
104     const node = $createCustomQuoteNode();
105     setCommonBlockPropsFromElement(element, node);
106     return {node};
107 }
108
109 export function $createCustomQuoteNode() {
110     return new CustomQuoteNode();
111 }
112
113 export function $isCustomQuoteNode(node: LexicalNode | null | undefined): node is CustomQuoteNode {
114     return node instanceof CustomQuoteNode;
115 }