import DrawIO from "../services/drawio"; import {build} from "./config"; 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; // Show image manager window.ImageManager.show(function (image) { if (selectedNode) { pageEditor.dom.replace(buildDrawingNode(image), selectedNode); } else { const drawingHtml = DrawIO.buildDrawingContentHtml(image); pageEditor.insertContent(drawingHtml); } }, 'drawio'); } function showDrawingEditor(mceEditor, selectedNode = null) { pageEditor = mceEditor; currentNode = selectedNode; DrawIO.show(options.drawioUrl, drawingInit, updateContent); } function buildDrawingNode(drawing) { const drawingEl = DrawIO.buildDrawingContentNode(drawing); drawingEl.setAttribute('contenteditable', 'false'); drawingEl.setAttribute('data-ephox-embed-iri', 'true'); return drawingEl; } async function updateContent(drawingData) { 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.log(error); }; // Handle updating an existing image if (currentNode) { DrawIO.close(); try { const img = await DrawIO.upload(drawingData, options.pageId); pageEditor.dom.replace(buildDrawingNode(img), currentNode); } catch (err) { handleUploadError(err); } return; } setTimeout(async () => { pageEditor.insertContent(`
Loading
`); DrawIO.close(); try { const img = await DrawIO.upload(drawingData, options.pageId); pageEditor.dom.replace(buildDrawingNode(img), pageEditor.dom.get(id).parentNode); } catch (err) { pageEditor.dom.remove(id); handleUploadError(err); } }, 5); } function drawingInit() { if (!currentNode) { return Promise.resolve(''); } let drawingId = currentNode.getAttribute('drawio-diagram'); return DrawIO.load(drawingId); } /** * @param {WysiwygConfigOptions} providedOptions * @return {function(Editor, string)} */ export function getPlugin(providedOptions) { options = providedOptions; return function(editor, url) { 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'); }, 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', event => { let selectedNode = editor.selection.getNode(); if (!isDrawing(selectedNode)) return; showDrawingEditor(editor, selectedNode); }); editor.on('PreInit', () => { editor.parser.addNodeFilter('div', function(nodes) { for (const node of nodes) { if (node.attr('drawio-diagram')) { // Set content editable to be false to prevent direct editing of child content. node.attr('contenteditable', 'false'); // Set this attribute to prevent drawing contents being parsed as media embeds // to avoid contents being replaced with placeholder images. // TinyMCE embed plugin sources looks for this attribute in its logic. node.attr('data-ephox-embed-iri', 'true'); } } }); editor.serializer.addNodeFilter('div', function(nodes) { for (const node of nodes) { // Clean up content attributes if (node.attr('drawio-diagram')) { node.attr('contenteditable', null); node.attr('data-ephox-embed-iri', null); } } }); }); }; }