From c73377b8f164475645fa9af8ae67b2e32e2cb022 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 14 Feb 2023 09:15:55 +0100 Subject: [PATCH] Uncompress drawio XML for better chainpad patches --- bower.json | 4 ++- www/drawio/empty.drawio | 1 - www/drawio/inner.js | 64 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 63 insertions(+), 6 deletions(-) delete mode 100644 www/drawio/empty.drawio diff --git a/bower.json b/bower.json index d7dd1eca7..3cad2a805 100644 --- a/bower.json +++ b/bower.json @@ -49,7 +49,9 @@ "requirejs-plugins": "^1.0.3", "dragula.js": "3.7.2", "MathJax": "3.0.5", - "drawio": "jgraph/drawio#v20.8.18" + "drawio": "jgraph/drawio#v20.8.18", + "js-base64": "^3.7.5", + "pako": "^2.1.0" }, "resolutions": { "bootstrap": "^v4.0.0", diff --git a/www/drawio/empty.drawio b/www/drawio/empty.drawio deleted file mode 100644 index ab8fc14c5..000000000 --- a/www/drawio/empty.drawio +++ /dev/null @@ -1 +0,0 @@ -dZFNE4IgEIZ/DXeFvjyb1aWTh86MbMIMug7SaP36dICMsU4sz77vLrsQljfj2fBOXlGAJjQRI2FHQmmaZMl0zOTpyGGzdaA2SnjRAkr1guD09KEE9JHQImqruhhW2LZQ2YhxY3CIZXfUcdeO17ACZcX1mt6UsNJPQfcLv4CqZeic7jKXaXgQ+0l6yQUOX4gVhOUG0bqoGXPQ8/LCXpzv9Cf7eZiB1v4wTMFSe7pEP8SKNw== \ No newline at end of file diff --git a/www/drawio/inner.js b/www/drawio/inner.js index 5e9100aad..3f3ea2209 100644 --- a/www/drawio/inner.js +++ b/www/drawio/inner.js @@ -2,26 +2,36 @@ define([ '/common/sframe-app-framework.js', '/customize/messages.js', // translation keys - 'text!/drawio/empty.drawio', + '/bower_components/pako/dist/pako.min.js', + '/bower_components/js-base64/base64.js', 'less!/drawio/app.less', 'css!/drawio/drawio.css', ], function ( Framework, Messages, - emptyDrawioXml) { + pako, + base64) { + console.log('XXX base64', base64); // This is the main initialization loop var onFrameworkReady = function (framework) { const drawioFrame = document.querySelector('#cp-app-drawio-content'); - let lastContent = emptyDrawioXml; + let lastContent = ''; + let drawIoInitalized = false; const postMessageToDrawio = function(msg) { + if (!drawIoInitalized) { + return; + } + console.log('XXX postMessageToDrawio', msg); drawioFrame.contentWindow.postMessage(JSON.stringify(msg), '*'); }; const onDrawioInit = function(data) { + drawIoInitalized = true; + postMessageToDrawio({ action: 'load', xml: lastContent, @@ -30,6 +40,7 @@ define([ }; const onDrawioChange = function(newXml) { + newXml = decompressDrawioXml(newXml); if (lastContent != newXml) { lastContent = newXml; framework.localChange(); @@ -71,7 +82,18 @@ define([ // starting the CryptPad framework framework.start(); - drawioFrame.src = '/bower_components/drawio/src/main/webapp/index.html?pages=0&dev=1&stealth=1&embed=1&drafts=0&noSaveBtn=1&modified=unsavedChanges&proto=json'; + drawioFrame.src = '/bower_components/drawio/src/main/webapp/index.html?' + + new URLSearchParams({ + // pages: 0, + dev: 1, + test: 1, + stealth: 1, + embed: 1, + drafts: 0, + noSaveBtn: 1, + modified: 'unsavedChanges', + proto: 'json', + }); window.addEventListener("message", (event) => { if (event.source == drawioFrame.contentWindow) { @@ -86,6 +108,40 @@ define([ }, false); }; + // As described here: https://drawio-app.com/extracting-the-xml-from-mxfiles/ + let decompressDrawioXml = function(xmlDocStr) { + const TEXT_NODE = 3; + + const parser = new DOMParser(); + const doc = parser.parseFromString(xmlDocStr, "application/xml"); + + doc.firstChild.removeAttribute('modified'); + doc.firstChild.removeAttribute('agent'); + doc.firstChild.removeAttribute('etag'); + + const errorNode = doc.querySelector("parsererror"); + if (errorNode) { + console.error("error while parsing", errorNode); + return xmlStr; + } + + const diagrams = doc.querySelectorAll('diagram'); + + diagrams.forEach((diagram) => { + if (diagram.firstChild && diagram.firstChild.nodeType == TEXT_NODE) { + const innerText = diagram.firstChild.nodeValue; + const bin = base64.toUint8Array(innerText); + const xmlUrlStr = pako.inflateRaw(bin, {to: 'string'}); + const xmlStr = decodeURIComponent(xmlUrlStr); + const diagramDoc = parser.parseFromString(xmlStr, "application/xml"); + diagram.replaceChild(diagramDoc.firstChild, diagram.firstChild); + } + }); + + + return new XMLSerializer().serializeToString(doc); + } + // Framework initialization Framework.create({ toolbarContainer: '#cme_toolbox',