"use strict";
-const Code = require('../code');
+const Code = require('../libs/code');
+const DrawIO = require('../libs/drawio');
/**
* Handle pasting images from clipboard.
let formData = new FormData();
formData.append('file', file, remoteFilename);
- return window.$http.post('/images/gallery/upload', formData).then(resp => (resp.data));
+ return window.$http.post(window.baseUrl('/images/gallery/upload'), formData).then(resp => (resp.data));
}
function registerEditorShortcuts(editor) {
});
}
-codePlugin();
function drawIoPlugin() {
const drawIoUrl = 'https://www.draw.io/?embed=1&ui=atlas&spin=1&proto=json';
let iframe = null;
let pageEditor = null;
+ let currentNode = null;
function isDrawing(node) {
return node.hasAttribute('drawio-diagram');
}
- function showDrawingEditor(mceEditor) {
+ function showDrawingEditor(mceEditor, selectedNode = null) {
pageEditor = mceEditor;
- iframe = document.createElement('iframe');
- iframe.setAttribute('frameborder', '0');
- window.addEventListener('message', drawReceive);
- iframe.setAttribute('src', drawIoUrl);
- iframe.setAttribute('class', 'fullscreen');
- document.body.appendChild(iframe);
+ currentNode = selectedNode;
+ DrawIO.show(drawingInit, updateContent);
}
- function drawReceive(event) {
- if (!event.data || event.data.length < 1) return;
- let message = JSON.parse(event.data);
- console.log(message);
- if (message.event === 'init') {
- drawEventInit();
- } else if (message.event === 'exit') {
- drawEventClose();
- } else if (message.event === 'save') {
- drawEventSave(message);
- } else if (message.event === 'export') {
- drawEventExport(message);
+ function updateContent(pngData) {
+ let id = "image-" + Math.random().toString(16).slice(2);
+ let loadingImage = window.baseUrl('/loading.gif');
+ let data = {
+ image: pngData,
+ uploaded_to: Number(document.getElementById('page-editor').getAttribute('page-id'))
+ };
+
+ // Handle updating an existing image
+ if (currentNode) {
+ DrawIO.close();
+ let imgElem = currentNode.querySelector('img');
+ let drawingId = currentNode.getAttribute('drawio-diagram');
+ window.$http.put(window.baseUrl(`/images/drawing/upload/${drawingId}`), data).then(resp => {
+ pageEditor.dom.setAttrib(imgElem, 'src', `${resp.data.url}?updated=${Date.now()}`);
+ }).catch(err => {
+ window.$events.emit('error', trans('errors.image_upload_error'));
+ console.log(err);
+ });
+ return;
}
- }
-
- function updateContent(svg) {
- let svgWrap = document.createElement('div');
- svgWrap.setAttribute('drawio-diagram', svg);
- svgWrap.setAttribute('contenteditable', 'false');
- pageEditor.insertContent(svgWrap.outerHTML);
- }
-
- function b64DecodeUnicode(str) {
- str = str.split(';base64,')[1];
- // Going backwards: from bytestream, to percent-encoding, to original string.
- return decodeURIComponent(atob(str).split('').map(function(c) {
- return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
- }).join(''));
- }
-
- function drawEventExport(message) {
- updateContent(message.data);
- }
- function drawEventSave(message) {
- drawPostMessage({action: 'export', format: 'svg', xml: message.xml, spin: 'Updating drawing'});
+ setTimeout(() => {
+ pageEditor.insertContent(`<div drawio-diagram contenteditable="false"><img src="${loadingImage}" id="${id}"></div>`);
+ DrawIO.close();
+ window.$http.post(window.baseUrl('/images/drawing/upload'), data).then(resp => {
+ pageEditor.dom.setAttrib(id, 'src', resp.data.url);
+ pageEditor.dom.get(id).parentNode.setAttribute('drawio-diagram', resp.data.id);
+ }).catch(err => {
+ pageEditor.dom.remove(id);
+ window.$events.emit('error', trans('errors.image_upload_error'));
+ console.log(err);
+ });
+ }, 5);
}
- function drawEventInit() {
- drawPostMessage({action: 'load', autosave: 1, xml: ''});
- }
- function drawEventClose() {
- window.removeEventListener('message', drawReceive);
- if (iframe) document.body.removeChild(iframe);
- }
+ function drawingInit() {
+ if (!currentNode) {
+ return Promise.resolve('');
+ }
- function drawPostMessage(data) {
- iframe.contentWindow.postMessage(JSON.stringify(data), '*');
+ let drawingId = currentNode.getAttribute('drawio-diagram');
+ return window.$http.get(window.baseUrl(`/images/base64/${drawingId}`)).then(resp => {
+ return `data:image/png;base64,${resp.data.content}`;
+ });
}
window.tinymce.PluginManager.add('drawio', function(editor, url) {
- let $ = editor.$;
-
editor.addCommand('drawio', () => {
showDrawingEditor(editor);
});
editor.addButton('drawio', {
- text: 'Drawing',
- icon: false,
+ tooltip: 'Drawing',
+ image: window.baseUrl('/icon/drawing.svg?color=000000'),
cmd: 'drawio'
});
editor.on('dblclick', event => {
let selectedNode = editor.selection.getNode();
if (!isDrawing(selectedNode)) return;
- showDrawingEditor(editor);
- });
-
- editor.on('PreProcess', function (e) {
- $('div[drawio-diagram]', e.node).
- each((index, elem) => {
- let $elem = $(elem);
- let svgData = b64DecodeUnicode($elem.attr('drawio-diagram'));
- $elem.html(svgData);
- });
+ showDrawingEditor(editor, selectedNode);
});
editor.on('SetContent', function () {
-
- let drawings = $('body > div[drawio-diagram]');
-
+ let drawings = editor.$('body > div[drawio-diagram]');
if (!drawings.length) return;
+
editor.undoManager.transact(function () {
drawings.each((index, elem) => {
- let svgContent = b64DecodeUnicode(elem.getAttribute('drawio-diagram'));
elem.setAttribute('contenteditable', 'false');
- elem.innerHTML = svgContent;
});
});
});
});
}
-drawIoPlugin();
window.tinymce.PluginManager.add('customhr', function (editor) {
editor.addCommand('InsertHorizontalRule', function () {
});
});
-
+// Load plugins
+let plugins = "image table textcolor paste link autolink fullscreen imagetools code customhr autosave lists codeeditor";
+codePlugin();
+if (document.querySelector('[drawio-enabled]').getAttribute('drawio-enabled') === 'true') {
+ drawIoPlugin();
+ plugins += ' drawio';
+}
module.exports = {
selector: '#html-editor',
content_css: [
window.baseUrl('/css/styles.css'),
- window.baseUrl('/libs/material-design-iconic-font/css/material-design-iconic-font.min.css')
],
branding: false,
body_class: 'page-content',
paste_data_images: false,
extended_valid_elements: 'pre[*],svg[*],div[drawio-diagram]',
automatic_uploads: false,
- valid_children: "-div[p|h1|h2|h3|h4|h5|h6|blockquote],+div[pre],+div[svg],+svg",
- plugins: "image table textcolor paste link autolink fullscreen imagetools code customhr autosave lists codeeditor drawio",
+ valid_children: "-div[p|h1|h2|h3|h4|h5|h6|blockquote],+div[pre],+div[img]",
+ plugins: plugins,
imagetools_toolbar: 'imageoptions',
- toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr | removeformat code fullscreen drawio",
+ toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr drawio | removeformat code fullscreen",
content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
style_formats: [
{title: "Header Large", format: "h2"},