156 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
| import {
 | |
|     DecoratorNode,
 | |
|     DOMConversion,
 | |
|     DOMConversionMap,
 | |
|     DOMConversionOutput,
 | |
|     LexicalEditor,
 | |
|     SerializedLexicalNode,
 | |
|     Spread
 | |
| } from "lexical";
 | |
| import type {EditorConfig} from "lexical/LexicalEditor";
 | |
| import {EditorDecoratorAdapter} from "../../ui/framework/decorator";
 | |
| import {el} from "../../utils/dom";
 | |
| 
 | |
| export type SerializedDiagramNode = Spread<{
 | |
|     id: string;
 | |
|     drawingId: string;
 | |
|     drawingUrl: string;
 | |
| }, SerializedLexicalNode>
 | |
| 
 | |
| export class DiagramNode extends DecoratorNode<EditorDecoratorAdapter> {
 | |
|     __id: string = '';
 | |
|     __drawingId: string = '';
 | |
|     __drawingUrl: string = '';
 | |
| 
 | |
|     static getType(): string {
 | |
|         return 'diagram';
 | |
|     }
 | |
| 
 | |
|     static clone(node: DiagramNode): DiagramNode {
 | |
|         const newNode = new DiagramNode(node.__drawingId, node.__drawingUrl);
 | |
|         newNode.__id = node.__id;
 | |
|         return newNode;
 | |
|     }
 | |
| 
 | |
|     constructor(drawingId: string, drawingUrl: string, key?: string) {
 | |
|         super(key);
 | |
|         this.__drawingId = drawingId;
 | |
|         this.__drawingUrl = drawingUrl;
 | |
|     }
 | |
| 
 | |
|     setDrawingIdAndUrl(drawingId: string, drawingUrl: string): void {
 | |
|         const self = this.getWritable();
 | |
|         self.__drawingUrl = drawingUrl;
 | |
|         self.__drawingId = drawingId;
 | |
|     }
 | |
| 
 | |
|     getDrawingIdAndUrl(): { id: string, url: string } {
 | |
|         const self = this.getLatest();
 | |
|         return {
 | |
|             id: self.__drawingId,
 | |
|             url: self.__drawingUrl,
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     setId(id: string) {
 | |
|         const self = this.getWritable();
 | |
|         self.__id = id;
 | |
|     }
 | |
| 
 | |
|     getId(): string {
 | |
|         const self = this.getLatest();
 | |
|         return self.__id;
 | |
|     }
 | |
| 
 | |
|     decorate(editor: LexicalEditor, config: EditorConfig): EditorDecoratorAdapter {
 | |
|         return {
 | |
|             type: 'diagram',
 | |
|             getNode: () => this,
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     isInline(): boolean {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     isIsolated() {
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     createDOM(_config: EditorConfig, _editor: LexicalEditor) {
 | |
|         return el('div', {
 | |
|             id: this.__id || null,
 | |
|             'drawio-diagram': this.__drawingId,
 | |
|         }, [
 | |
|             el('img', {src: this.__drawingUrl}),
 | |
|         ]);
 | |
|     }
 | |
| 
 | |
|     updateDOM(prevNode: DiagramNode, dom: HTMLElement) {
 | |
|         const img = dom.querySelector('img');
 | |
|         if (!img) return false;
 | |
| 
 | |
|         if (prevNode.__id !== this.__id) {
 | |
|             dom.setAttribute('id', this.__id);
 | |
|         }
 | |
| 
 | |
|         if (prevNode.__drawingUrl !== this.__drawingUrl) {
 | |
|             img.setAttribute('src', this.__drawingUrl);
 | |
|         }
 | |
| 
 | |
|         if (prevNode.__drawingId !== this.__drawingId) {
 | |
|             dom.setAttribute('drawio-diagram', this.__drawingId);
 | |
|         }
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     static importDOM(): DOMConversionMap | null {
 | |
|         return {
 | |
|             div(node: HTMLElement): DOMConversion | null {
 | |
| 
 | |
|                 if (!node.hasAttribute('drawio-diagram')) {
 | |
|                     return null;
 | |
|                 }
 | |
| 
 | |
|                 return {
 | |
|                     conversion: (element: HTMLElement): DOMConversionOutput | null => {
 | |
| 
 | |
|                         const img = element.querySelector('img');
 | |
|                         const drawingUrl = img?.getAttribute('src') || '';
 | |
|                         const drawingId = element.getAttribute('drawio-diagram') || '';
 | |
|                         const node = $createDiagramNode(drawingId, drawingUrl);
 | |
| 
 | |
|                         if (element.id) {
 | |
|                             node.setId(element.id);
 | |
|                         }
 | |
| 
 | |
|                         return { node };
 | |
|                     },
 | |
|                     priority: 3,
 | |
|                 };
 | |
|             },
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     exportJSON(): SerializedDiagramNode {
 | |
|         return {
 | |
|             type: 'diagram',
 | |
|             version: 1,
 | |
|             id: this.__id,
 | |
|             drawingId: this.__drawingId,
 | |
|             drawingUrl: this.__drawingUrl,
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     static importJSON(serializedNode: SerializedDiagramNode): DiagramNode {
 | |
|         const node = $createDiagramNode(serializedNode.drawingId, serializedNode.drawingUrl);
 | |
|         node.setId(serializedNode.id || '');
 | |
|         return node;
 | |
|     }
 | |
| }
 | |
| 
 | |
| export function $createDiagramNode(drawingId: string = '', drawingUrl: string = ''): DiagramNode {
 | |
|     return new DiagramNode(drawingId, drawingUrl);
 | |
| }
 |