in src/visual/Paper.js [117:192]
getSVG() {
const paper = this;
const svgClone = this._createCloneNode();
svgClone.removeAttribute('style');
// The code below was inspired by the old jointjs version of format plugin.
// It copies the necessary styles from paper to our svg file.
// Unfortunately, it does its job in a sophisticated way:
// 1. Disables all paper's stylesheets to obtain default values.
// 2. Enable them back and retrieve only differences in styles.
// 3. Applies styles to SVG elements.
const styleSheetsCount = document.styleSheets.length;
const styleSheetsCopy = [];
// 1.
for (let i = styleSheetsCount - 1; i >= 0; --i) {
// Disabled styles could accidentally be removed from paper.
// Therefore, backup them.
styleSheetsCopy[i] = document.styleSheets[i];
document.styleSheets[i].disabled = true;
}
const defaultComputedStyles = [];
_.forEach(paper.svg.getElementsByTagName('*'), (elem, idx) => {
const computedStyle = window.getComputedStyle(elem, null);
defaultComputedStyles[idx] = _.cloneDeep(computedStyle);
});
if (styleSheetsCount !== document.styleSheets.length) {
_.forEach(styleSheetsCopy, (copy, i) => {
document.styleSheets[i] = copy;
});
}
// 2.
for (let i = 0; i < styleSheetsCount; i++) {
document.styleSheets[i].disabled = false;
}
const customStyles = {};
_.forEach(paper.svg.getElementsByTagName('*'), (elem, idx) => {
const computedStyle = window.getComputedStyle(elem, null);
const defaultComputedStyle = defaultComputedStyles[idx];
const customStyle = {};
_.forEach(computedStyle, (property) => {
// Store only those that differ from the default styles applied by the browser.
if (property !== 'width' && property !== 'height' &&
computedStyle[property] !== defaultComputedStyle[property]) {
customStyle[property] = computedStyle[property];
}
});
customStyles[idx] = customStyle;
});
// 3.
_.forEach(svgClone.getElementsByTagName('*'), (elem, idx) => {
_.assign(elem.style, customStyles[idx]);
});
// Remove redundant 'onhover' elements
_.forEach(
svgClone.querySelectorAll('.connection-wrap,.marker-vertices,.link-tools,.marker-arrowheads'),
(elem) => { elem.parentNode.removeChild(elem); });
let svgString = '';
try {
const serializer = new XMLSerializer();
svgString = serializer.serializeToString(svgClone);
} catch (err) {
return svgString;
}
return svgString;
}