Improved CSS cloning
Better separation of styles between multiple mermaid SVGs on the same page Added support for text label styling
This commit is contained in:
parent
3fe38237e6
commit
84124c9427
45
src/utils.js
45
src/utils.js
|
@ -59,17 +59,17 @@ module.exports.cloneCssStyles = function(svg, classes){
|
||||||
if (classes.hasOwnProperty(className) && typeof(className) != "undefined") {
|
if (classes.hasOwnProperty(className) && typeof(className) != "undefined") {
|
||||||
if (className === 'default') {
|
if (className === 'default') {
|
||||||
if (classes.default.styles instanceof Array) {
|
if (classes.default.styles instanceof Array) {
|
||||||
defaultStyles += '.node' + ' { ' + classes[className].styles.join("; ") + '; }\n';
|
defaultStyles += "#" + svg.id.trim() + ' .node' + ' { ' + classes[className].styles.join("; ") + '; }\n';
|
||||||
}
|
}
|
||||||
if (classes.default.nodeLabelStyles instanceof Array) {
|
if (classes.default.nodeLabelStyles instanceof Array) {
|
||||||
defaultStyles += '.node text ' + ' { ' + classes[className].nodeLabelStyles.join("; ") + '; }\n';
|
defaultStyles += "#" + svg.id.trim() + ' .node text ' + ' { ' + classes[className].nodeLabelStyles.join("; ") + '; }\n';
|
||||||
}
|
}
|
||||||
if (classes.default.edgeLabelStyles instanceof Array) {
|
if (classes.default.edgeLabelStyles instanceof Array) {
|
||||||
defaultStyles += '.edgeLabel text ' + ' { ' + classes[className].edgeLabelStyles.join("; ") + '; }\n';
|
defaultStyles += "#" + svg.id.trim() + ' .edgeLabel text ' + ' { ' + classes[className].edgeLabelStyles.join("; ") + '; }\n';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (classes[className].styles instanceof Array) {
|
if (classes[className].styles instanceof Array) {
|
||||||
embeddedStyles += '.' + className + ' { ' + classes[className].styles.join("; ") + '; }\n';
|
embeddedStyles += "#" + svg.id.trim() + ' .' + className + ' { ' + classes[className].styles.join("; ") + '; }\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,6 @@ module.exports.cloneCssStyles = function(svg, classes){
|
||||||
s.setAttribute('title', 'mermaid-svg-internal-css');
|
s.setAttribute('title', 'mermaid-svg-internal-css');
|
||||||
s.innerHTML = "/* <![CDATA[ */\n";
|
s.innerHTML = "/* <![CDATA[ */\n";
|
||||||
// Make this CSS local to this SVG
|
// Make this CSS local to this SVG
|
||||||
s.innerHTML += "#" + svg.id.trim() + " {\n";
|
|
||||||
if (defaultStyles !== "") {
|
if (defaultStyles !== "") {
|
||||||
s.innerHTML += defaultStyles;
|
s.innerHTML += defaultStyles;
|
||||||
}
|
}
|
||||||
|
@ -91,43 +90,7 @@ module.exports.cloneCssStyles = function(svg, classes){
|
||||||
if (embeddedStyles !== "") {
|
if (embeddedStyles !== "") {
|
||||||
s.innerHTML += embeddedStyles;
|
s.innerHTML += embeddedStyles;
|
||||||
}
|
}
|
||||||
s.innerHTML += "}\n";
|
|
||||||
s.innerHTML += "/* ]]> */\n";
|
s.innerHTML += "/* ]]> */\n";
|
||||||
svg.insertBefore(s, svg.firstChild);
|
svg.insertBefore(s, svg.firstChild);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var equals = function (val, variable){
|
|
||||||
if(typeof variable === 'undefined'){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return (val === variable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var mermaid_config_exists = function() {
|
|
||||||
return (typeof mermaid_config !== 'undefined');
|
|
||||||
};
|
|
||||||
|
|
||||||
var mermaid_config_item_exists = function(item) {
|
|
||||||
return mermaid_config_exists() && (typeof mermaid_config[item] !== 'undefined');
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.config = {};
|
|
||||||
|
|
||||||
module.exports.config.startOnLoad = function() {
|
|
||||||
if (mermaid_config_item_exists(startOnLoad)) {
|
|
||||||
return mermaid_config.startOnLoad === true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.config.labelStyle = function() {
|
|
||||||
if (mermaid_config_item_exists(labelStyle)) {
|
|
||||||
return mermaid_config.labelStyle === 'html';
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -84,26 +84,23 @@ describe('when cloning CSS ',function() {
|
||||||
return styleArrTrim;
|
return styleArrTrim;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStyleToDocument(title) {
|
function addStyleToDocument() {
|
||||||
var styleSheetCount = document.styleSheets.length;
|
var styleSheetCount = document.styleSheets.length;
|
||||||
var s = document.createElement('style');
|
var s = document.createElement('style');
|
||||||
s.setAttribute('title', title);
|
|
||||||
s.innerHTML = '.node { stroke:#eee; }\n.node-square { stroke:#bbb; }\n';
|
s.innerHTML = '.node { stroke:#eee; }\n.node-square { stroke:#bbb; }\n';
|
||||||
document.body.appendChild(s);
|
document.body.appendChild(s);
|
||||||
document.styleSheets[styleSheetCount].title = title;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSecondStyleToDocument(title) {
|
function addSecondStyleToDocument() {
|
||||||
var styleSheetCount = document.styleSheets.length;
|
var styleSheetCount = document.styleSheets.length;
|
||||||
var s = document.createElement('style');
|
var s = document.createElement('style');
|
||||||
s.setAttribute('title', title);
|
|
||||||
s.innerHTML = '.node2 { stroke:#eee; }\n.node-square { stroke:#beb; }\n';
|
s.innerHTML = '.node2 { stroke:#eee; }\n.node-square { stroke:#beb; }\n';
|
||||||
document.body.appendChild(s);
|
document.body.appendChild(s);
|
||||||
document.styleSheets[styleSheetCount].title = title;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateSVG() {
|
function generateSVG() {
|
||||||
var svg = document.createElement('svg');
|
var svg = document.createElement('svg');
|
||||||
|
svg.setAttribute('id', 'mermaid-01');
|
||||||
var g1 = document.createElement('g');
|
var g1 = document.createElement('g');
|
||||||
g1.setAttribute('class', 'node');
|
g1.setAttribute('class', 'node');
|
||||||
svg.appendChild(g1);
|
svg.appendChild(g1);
|
||||||
|
@ -113,30 +110,22 @@ describe('when cloning CSS ',function() {
|
||||||
return svg;
|
return svg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSVGwithStyleToDocument() {
|
|
||||||
var svg = document.createElement('svg');
|
|
||||||
var s = document.createElement('style');
|
|
||||||
s.innerHTML = '.node2 { stroke:#eee; }\n.node-square { stroke:#bfb; }\n';
|
|
||||||
svg.appendChild(s);
|
|
||||||
document.body.appendChild(svg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addMermaidSVGwithStyleToDocument() {
|
function addMermaidSVGwithStyleToDocument() {
|
||||||
var styleSheetCount = document.styleSheets.length;
|
var styleSheetCount = document.styleSheets.length;
|
||||||
var svg = document.createElement('svg');
|
var svg = document.createElement('svg');
|
||||||
|
svg.setAttribute('id', 'mermaid-03');
|
||||||
var s = document.createElement('style');
|
var s = document.createElement('style');
|
||||||
s.setAttribute('type', 'text/css');
|
s.setAttribute('type', 'text/css');
|
||||||
s.setAttribute('title', 'mermaid-svg-internal-css');
|
s.setAttribute('title', 'mermaid-svg-internal-css');
|
||||||
s.innerHTML = '.node2 { stroke:#eee; }\n.node-square { stroke:#bfe; }\n';
|
s.innerHTML = '#mermaid-05 .node2 { stroke:#eee; }\n.node-square { stroke:#bfe; }\n';
|
||||||
svg.appendChild(s);
|
svg.appendChild(s);
|
||||||
document.body.appendChild(svg);
|
document.body.appendChild(svg);
|
||||||
// The Mock-browser seems not to support stylesheets title attribute, so we add it manually
|
document.styleSheets[styleSheetCount].title = 'mermaid-svg-internal-css';
|
||||||
var sheets = document.styleSheets;
|
|
||||||
sheets[styleSheetCount].title = "mermaid-svg-internal-css";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should handle an empty set of classes', function () {
|
it('should handle an empty set of classes', function () {
|
||||||
var svg = document.createElement('svg');
|
var svg = document.createElement('svg');
|
||||||
|
svg.setAttribute('id', 'mermaid-01');
|
||||||
|
|
||||||
utils.cloneCssStyles(svg, {});
|
utils.cloneCssStyles(svg, {});
|
||||||
// Should not create style element if not needed
|
// Should not create style element if not needed
|
||||||
|
@ -145,57 +134,43 @@ describe('when cloning CSS ',function() {
|
||||||
|
|
||||||
it('should handle a default class', function () {
|
it('should handle a default class', function () {
|
||||||
var svg = document.createElement('svg');
|
var svg = document.createElement('svg');
|
||||||
|
svg.setAttribute('id', 'mermaid-01');
|
||||||
|
|
||||||
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] } });
|
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] } });
|
||||||
expect(stylesToArray(svg)).toEqual([ '.node { stroke:#fff; stroke-width:1.5px; }']);
|
expect(stylesToArray(svg)).toEqual([ '#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }' ]);
|
||||||
// Also verify the elements around the styling
|
// Also verify the elements around the styling
|
||||||
expect(svg.innerHTML).toBe('<style type="text/css" title="mermaid-svg-internal-css">/* <![CDATA[ */\n.node { stroke:#fff; stroke-width:1.5px; }\n/* ]]> */\n</style>');
|
expect(svg.innerHTML).toBe('<style type="text/css" title="mermaid-svg-internal-css">/* <![CDATA[ */\n#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }\n/* ]]> */\n</style>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle stylesheet in document with no classes in SVG', function () {
|
it('should handle stylesheet in document with no classes in SVG', function () {
|
||||||
var svg = document.createElement('svg');
|
var svg = document.createElement('svg');
|
||||||
|
svg.setAttribute('id', 'mermaid-01');
|
||||||
|
|
||||||
addStyleToDocument('mermaid');
|
addStyleToDocument('mermaid');
|
||||||
utils.cloneCssStyles(svg, {});
|
utils.cloneCssStyles(svg, {});
|
||||||
// Should not create style element if not needed
|
// Should not create style element if not needed
|
||||||
expect(svg.innerHTML).toBe('');
|
expect(svg.innerHTML).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore non-mermaid stylesheet in document with classes in SVG', function () {
|
|
||||||
var svg = generateSVG();
|
|
||||||
addStyleToDocument('non-mermaid');
|
|
||||||
utils.cloneCssStyles(svg, {});
|
|
||||||
expect(svg.innerHTML).toBe('<g class="node"></g><g class="node-square"></g>');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle stylesheet in document with classes in SVG', function () {
|
it('should handle stylesheet in document with classes in SVG', function () {
|
||||||
var svg = generateSVG();
|
var svg = generateSVG();
|
||||||
addStyleToDocument('mermaid');
|
addStyleToDocument();
|
||||||
utils.cloneCssStyles(svg, {});
|
utils.cloneCssStyles(svg, {});
|
||||||
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }']);
|
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle multiple stylesheets in document with classes in SVG', function () {
|
it('should handle multiple stylesheets in document with classes in SVG', function () {
|
||||||
var svg = generateSVG();
|
var svg = generateSVG();
|
||||||
addStyleToDocument('mermaid');
|
addStyleToDocument();
|
||||||
addSecondStyleToDocument('mermaid');
|
addSecondStyleToDocument();
|
||||||
utils.cloneCssStyles(svg, {});
|
utils.cloneCssStyles(svg, {});
|
||||||
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }']);
|
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle multiple stylesheets + ignore styles in other SVG', function () {
|
it('should handle multiple stylesheets + ignore styles in other mermaid SVG', function () {
|
||||||
var svg = generateSVG();
|
var svg = generateSVG();
|
||||||
addStyleToDocument('mermaid');
|
addStyleToDocument();
|
||||||
addSecondStyleToDocument('mermaid');
|
addSecondStyleToDocument();
|
||||||
addSVGwithStyleToDocument();
|
|
||||||
utils.cloneCssStyles(svg, {});
|
|
||||||
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle multiple stylesheets + ignore styles in mermaid SVG', function () {
|
|
||||||
var svg = generateSVG();
|
|
||||||
addStyleToDocument('mermaid');
|
|
||||||
addSecondStyleToDocument('mermaid');
|
|
||||||
addSVGwithStyleToDocument();
|
|
||||||
addMermaidSVGwithStyleToDocument();
|
addMermaidSVGwithStyleToDocument();
|
||||||
utils.cloneCssStyles(svg, {});
|
utils.cloneCssStyles(svg, {});
|
||||||
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }']);
|
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }']);
|
||||||
|
@ -203,22 +178,23 @@ describe('when cloning CSS ',function() {
|
||||||
|
|
||||||
it('should handle a default class together with stylesheet in document with classes in SVG', function () {
|
it('should handle a default class together with stylesheet in document with classes in SVG', function () {
|
||||||
var svg = generateSVG();
|
var svg = generateSVG();
|
||||||
addStyleToDocument('mermaid');
|
addStyleToDocument();
|
||||||
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] } });
|
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] } });
|
||||||
expect(stylesToArray(svg)).toEqual([ '.node { stroke:#fff; stroke-width:1.5px; }', '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }']);
|
expect(stylesToArray(svg)).toEqual([ '#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }', '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }']);
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('should handle a default class together with stylesheet in document and classDefs', function () {
|
it('should handle a default class together with stylesheet in document and classDefs', function () {
|
||||||
var svg = generateSVG();
|
var svg = generateSVG();
|
||||||
addStyleToDocument('mermaid');
|
addStyleToDocument();
|
||||||
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] },
|
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] },
|
||||||
"node-square": { "styles": ["fill:#eee", "stroke:#aaa"] },
|
"node-square": { "styles": ["fill:#eee", "stroke:#aaa"] },
|
||||||
"node-circle": { "styles": ["fill:#444", "stroke:#111"] } });
|
"node-circle": { "styles": ["fill:#444", "stroke:#111"] } });
|
||||||
expect(stylesToArray(svg)).toEqual([ '.node { stroke:#fff; stroke-width:1.5px; }',
|
expect(stylesToArray(svg)).toEqual([ '#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }',
|
||||||
'.node { stroke: #eee; }',
|
'.node { stroke: #eee; }',
|
||||||
'.node-square { stroke: #bbb; }',
|
'.node-square { stroke: #bbb; }',
|
||||||
'.node-square { fill:#eee; stroke:#aaa; }',
|
'#mermaid-01 .node-square { fill:#eee; stroke:#aaa; }',
|
||||||
'.node-circle { fill:#444; stroke:#111; }' ]);
|
'#mermaid-01 .node-circle { fill:#444; stroke:#111; }'
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue