Skip to content

Commit

Permalink
Add support for editing diagrams.net diagrams
Browse files Browse the repository at this point in the history
Any SVG or PNG images that contain an editable diagrams.net document will
display an "edit" button on hover that opens the image in any embedded editor.
Saving the image will cause the file to be downloaded to the user's
browser, ready for use back in the docsy site.
  • Loading branch information
gwatts committed Nov 20, 2021
1 parent 43361e9 commit 87cbf9b
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 11 deletions.
106 changes: 106 additions & 0 deletions assets/js/drawio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{{with .Site.Params.drawio}}
{{if .enable }}
(function () {
var shade;
var iframe;

var insertFrame = function () {
shade = document.createElement('div');
shade.classList.add('drawioframe');
iframe = document.createElement('iframe');
shade.appendChild(iframe);
document.body.appendChild(shade);
}

var closeFrame = function () {
if (shade) {
document.body.removeChild(shade);
shade = undefined;
iframe = undefined;
}
}

var imghandler = function (img, imgdata) {
var url = {{ .drawio_server | default "https://embed.diagrams.net/" | jsonify }};
url += '?embed=1&ui=atlas&spin=1&modified=unsavedChanges&proto=json&saveAndEdit=1&noSaveBtn=1';

var wrapper = document.createElement('div');
wrapper.classList.add('drawio');
img.parentNode.insertBefore(wrapper, img);
wrapper.appendChild(img);

var btn = document.createElement('button');
btn.classList.add('drawiobtn');
btn.insertAdjacentHTML('beforeend', '<i class="fas fa-edit"></i>');
wrapper.appendChild(btn);

btn.addEventListener('click', function (evt) {
if (iframe) return;
insertFrame();
var handler = function (evt) {
var wind = iframe.contentWindow;
if (evt.data.length > 0 && evt.source == wind) {
var msg = JSON.parse(evt.data);

if (msg.event == 'init') {
wind.postMessage(JSON.stringify({action: 'load', xml: imgdata}), '*');

} else if (msg.event == 'save') {
var fmt = imgdata.indexOf('data:image/png') == 0 ? 'xmlpng' : 'xmlsvg';
wind.postMessage(JSON.stringify({action: 'export', format: fmt}), '*');

} else if (msg.event == 'export') {
const fn = img.src.replace(/^.*?([^/]+)$/, '$1');
const dl = document.createElement('a');
dl.setAttribute('href', msg.data);
dl.setAttribute('download', fn);
document.body.appendChild(dl);
dl.click();
dl.parentNode.removeChild(dl);
}

if (msg.event == 'exit' || msg.event == 'export') {
window.removeEventListener('message', handler);
closeFrame();
}
}
};

window.addEventListener('message', handler);
iframe.setAttribute('src', url);
});
};


document.addEventListener('DOMContentLoaded', function () {
// find all the png and svg images that may have embedded xml diagrams
for (const el of document.getElementsByTagName('img')) {
const img = el;
const src = img.getAttribute('src');
if (!src.endsWith('.svg') && !src.endsWith('.png')) {
continue;
}

const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.open("GET", src);
xhr.addEventListener("load", function () {
const fr = new FileReader();
fr.addEventListener('load', function () {
if (fr.result.indexOf('mxfile') != -1) {
const fr = new FileReader();
fr.addEventListener('load', function () {
const imgdata = fr.result;
imghandler(img, imgdata);
});
fr.readAsDataURL(xhr.response);
}
});
fr.readAsBinaryString(xhr.response);
});
xhr.send();
};
});
}());
{{end}}
{{end}}
40 changes: 40 additions & 0 deletions assets/scss/_drawio.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
div.drawio {
display: inline-block;
position: relative;

button {
position: absolute;
font-size: 0.8em;
bottom: 5px;
right: 5px;
background-color: rgba($secondary, .8);
color: $primary-light;
padding: 0.4em 0.5em;
display: none;
}

&:hover button {
display: inline;
}
}

div.drawioframe {
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0px;
z-index: 1000;
background: #000b;
border: 0;

iframe {
position: absolute;
height: 90%;
width: 90%;
top: 5%;
left: 5%;
z-index: 1010;
}
}

5 changes: 4 additions & 1 deletion assets/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
@import "section-index";
@import "pageinfo";
@import "taxonomy";
@import "drawio";

@if $td-enable-google-fonts {
@import url($web-font-path);
Expand Down Expand Up @@ -61,5 +62,7 @@ footer {
}
}



@import "rtl/main";
@import "styles_project";
@import "styles_project";
3 changes: 3 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ time_format_default = "January 2, 2006"
# Sections to publish in the main RSS feed.
rss_sections = ["blog"]

