A method to extends DRAWIO
A simple method to extends DrawIO based on Placeholder and WebComponent.
Placeholder
Check out this article: placeholders
- Draw a simple rectangle with label
Hello %name%!
- Edit the rectangle’s data (right click on the rectangle)
- Add a property with name
name
and value<name-comp>world</name-comp>
- A Webcomponent
<name-comp>
will be rendered, and the default value isworld
- A Webcomponent
- Check the placeholder’s value
- Apply it to rectangle
Render
We can get the source-code of drawio file by cat
command:
> cat a.drawio
<mxfile host="65bd71144e">
<diagram id="wvjVHeBDJ11HY7uDms1G" name="Page-1">
<mxGraphModel dx="957" dy="646" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<object label="Hello %name%!" name="<name-comp>world</name-comp>" placeholders="1" id="2">
<mxCell style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="120" width="120" height="60" as="geometry"/>
</mxCell>
</object>
</root>
</mxGraphModel>
</diagram>
</mxfile>%
And render it by viewer.js
from jgraph/drawio
and enable Custom Element’s render
var graph = new Graph(document.getElementById('root'));
graph.setEnabled(false);
graph.setTooltips(false)
graph.isHtmlLabel = function (cell) {
return true;
};
graph.isTableCell = function (cell) {
console.log('istablecell');
return true;
};
function loadXml(graph, xml) {
graph.getModel().beginUpdate();
try {
var root = mxUtils.parseXml(xml);
var dec = new mxCodec(root);
dec.decode(root.documentElement, graph.getModel());
} finally {
graph.getModel().endUpdate();
}
}
window.DOM_PURIFY_CONFIG = {
// Original Config
"ADD_TAGS": ["use"],
"FORBID_TAGS": ["form"],
"ALLOWED_URI_REGEXP": /^((?!javascript:).)*$/i,
"ADD_ATTR": ["target", "content"],
"IN_PLACE": false,
// new custom element
// https://github.com/cure53/DOMPurify
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: () => true,
attributeNameCheck: () => true,
allowCustomizedBuiltInElements: true,
},
}
// drawiofile is refer to a.drawio
const xml = drawioFile.match(/<mxGraphModel[\s\S]*<\/mxGraphModel>/);
loadXml(graph, xml[0]);
WebComponent
Create a WebComponent like this:
class NameComp extends HTMLElement {
connectedCallback() {
const names = ['Alice', 'Bob', 'World'];
let i = 0;
setInterval(() => {
this.innerHTML = names[i++%3];
}, 1000)
}
}
customElements.define('name-comp', NameComp)
Online Demo
Finnally, we can get a online demo:
We extends the drawio by a WebComponent, and see the page will be updated every second.