--- /dev/null
+import {
+ DecoratorNode,
+ DOMConversion,
+ DOMConversionMap,
+ DOMConversionOutput,
+ LexicalEditor, LexicalNode,
+ SerializedLexicalNode,
+ Spread
+} from "lexical";
+import type {EditorConfig} from "lexical/LexicalEditor";
+import {el} from "../helpers";
+import {EditorDecoratorAdapter} from "../ui/framework/decorator";
+
+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 {
+ return new DiagramNode(node.__drawingId, node.__drawingUrl);
+ }
+
+ 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.__drawingUrl,
+ 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') || '';
+
+ return {
+ node: $createDiagramNode(drawingId, drawingUrl),
+ };
+ },
+ 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);
+}
+
+export function $isDiagramNode(node: LexicalNode | null | undefined) {
+ return node instanceof DiagramNode;
+}
+
+export function $openDrawingEditorForNode(editor: LexicalEditor, node: DiagramNode): void {
+ // Todo
+}
\ No newline at end of file
import {ImageDecorator} from "./decorators/image";
import {EditorUiContext} from "./framework/core";
import {CodeBlockDecorator} from "./decorators/code-block";
+import {DiagramDecorator} from "./decorators/diagram";
export function buildEditorUI(container: HTMLElement, element: HTMLElement, editor: LexicalEditor) {
const manager = new EditorUIManager();
// Register image decorator listener
manager.registerDecoratorType('image', ImageDecorator);
manager.registerDecoratorType('code', CodeBlockDecorator);
+ manager.registerDecoratorType('diagram', DiagramDecorator);
}
\ No newline at end of file