]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/nodes/callout.js
Lexical: Played with commands, extracted & improved callout node
[bookstack] / resources / js / wysiwyg / nodes / callout.js
1 import {$createParagraphNode, ElementNode} from 'lexical';
2
3 export class Callout extends ElementNode {
4
5     __category = 'info';
6
7     static getType() {
8         return 'callout';
9     }
10
11     static clone(node) {
12         return new Callout(node.__category, node.__key);
13     }
14
15     constructor(category, key) {
16         super(key);
17         this.__category = category;
18     }
19
20     createDOM(_config, _editor) {
21         const element = document.createElement('p');
22         element.classList.add('callout', this.__category || '');
23         return element;
24     }
25
26     updateDOM(prevNode, dom) {
27         // Returning false tells Lexical that this node does not need its
28         // DOM element replacing with a new copy from createDOM.
29         return false;
30     }
31
32     insertNewAfter(selection, restoreSelection) {
33         const anchorOffset = selection ? selection.anchor.offset : 0;
34         const newElement = anchorOffset === this.getTextContentSize() || !selection
35             ? $createParagraphNode() : $createCalloutNode(this.__category);
36
37         newElement.setDirection(this.getDirection());
38         this.insertAfter(newElement, restoreSelection);
39
40         if (anchorOffset === 0 && !this.isEmpty() && selection) {
41             const paragraph = $createParagraphNode();
42             paragraph.select();
43             this.replace(paragraph, true);
44         }
45
46         return newElement;
47     }
48
49     static importDOM() {
50         return {
51             p: node => {
52                 if (node.classList.contains('callout')) {
53                     return {
54                         conversion: element => {
55                             let category = 'info';
56                             const categories = ['info', 'success', 'warning', 'danger'];
57
58                             for (const c of categories) {
59                                 if (element.classList.contains(c)) {
60                                     category = c;
61                                     break;
62                                 }
63                             }
64
65                             return {
66                                 node: new Callout(category),
67                             };
68                         },
69                         priority: 3,
70                     };
71                 }
72                 return null;
73             },
74         };
75     }
76
77     exportJSON() {
78         return {
79             ...super.exportJSON(),
80             type: 'callout',
81             version: 1,
82             category: this.__category,
83         };
84     }
85
86     static importJSON(serializedNode) {
87         return $createCalloutNode(serializedNode.category);
88     }
89
90 }
91
92 export function $createCalloutNode(category = 'info') {
93     return new Callout(category);
94 }
95
96 export function $isCalloutNode(node) {
97     return node instanceof Callout;
98 }