]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/nodes/details.ts
119619da6adb61ae0d5e4feffacfc9a01f7d3d2e
[bookstack] / resources / js / wysiwyg / nodes / details.ts
1 import {
2     DOMConversion,
3     DOMConversionMap, DOMConversionOutput,
4     ElementNode,
5     LexicalEditor,
6     LexicalNode,
7     SerializedElementNode, Spread,
8 } from 'lexical';
9 import type {EditorConfig} from "lexical/LexicalEditor";
10
11 import {el} from "../utils/dom";
12
13 export type SerializedDetailsNode = Spread<{
14     id: string;
15 }, SerializedElementNode>
16
17 export class DetailsNode extends ElementNode {
18     __id: string = '';
19
20     static getType() {
21         return 'details';
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: DetailsNode): DetailsNode {
35         const newNode =  new DetailsNode(node.__key);
36         newNode.__id = node.__id;
37         return newNode;
38     }
39
40     createDOM(_config: EditorConfig, _editor: LexicalEditor) {
41         const el = document.createElement('details');
42         if (this.__id) {
43             el.setAttribute('id', this.__id);
44         }
45
46         return el;
47     }
48
49     updateDOM(prevNode: DetailsNode, dom: HTMLElement) {
50         return prevNode.__id !== this.__id;
51     }
52
53     static importDOM(): DOMConversionMap|null {
54         return {
55             details(node: HTMLElement): DOMConversion|null {
56                 return {
57                     conversion: (element: HTMLElement): DOMConversionOutput|null => {
58                         const node = new DetailsNode();
59                         if (element.id) {
60                             node.setId(element.id);
61                         }
62
63                         return {node};
64                     },
65                     priority: 3,
66                 };
67             },
68         };
69     }
70
71     exportJSON(): SerializedDetailsNode {
72         return {
73             ...super.exportJSON(),
74             type: 'details',
75             version: 1,
76             id: this.__id,
77         };
78     }
79
80     static importJSON(serializedNode: SerializedDetailsNode): DetailsNode {
81         const node = $createDetailsNode();
82         node.setId(serializedNode.id);
83         return node;
84     }
85
86 }
87
88 export function $createDetailsNode() {
89     return new DetailsNode();
90 }
91
92 export function $isDetailsNode(node: LexicalNode | null | undefined): node is DetailsNode {
93     return node instanceof DetailsNode;
94 }
95
96 export class SummaryNode extends ElementNode {
97
98     static getType() {
99         return 'summary';
100     }
101
102     static clone(node: SummaryNode) {
103         return new SummaryNode(node.__key);
104     }
105
106     createDOM(_config: EditorConfig, _editor: LexicalEditor) {
107         return el('summary');
108     }
109
110     updateDOM(prevNode: DetailsNode, dom: HTMLElement) {
111         return false;
112     }
113
114     static importDOM(): DOMConversionMap|null {
115         return {
116             summary(node: HTMLElement): DOMConversion|null {
117                 return {
118                     conversion: (element: HTMLElement): DOMConversionOutput|null => {
119                         return {
120                             node: new SummaryNode(),
121                         };
122                     },
123                     priority: 3,
124                 };
125             },
126         };
127     }
128
129     exportJSON(): SerializedElementNode {
130         return {
131             ...super.exportJSON(),
132             type: 'summary',
133             version: 1,
134         };
135     }
136
137     static importJSON(serializedNode: SerializedElementNode): SummaryNode {
138         return $createSummaryNode();
139     }
140
141 }
142
143 export function $createSummaryNode(): SummaryNode {
144     return new SummaryNode();
145 }
146
147 export function $isSummaryNode(node: LexicalNode | null | undefined): node is SummaryNode {
148     return node instanceof SummaryNode;
149 }