]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/nodes/custom-paragraph.ts
Lexical: Added id support for all main block types
[bookstack] / resources / js / wysiwyg / nodes / custom-paragraph.ts
1 import {
2     DOMConversion,
3     DOMConversionMap,
4     DOMConversionOutput, ElementFormatType,
5     LexicalNode,
6     ParagraphNode,
7     SerializedParagraphNode,
8     Spread
9 } from "lexical";
10 import {EditorConfig} from "lexical/LexicalEditor";
11
12
13 export type SerializedCustomParagraphNode = Spread<{
14     id: string;
15 }, SerializedParagraphNode>
16
17 export class CustomParagraphNode extends ParagraphNode {
18     __id: string = '';
19
20     static getType() {
21         return 'custom-paragraph';
22     }
23
24     setId(id: string) {
25         const self = this.getWritable();
26         self.__id = id;
27     }
28
29     getId(): string {
30         const self = this.getLatest();
31         return self.__id;
32     }
33
34     static clone(node: CustomParagraphNode): CustomParagraphNode {
35         const newNode = new CustomParagraphNode(node.__key);
36         newNode.__id = node.__id;
37         return newNode;
38     }
39
40     createDOM(config: EditorConfig): HTMLElement {
41         const dom = super.createDOM(config);
42         if (this.__id) {
43             dom.setAttribute('id', this.__id);
44         }
45
46         return dom;
47     }
48
49     exportJSON(): SerializedCustomParagraphNode {
50         return {
51             ...super.exportJSON(),
52             type: 'custom-paragraph',
53             version: 1,
54             id: this.__id,
55         };
56     }
57
58     static importJSON(serializedNode: SerializedCustomParagraphNode): CustomParagraphNode {
59         const node = $createCustomParagraphNode();
60         node.setId(serializedNode.id);
61         return node;
62     }
63
64     static importDOM(): DOMConversionMap|null {
65         return {
66             p(node: HTMLElement): DOMConversion|null {
67                 return {
68                     conversion: (element: HTMLElement): DOMConversionOutput|null => {
69                         const node = $createCustomParagraphNode();
70                         if (element.style) {
71                             node.setFormat(element.style.textAlign as ElementFormatType);
72                             const indent = parseInt(element.style.textIndent, 10) / 20;
73                             if (indent > 0) {
74                                 node.setIndent(indent);
75                             }
76                         }
77
78                         if (element.id) {
79                             node.setId(element.id);
80                         }
81
82                         return {node};
83                     },
84                     priority: 1,
85                 };
86             },
87         };
88     }
89 }
90
91 export function $createCustomParagraphNode(): CustomParagraphNode {
92     return new CustomParagraphNode();
93 }
94
95 export function $isCustomParagraphNode(node: LexicalNode | null | undefined): node is CustomParagraphNode {
96     return node instanceof CustomParagraphNode;
97 }