1 import * as DrawIO from '../services/drawio.ts';
2 import {wait} from '../services/util.ts';
5 let currentNode = null;
8 * @type {WysiwygConfigOptions}
12 function isDrawing(node) {
13 return node.hasAttribute('drawio-diagram');
16 function showDrawingManager(mceEditor, selectedNode = null) {
17 pageEditor = mceEditor;
18 currentNode = selectedNode;
20 /** @type {ImageManager} * */
21 const imageManager = window.$components.first('image-manager');
22 imageManager.show(image => {
24 const imgElem = selectedNode.querySelector('img');
25 pageEditor.undoManager.transact(() => {
26 pageEditor.dom.setAttrib(imgElem, 'src', image.url);
27 pageEditor.dom.setAttrib(selectedNode, 'drawio-diagram', image.id);
30 const imgHTML = `<div drawio-diagram="${image.id}" contenteditable="false"><img src="${image.url}"></div>`;
31 pageEditor.insertContent(imgHTML);
36 async function updateContent(pngData) {
37 const loadingImage = window.baseUrl('/loading.gif');
39 const handleUploadError = error => {
40 if (error.status === 413) {
41 window.$events.emit('error', options.translations.serverUploadLimitText);
43 window.$events.emit('error', options.translations.imageUploadErrorText);
48 // Handle updating an existing image
51 const imgElem = currentNode.querySelector('img');
53 const img = await DrawIO.upload(pngData, options.pageId);
54 pageEditor.undoManager.transact(() => {
55 pageEditor.dom.setAttrib(imgElem, 'src', img.url);
56 pageEditor.dom.setAttrib(currentNode, 'drawio-diagram', img.id);
59 handleUploadError(err);
60 throw new Error(`Failed to save image with error: ${err}`);
67 const id = `drawing-${Math.random().toString(16).slice(2)}`;
68 const wrapId = `drawing-wrap-${Math.random().toString(16).slice(2)}`;
69 pageEditor.insertContent(`<div drawio-diagram contenteditable="false" id="${wrapId}"><img src="${loadingImage}" id="${id}"></div>`);
73 const img = await DrawIO.upload(pngData, options.pageId);
74 pageEditor.undoManager.transact(() => {
75 pageEditor.dom.setAttrib(id, 'src', img.url);
76 pageEditor.dom.setAttrib(wrapId, 'drawio-diagram', img.id);
79 pageEditor.dom.remove(wrapId);
80 handleUploadError(err);
81 throw new Error(`Failed to save image with error: ${err}`);
85 function drawingInit() {
87 return Promise.resolve('');
90 const drawingId = currentNode.getAttribute('drawio-diagram');
91 return DrawIO.load(drawingId);
94 function showDrawingEditor(mceEditor, selectedNode = null) {
95 pageEditor = mceEditor;
96 currentNode = selectedNode;
97 DrawIO.show(options.drawioUrl, drawingInit, updateContent);
101 * @param {Editor} editor
103 function register(editor) {
104 editor.addCommand('drawio', () => {
105 const selectedNode = editor.selection.getNode();
106 showDrawingEditor(editor, isDrawing(selectedNode) ? selectedNode : null);
109 editor.ui.registry.addIcon('diagram', `<svg width="24" height="24" fill="${options.darkMode ? '#BBB' : '#000000'}" xmlns="http://www.w3.org/2000/svg"><path d="M20.716 7.639V2.845h-4.794v1.598h-7.99V2.845H3.138v4.794h1.598v7.99H3.138v4.794h4.794v-1.598h7.99v1.598h4.794v-4.794h-1.598v-7.99zM4.736 4.443h1.598V6.04H4.736zm1.598 14.382H4.736v-1.598h1.598zm9.588-1.598h-7.99v-1.598H6.334v-7.99h1.598V6.04h7.99v1.598h1.598v7.99h-1.598zm3.196 1.598H17.52v-1.598h1.598zM17.52 6.04V4.443h1.598V6.04zm-4.21 7.19h-2.79l-.582 1.599H8.643l2.717-7.191h1.119l2.724 7.19h-1.302zm-2.43-1.006h2.086l-1.039-3.06z"/></svg>`);
111 editor.ui.registry.addSplitButton('drawio', {
112 tooltip: 'Insert/edit drawing',
115 editor.execCommand('drawio');
116 // Hack to de-focus the tinymce editor toolbar
117 window.document.body.dispatchEvent(new Event('mousedown', {bubbles: true}));
123 text: 'Drawing manager',
124 value: 'drawing-manager',
128 onItemAction(api, value) {
129 if (value === 'drawing-manager') {
130 const selectedNode = editor.selection.getNode();
131 showDrawingManager(editor, isDrawing(selectedNode) ? selectedNode : null);
136 editor.on('dblclick', () => {
137 const selectedNode = editor.selection.getNode();
138 if (!isDrawing(selectedNode)) return;
139 showDrawingEditor(editor, selectedNode);
142 editor.on('SetContent', () => {
143 const drawings = editor.dom.select('body > div[drawio-diagram]');
144 if (!drawings.length) return;
146 editor.undoManager.transact(() => {
147 for (const drawing of drawings) {
148 drawing.setAttribute('contenteditable', 'false');
156 * @param {WysiwygConfigOptions} providedOptions
157 * @return {function(Editor, string)}
159 export function getPlugin(providedOptions) {
160 options = providedOptions;