]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/nodes/custom-paragraph.ts
Move settings category layouts into their own view folder
[bookstack] / resources / js / wysiwyg / nodes / custom-paragraph.ts
1 import {
2     DOMConversion,
3     DOMConversionMap,
4     DOMConversionOutput,
5     LexicalNode,
6     ParagraphNode, SerializedParagraphNode, Spread,
7 } from "lexical";
8 import {EditorConfig} from "lexical/LexicalEditor";
9 import {
10     CommonBlockAlignment, commonPropertiesDifferent, deserializeCommonBlockNode,
11     SerializedCommonBlockNode,
12     setCommonBlockPropsFromElement,
13     updateElementWithCommonBlockProps
14 } from "./_common";
15
16 export type SerializedCustomParagraphNode = Spread<SerializedCommonBlockNode, SerializedParagraphNode>
17
18 export class CustomParagraphNode extends ParagraphNode {
19     __id: string = '';
20     __alignment: CommonBlockAlignment = '';
21     __inset: number = 0;
22
23     static getType() {
24         return 'custom-paragraph';
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     setInset(size: number) {
48         const self = this.getWritable();
49         self.__inset = size;
50     }
51
52     getInset(): number {
53         const self = this.getLatest();
54         return self.__inset;
55     }
56
57     static clone(node: CustomParagraphNode): CustomParagraphNode {
58         const newNode = new CustomParagraphNode(node.__key);
59         newNode.__id = node.__id;
60         newNode.__alignment = node.__alignment;
61         newNode.__inset = node.__inset;
62         return newNode;
63     }
64
65     createDOM(config: EditorConfig): HTMLElement {
66         const dom = super.createDOM(config);
67         updateElementWithCommonBlockProps(dom, this);
68         return dom;
69     }
70
71     updateDOM(prevNode: CustomParagraphNode, dom: HTMLElement, config: EditorConfig): boolean {
72         return super.updateDOM(prevNode, dom, config)
73             || commonPropertiesDifferent(prevNode, this);
74     }
75
76     exportJSON(): SerializedCustomParagraphNode {
77         return {
78             ...super.exportJSON(),
79             type: 'custom-paragraph',
80             version: 1,
81             id: this.__id,
82             alignment: this.__alignment,
83             inset: this.__inset,
84         };
85     }
86
87     static importJSON(serializedNode: SerializedCustomParagraphNode): CustomParagraphNode {
88         const node = $createCustomParagraphNode();
89         deserializeCommonBlockNode(serializedNode, node);
90         return node;
91     }
92
93     static importDOM(): DOMConversionMap|null {
94         return {
95             p(node: HTMLElement): DOMConversion|null {
96                 return {
97                     conversion: (element: HTMLElement): DOMConversionOutput|null => {
98                         const node = $createCustomParagraphNode();
99                         if (element.style.textIndent) {
100                             const indent = parseInt(element.style.textIndent, 10) / 20;
101                             if (indent > 0) {
102                                 node.setIndent(indent);
103                             }
104                         }
105
106                         setCommonBlockPropsFromElement(element, node);
107
108                         return {node};
109                     },
110                     priority: 1,
111                 };
112             },
113         };
114     }
115 }
116
117 export function $createCustomParagraphNode(): CustomParagraphNode {
118     return new CustomParagraphNode();
119 }
120
121 export function $isCustomParagraphNode(node: LexicalNode | null | undefined): node is CustomParagraphNode {
122     return node instanceof CustomParagraphNode;
123 }