| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |     $createParagraphNode, | 
					
						
							|  |  |  |     DOMConversion, | 
					
						
							|  |  |  |     DOMConversionMap, DOMConversionOutput, | 
					
						
							|  |  |  |     ElementNode, | 
					
						
							|  |  |  |     LexicalEditor, | 
					
						
							|  |  |  |     LexicalNode, | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |     ParagraphNode, Spread | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  | } from 'lexical'; | 
					
						
							|  |  |  | import type {EditorConfig} from "lexical/LexicalEditor"; | 
					
						
							|  |  |  | import type {RangeSelection} from "lexical/LexicalSelection"; | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2024-09-10 22:55:46 +08:00
										 |  |  |     CommonBlockAlignment, commonPropertiesDifferent, deserializeCommonBlockNode, | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |     setCommonBlockPropsFromElement, | 
					
						
							|  |  |  |     updateElementWithCommonBlockProps | 
					
						
							| 
									
										
										
										
											2024-12-05 02:53:59 +08:00
										 |  |  | } from "lexical/nodes/common"; | 
					
						
							|  |  |  | import {SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode"; | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export type CalloutCategory = 'info' | 'danger' | 'warning' | 'success'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type SerializedCalloutNode = Spread<{ | 
					
						
							|  |  |  |     category: CalloutCategory; | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  | }, SerializedCommonBlockNode> | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 22:09:50 +08:00
										 |  |  | export class CalloutNode extends ElementNode { | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |     __id: string = ''; | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  |     __category: CalloutCategory = 'info'; | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |     __alignment: CommonBlockAlignment = ''; | 
					
						
							| 
									
										
										
										
											2024-09-10 22:55:46 +08:00
										 |  |  |     __inset: number = 0; | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static getType() { | 
					
						
							|  |  |  |         return 'callout'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 22:09:50 +08:00
										 |  |  |     static clone(node: CalloutNode) { | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |         const newNode = new CalloutNode(node.__category, node.__key); | 
					
						
							|  |  |  |         newNode.__id = node.__id; | 
					
						
							| 
									
										
										
										
											2024-09-08 20:37:13 +08:00
										 |  |  |         newNode.__alignment = node.__alignment; | 
					
						
							| 
									
										
										
										
											2024-09-10 22:55:46 +08:00
										 |  |  |         newNode.__inset = node.__inset; | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |         return newNode; | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  |     constructor(category: CalloutCategory, key?: string) { | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |         super(key); | 
					
						
							|  |  |  |         this.__category = category; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-29 01:04:48 +08:00
										 |  |  |     setCategory(category: CalloutCategory) { | 
					
						
							|  |  |  |         const self = this.getWritable(); | 
					
						
							|  |  |  |         self.__category = category; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getCategory(): CalloutCategory { | 
					
						
							|  |  |  |         const self = this.getLatest(); | 
					
						
							|  |  |  |         return self.__category; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |     setId(id: string) { | 
					
						
							|  |  |  |         const self = this.getWritable(); | 
					
						
							|  |  |  |         self.__id = id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getId(): string { | 
					
						
							|  |  |  |         const self = this.getLatest(); | 
					
						
							|  |  |  |         return self.__id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |     setAlignment(alignment: CommonBlockAlignment) { | 
					
						
							|  |  |  |         const self = this.getWritable(); | 
					
						
							|  |  |  |         self.__alignment = alignment; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getAlignment(): CommonBlockAlignment { | 
					
						
							|  |  |  |         const self = this.getLatest(); | 
					
						
							|  |  |  |         return self.__alignment; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 22:55:46 +08:00
										 |  |  |     setInset(size: number) { | 
					
						
							|  |  |  |         const self = this.getWritable(); | 
					
						
							|  |  |  |         self.__inset = size; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getInset(): number { | 
					
						
							|  |  |  |         const self = this.getLatest(); | 
					
						
							|  |  |  |         return self.__inset; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  |     createDOM(_config: EditorConfig, _editor: LexicalEditor) { | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |         const element = document.createElement('p'); | 
					
						
							|  |  |  |         element.classList.add('callout', this.__category || ''); | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |         updateElementWithCommonBlockProps(element, this); | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |         return element; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |     updateDOM(prevNode: CalloutNode): boolean { | 
					
						
							|  |  |  |         return prevNode.__category !== this.__category || | 
					
						
							|  |  |  |             commonPropertiesDifferent(prevNode, this); | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 22:09:50 +08:00
										 |  |  |     insertNewAfter(selection: RangeSelection, restoreSelection?: boolean): CalloutNode|ParagraphNode { | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |         const anchorOffset = selection ? selection.anchor.offset : 0; | 
					
						
							|  |  |  |         const newElement = anchorOffset === this.getTextContentSize() || !selection | 
					
						
							|  |  |  |             ? $createParagraphNode() : $createCalloutNode(this.__category); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         newElement.setDirection(this.getDirection()); | 
					
						
							|  |  |  |         this.insertAfter(newElement, restoreSelection); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (anchorOffset === 0 && !this.isEmpty() && selection) { | 
					
						
							|  |  |  |             const paragraph = $createParagraphNode(); | 
					
						
							|  |  |  |             paragraph.select(); | 
					
						
							|  |  |  |             this.replace(paragraph, true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return newElement; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  |     static importDOM(): DOMConversionMap|null { | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |         return { | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  |             p(node: HTMLElement): DOMConversion|null { | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |                 if (node.classList.contains('callout')) { | 
					
						
							|  |  |  |                     return { | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  |                         conversion: (element: HTMLElement): DOMConversionOutput|null => { | 
					
						
							|  |  |  |                             let category: CalloutCategory = 'info'; | 
					
						
							|  |  |  |                             const categories: CalloutCategory[] = ['info', 'success', 'warning', 'danger']; | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |                             for (const c of categories) { | 
					
						
							|  |  |  |                                 if (element.classList.contains(c)) { | 
					
						
							|  |  |  |                                     category = c; | 
					
						
							|  |  |  |                                     break; | 
					
						
							|  |  |  |                                 } | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |                             const node = new CalloutNode(category); | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |                             setCommonBlockPropsFromElement(element, node); | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |                             return { | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |                                 node, | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |                             }; | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                         priority: 3, | 
					
						
							|  |  |  |                     }; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return null; | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  |     exportJSON(): SerializedCalloutNode { | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |         return { | 
					
						
							|  |  |  |             ...super.exportJSON(), | 
					
						
							|  |  |  |             type: 'callout', | 
					
						
							|  |  |  |             version: 1, | 
					
						
							|  |  |  |             category: this.__category, | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |             id: this.__id, | 
					
						
							| 
									
										
										
										
											2024-08-18 23:51:08 +08:00
										 |  |  |             alignment: this.__alignment, | 
					
						
							| 
									
										
										
										
											2024-09-10 22:55:46 +08:00
										 |  |  |             inset: this.__inset, | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 22:09:50 +08:00
										 |  |  |     static importJSON(serializedNode: SerializedCalloutNode): CalloutNode { | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |         const node = $createCalloutNode(serializedNode.category); | 
					
						
							| 
									
										
										
										
											2024-09-10 22:55:46 +08:00
										 |  |  |         deserializeCommonBlockNode(serializedNode, node); | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  |         return node; | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 06:50:28 +08:00
										 |  |  | export function $createCalloutNode(category: CalloutCategory = 'info') { | 
					
						
							| 
									
										
										
										
											2024-05-28 22:09:50 +08:00
										 |  |  |     return new CalloutNode(category); | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-11 23:08:51 +08:00
										 |  |  | export function $isCalloutNode(node: LexicalNode | null | undefined): node is CalloutNode { | 
					
						
							| 
									
										
										
										
											2024-05-28 22:09:50 +08:00
										 |  |  |     return node instanceof CalloutNode; | 
					
						
							| 
									
										
										
										
											2024-05-28 03:23:45 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-05-29 01:04:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function $isCalloutNodeOfCategory(node: LexicalNode | null | undefined, category: CalloutCategory = 'info') { | 
					
						
							|  |  |  |     return node instanceof CalloutNode && (node as CalloutNode).getCategory() === category; | 
					
						
							|  |  |  | } |