| 
									
										
										
										
											2024-12-04 01:04:50 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |     $applyNodeReplacement, | 
					
						
							|  |  |  |     $createParagraphNode, | 
					
						
							|  |  |  |     type DOMConversionMap, | 
					
						
							|  |  |  |     type DOMConversionOutput, | 
					
						
							|  |  |  |     type DOMExportOutput, | 
					
						
							|  |  |  |     type EditorConfig, | 
					
						
							|  |  |  |     isHTMLElement, | 
					
						
							|  |  |  |     type LexicalEditor, | 
					
						
							|  |  |  |     LexicalNode, | 
					
						
							|  |  |  |     type NodeKey, | 
					
						
							|  |  |  |     type ParagraphNode, | 
					
						
							| 
									
										
										
										
											2024-12-05 02:53:59 +08:00
										 |  |  |     type RangeSelection | 
					
						
							| 
									
										
										
										
											2024-12-04 01:04:50 +08:00
										 |  |  | } from "lexical"; | 
					
						
							|  |  |  | import {addClassNamesToElement} from "@lexical/utils"; | 
					
						
							| 
									
										
										
										
											2024-12-05 02:53:59 +08:00
										 |  |  | import {CommonBlockNode, copyCommonBlockProperties, SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode"; | 
					
						
							| 
									
										
										
										
											2024-12-04 01:04:50 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |     commonPropertiesDifferent, deserializeCommonBlockNode, | 
					
						
							| 
									
										
										
										
											2024-12-05 02:53:59 +08:00
										 |  |  |     setCommonBlockPropsFromElement, | 
					
						
							| 
									
										
										
										
											2024-12-04 01:04:50 +08:00
										 |  |  |     updateElementWithCommonBlockProps | 
					
						
							| 
									
										
										
										
											2024-12-05 02:53:59 +08:00
										 |  |  | } from "lexical/nodes/common"; | 
					
						
							| 
									
										
										
										
											2024-12-04 01:04:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export type SerializedQuoteNode = SerializedCommonBlockNode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** @noInheritDoc */ | 
					
						
							|  |  |  | export class QuoteNode extends CommonBlockNode { | 
					
						
							|  |  |  |     static getType(): string { | 
					
						
							|  |  |  |         return 'quote'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static clone(node: QuoteNode): QuoteNode { | 
					
						
							|  |  |  |         const clone = new QuoteNode(node.__key); | 
					
						
							|  |  |  |         copyCommonBlockProperties(node, clone); | 
					
						
							|  |  |  |         return clone; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(key?: NodeKey) { | 
					
						
							|  |  |  |         super(key); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // View
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     createDOM(config: EditorConfig): HTMLElement { | 
					
						
							|  |  |  |         const element = document.createElement('blockquote'); | 
					
						
							|  |  |  |         addClassNamesToElement(element, config.theme.quote); | 
					
						
							|  |  |  |         updateElementWithCommonBlockProps(element, this); | 
					
						
							|  |  |  |         return element; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     updateDOM(prevNode: QuoteNode, dom: HTMLElement): boolean { | 
					
						
							|  |  |  |         return commonPropertiesDifferent(prevNode, this); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static importDOM(): DOMConversionMap | null { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             blockquote: (node: Node) => ({ | 
					
						
							|  |  |  |                 conversion: $convertBlockquoteElement, | 
					
						
							|  |  |  |                 priority: 0, | 
					
						
							|  |  |  |             }), | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     exportDOM(editor: LexicalEditor): DOMExportOutput { | 
					
						
							|  |  |  |         const {element} = super.exportDOM(editor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (element && isHTMLElement(element)) { | 
					
						
							|  |  |  |             if (this.isEmpty()) { | 
					
						
							|  |  |  |                 element.append(document.createElement('br')); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             element, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static importJSON(serializedNode: SerializedQuoteNode): QuoteNode { | 
					
						
							|  |  |  |         const node = $createQuoteNode(); | 
					
						
							|  |  |  |         deserializeCommonBlockNode(serializedNode, node); | 
					
						
							|  |  |  |         return node; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     exportJSON(): SerializedQuoteNode { | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             ...super.exportJSON(), | 
					
						
							|  |  |  |             type: 'quote', | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Mutation
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     insertNewAfter(_: RangeSelection, restoreSelection?: boolean): ParagraphNode { | 
					
						
							|  |  |  |         const newBlock = $createParagraphNode(); | 
					
						
							|  |  |  |         const direction = this.getDirection(); | 
					
						
							|  |  |  |         newBlock.setDirection(direction); | 
					
						
							|  |  |  |         this.insertAfter(newBlock, restoreSelection); | 
					
						
							|  |  |  |         return newBlock; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     collapseAtStart(): true { | 
					
						
							|  |  |  |         const paragraph = $createParagraphNode(); | 
					
						
							|  |  |  |         const children = this.getChildren(); | 
					
						
							|  |  |  |         children.forEach((child) => paragraph.append(child)); | 
					
						
							|  |  |  |         this.replace(paragraph); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     canMergeWhenEmpty(): true { | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function $createQuoteNode(): QuoteNode { | 
					
						
							|  |  |  |     return $applyNodeReplacement(new QuoteNode()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function $isQuoteNode( | 
					
						
							|  |  |  |     node: LexicalNode | null | undefined, | 
					
						
							|  |  |  | ): node is QuoteNode { | 
					
						
							|  |  |  |     return node instanceof QuoteNode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function $convertBlockquoteElement(element: HTMLElement): DOMConversionOutput { | 
					
						
							|  |  |  |     const node = $createQuoteNode(); | 
					
						
							|  |  |  |     setCommonBlockPropsFromElement(element, node); | 
					
						
							|  |  |  |     return {node}; | 
					
						
							|  |  |  | } |