mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-12-11 20:54:38 +08:00
158 lines
4.2 KiB
TypeScript
158 lines
4.2 KiB
TypeScript
|
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
|
||
|
}
|