I have svg image, that has some classes(jointJS paper). I'm saving this svg, and then converting it to png file on backend. Problem is - classes on my backend can't be recognized, so i would like to replace class names with styles that assigned to these classes, for ex.
<g id=\"j_42\" model-id=\"7c170ce6-09a5-49e9-b470-c1bb1980bd02\" class=\"link joint-theme-default\"><path class=\"connection\" stroke=\"#222\" d=\"M 803 387 C 881 387 881 196 959 196\" id=\"v-522\" stroke-width=\"3\"/>
<g id=\"j_42\" model-id=\"7c170ce6-09a5-49e9-b470-c1bb1980bd02\" style="some_styles_that_stands_for joint-theme-default class"><path class=\"connection\" stroke=\"#222\" d=\"M 803 387 C 881 387 881 196 959 196\" id=\"v-522\" stroke-width=\"3\"/
you can use document.styleSheets
to read all stylesheets, find all the class rules you want and replace the class attribute of the Elemets with the style definition from the stylesheet.
what i do here is basicly get:
with this you end with rect elements which have their class names replaced by inline styles...
P.S:: i know i make a lot of assumptions here. To make this work for you, or work in a general case, there still is a lot of work to do...
classMap = {}
var rules = document.styleSheets[0].cssRules // 1. get first stylesheet
for (var j = 0; j < rules.length; j++) { // 2. loop over all rules
var selector = rules[j].selectorText
var csstext = rules[j].cssText
classMap[selector.replace(".", "")] = csstext.split("{")[1].replace("}", "") // 3. save class name and rule text to mapper object
}
document.querySelectorAll("rect").forEach(function(item, index) { // 4. loop over all rects
var style = ""
item.classList.forEach(function(className) { // 5. loop over all class names
style += classMap[className] // 6. + 7. get style rules form mapper and concat
})
item.removeAttribute("class") // 8. remove class
item.setAttribute("style", style) // 9. add inline style
document.write("<br/>" + item.id + ": " + style)
})
.cl1 {
fill: green
}
.cl2 {
fill: red
}
.st1 {
stroke: blue;
stroke-width: 10
}
.st2 {
stroke: orange;
stroke-width: 5
}
<svg>
<rect id="rect1" x="10" y="10" width="100" height="100" class="cl1 st1" />
<rect id="rect2" y="10" x="150" width="100" height="100" class="cl2 st2" />
</svg>
another approach would be to use getComputedStyle
to get the style definition. this is more easy, and works for the general case, but will bloat your document quite fast...
to prevent that (and prevent you from running into some chrome bug...) you can maintain a list of all style properties you are interested in, and get the current values only for these properties from getComputedStyle
var props = ["fill", "stroke", "stroke-width"]
document.querySelectorAll("rect").forEach(function(item, index) {
var cstyle = getComputedStyle(item)
props.forEach(function(prop) {
item.setAttribute(prop, cstyle[prop])
})
item.removeAttribute("class")
var X = new XMLSerializer()
var txt = document.createTextNode(X.serializeToString(item))
document.write("<br/><br/>")
document.body.appendChild(txt)
})
.cl1 {
fill: green
}
.cl2 {
fill: red
}
.st1 {
stroke: blue;
stroke-width: 10
}
.st2 {
stroke: orange;
stroke-width: 5
}
<svg>
<rect id="rect1" x="10" y="10" width="100" height="100" class="cl1 st1" />
<rect id="rect2" y="10" x="150" width="100" height="100" class="cl2 st2" />
</svg>