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