1 import * as DrawIO from '../services/drawio';
4 let currentNode = null;
7 * @type {WysiwygConfigOptions}
11 function isDrawing(node) {
12 return node.hasAttribute('drawio-diagram');
15 function showDrawingManager(mceEditor, selectedNode = null) {
16 pageEditor = mceEditor;
17 currentNode = selectedNode;
19 /** @type {ImageManager} * */
20 const imageManager = window.$components.first('image-manager');
21 imageManager.show(image => {
23 const imgElem = selectedNode.querySelector('img');
24 pageEditor.undoManager.transact(() => {
25 pageEditor.dom.setAttrib(imgElem, 'src', image.url);
26 pageEditor.dom.setAttrib(selectedNode, 'drawio-diagram', image.id);
29 const imgHTML = `<div drawio-diagram="${image.id}" contenteditable="false"><img src="${image.url}"></div>`;
30 pageEditor.insertContent(imgHTML);
35 async function updateContent(pngData) {
36 const id = `image-${Math.random().toString(16).slice(2)}`;
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);
64 setTimeout(async () => {
65 pageEditor.insertContent(`<div drawio-diagram contenteditable="false"><img src="${loadingImage}" id="${id}"></div>`);
68 const img = await DrawIO.upload(pngData, options.pageId);
69 pageEditor.undoManager.transact(() => {
70 pageEditor.dom.setAttrib(id, 'src', img.url);
71 pageEditor.dom.get(id).parentNode.setAttribute('drawio-diagram', img.id);
74 pageEditor.dom.remove(id);
75 handleUploadError(err);
80 function drawingInit() {
82 return Promise.resolve('');
85 const drawingId = currentNode.getAttribute('drawio-diagram');
86 return DrawIO.load(drawingId);
89 function showDrawingEditor(mceEditor, selectedNode = null) {
90 pageEditor = mceEditor;
91 currentNode = selectedNode;
92 DrawIO.show(options.drawioUrl, drawingInit, updateContent);
96 * @param {Editor} editor
98 function register(editor) {
99 editor.addCommand('drawio', () => {
100 const selectedNode = editor.selection.getNode();
101 showDrawingEditor(editor, isDrawing(selectedNode) ? selectedNode : null);
104 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>`);
106 editor.ui.registry.addSplitButton('drawio', {
107 tooltip: 'Insert/edit drawing',
110 editor.execCommand('drawio');
111 // Hack to de-focus the tinymce editor toolbar
112 window.document.body.dispatchEvent(new Event('mousedown', {bubbles: true}));
118 text: 'Drawing manager',
119 value: 'drawing-manager',
123 onItemAction(api, value) {
124 if (value === 'drawing-manager') {
125 const selectedNode = editor.selection.getNode();
126 showDrawingManager(editor, isDrawing(selectedNode) ? selectedNode : null);
131 editor.on('dblclick', () => {
132 const selectedNode = editor.selection.getNode();
133 if (!isDrawing(selectedNode)) return;
134 showDrawingEditor(editor, selectedNode);
137 editor.on('SetContent', () => {
138 const drawings = editor.dom.select('body > div[drawio-diagram]');
139 if (!drawings.length) return;
141 editor.undoManager.transact(() => {
142 for (const drawing of drawings) {
143 drawing.setAttribute('contenteditable', 'false');
151 * @param {WysiwygConfigOptions} providedOptions
152 * @return {function(Editor, string)}
154 export function getPlugin(providedOptions) {
155 options = providedOptions;