import * as DrawIO from '../services/drawio'; import {wait} from '../services/util'; let pageEditor = null; let currentNode = null; /** * @type {WysiwygConfigOptions} */ let options = {}; function isDrawing(node) { return node.hasAttribute('drawio-diagram'); } function showDrawingManager(mceEditor, selectedNode = null) { pageEditor = mceEditor; currentNode = selectedNode; /** @type {ImageManager} * */ const imageManager = window.$components.first('image-manager'); imageManager.show(image => { if (selectedNode) { const imgElem = selectedNode.querySelector('img'); pageEditor.undoManager.transact(() => { pageEditor.dom.setAttrib(imgElem, 'src', image.url); pageEditor.dom.setAttrib(selectedNode, 'drawio-diagram', image.id); }); } else { const imgHTML = `
`; pageEditor.insertContent(imgHTML); } }, 'drawio'); } async function updateContent(pngData) { const id = `image-${Math.random().toString(16).slice(2)}`; const loadingImage = window.baseUrl('/loading.gif'); const handleUploadError = error => { if (error.status === 413) { window.$events.emit('error', options.translations.serverUploadLimitText); } else { window.$events.emit('error', options.translations.imageUploadErrorText); } console.error(error); }; // Handle updating an existing image if (currentNode) { DrawIO.close(); const imgElem = currentNode.querySelector('img'); try { const img = await DrawIO.upload(pngData, options.pageId); pageEditor.undoManager.transact(() => { pageEditor.dom.setAttrib(imgElem, 'src', img.url); pageEditor.dom.setAttrib(currentNode, 'drawio-diagram', img.id); }); } catch (err) { handleUploadError(err); throw new Error(`Failed to save image with error: ${err}`); } return; } await wait(5); pageEditor.insertContent(`
`); DrawIO.close(); try { const img = await DrawIO.upload(pngData, options.pageId); pageEditor.undoManager.transact(() => { pageEditor.dom.setAttrib(id, 'src', img.url); pageEditor.dom.get(id).parentNode.setAttribute('drawio-diagram', img.id); }); } catch (err) { pageEditor.dom.remove(id); handleUploadError(err); throw new Error(`Failed to save image with error: ${err}`); } } function drawingInit() { if (!currentNode) { return Promise.resolve(''); } const drawingId = currentNode.getAttribute('drawio-diagram'); return DrawIO.load(drawingId); } function showDrawingEditor(mceEditor, selectedNode = null) { pageEditor = mceEditor; currentNode = selectedNode; DrawIO.show(options.drawioUrl, drawingInit, updateContent); } /** * @param {Editor} editor */ function register(editor) { editor.addCommand('drawio', () => { const selectedNode = editor.selection.getNode(); showDrawingEditor(editor, isDrawing(selectedNode) ? selectedNode : null); }); editor.ui.registry.addIcon('diagram', ``); editor.ui.registry.addSplitButton('drawio', { tooltip: 'Insert/edit drawing', icon: 'diagram', onAction() { editor.execCommand('drawio'); // Hack to de-focus the tinymce editor toolbar window.document.body.dispatchEvent(new Event('mousedown', {bubbles: true})); }, fetch(callback) { callback([ { type: 'choiceitem', text: 'Drawing manager', value: 'drawing-manager', }, ]); }, onItemAction(api, value) { if (value === 'drawing-manager') { const selectedNode = editor.selection.getNode(); showDrawingManager(editor, isDrawing(selectedNode) ? selectedNode : null); } }, }); editor.on('dblclick', () => { const selectedNode = editor.selection.getNode(); if (!isDrawing(selectedNode)) return; showDrawingEditor(editor, selectedNode); }); editor.on('SetContent', () => { const drawings = editor.dom.select('body > div[drawio-diagram]'); if (!drawings.length) return; editor.undoManager.transact(() => { for (const drawing of drawings) { drawing.setAttribute('contenteditable', 'false'); } }); }); } /** * * @param {WysiwygConfigOptions} providedOptions * @return {function(Editor, string)} */ export function getPlugin(providedOptions) { options = providedOptions; return register; }