[params.drawio]
enable = true
#drawio_server = "https://example.com/"

# For a full list of parameters used in Docsy sites, see:
# https://github.com/google/docsy-example/blob/master/config.toml
Expand Down
30 changes: 21 additions & 9 deletions layouts/partials/scripts.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF"
crossorigin="anonymous"></script>

{{ if .Site.Params.mermaid.enable }}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/mermaid.min.js" integrity="sha384-m8Pdaep6Qk8sW3J6XhPOiwUww3maU9HxZTLvEfSEB4e1UVvTdHyfJsYmEfYqvwLC" crossorigin="anonymous"></script>
Expand Down Expand Up @@ -27,18 +31,25 @@
<script src='{{ "/js/deflate.js" | relURL }}'></script>
{{ end }}

<!-- load stylesheet and scripts for KaTeX support -->
<!-- load stylesheet and scripts for KaTeX support -->
{{ if .Site.Params.katex.enable }}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" integrity="sha384-Cqd8ihRLum0CCg8rz0hYKPoLZ3uw+gES2rXQXycqnL5pgVQIflxAUDS7ZSjITLb5" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
integrity="sha384-Cqd8ihRLum0CCg8rz0hYKPoLZ3uw+gES2rXQXycqnL5pgVQIflxAUDS7ZSjITLb5" crossorigin="anonymous">
<!-- The loading of KaTeX is deferred to speed up page rendering -->
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js" integrity="sha384-1Or6BdeNQb0ezrmtGeqQHFpppNd7a/gw29xeiSikBbsb44xu3uAo8c7FwbF5jhbd" crossorigin="anonymous"></script>
<!-- check whether support of mhchem is enabled in config.toml -->
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"
integrity="sha384-1Or6BdeNQb0ezrmtGeqQHFpppNd7a/gw29xeiSikBbsb44xu3uAo8c7FwbF5jhbd"
crossorigin="anonymous"></script>
<!-- check whether support of mhchem is enabled in config.toml -->
{{ if .Site.Params.katex.mhchem.enable }}
<!-- To add support for displaying chemical equations and physical units, load the mhchem extension: -->
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/mhchem.min.js" integrity="sha384-LIgAiYlGSAdpNC9+YDjDPF6JeS/RRIumtNo0CmyQERZ/+g0h9MbuYQwf/5pQ4Y4M" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/mhchem.min.js"
integrity="sha384-LIgAiYlGSAdpNC9+YDjDPF6JeS/RRIumtNo0CmyQERZ/+g0h9MbuYQwf/5pQ4Y4M"
crossorigin="anonymous"></script>
{{ end }}
<!-- To automatically render math in text elements, include the auto-render extension: -->
<script defer src='https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js' integrity='sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl' crossorigin='anonymous' {{ printf "onload='renderMathInElement(%s, %s);'" (( .Site.Params.katex.html_dom_element | default "document.body" ) | safeJS ) ( printf "%s" ( $.Site.Params.katex.options | jsonify )) | safeHTMLAttr }}></script>
<script defer src='https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js'
integrity='sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl' crossorigin='anonymous'
{{ printf "onload='renderMathInElement(%s, %s);'" (( .Site.Params.katex.html_dom_element | default "document.body" ) | safeJS ) ( printf "%s" ( $.Site.Params.katex.options | jsonify )) | safeHTMLAttr }}></script>
{{ end }}

{{ $jsBase := resources.Get "js/base.js" }}
Expand All @@ -47,10 +58,11 @@
{{ $jsMermaid := resources.Get "js/mermaid.js" | resources.ExecuteAsTemplate "js/mermaid.js" . }}
{{ $jsMarkmap := resources.Get "js/markmap.js" | resources.ExecuteAsTemplate "js/markmap.js" . }}
{{ $jsPlantuml := resources.Get "js/plantuml.js" | resources.ExecuteAsTemplate "js/plantuml.js" . }}
{{ $jsDrawio := resources.Get "js/drawio.js" | resources.ExecuteAsTemplate "js/plantuml.js" .}}
{{ if .Site.Params.offlineSearch }}
{{ $jsSearch = resources.Get "js/offline-search.js" }}
{{ end }}
{{ $js := (slice $jsBase $jsAnchor $jsSearch $jsMermaid $jsPlantuml $jsMarkmap) | resources.Concat "js/main.js" }}
{{ $js := (slice $jsBase $jsAnchor $jsSearch $jsMermaid $jsPlantuml $jsMarkmap $jsDrawio) | resources.Concat "js/main.js" }}
{{ if not hugo.IsProduction }}
<script src="{{ $js.RelPermalink }}"></script>
{{ else }}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 87cbf9b

Please sign in to comment.