What I’m trying to do:
- Save/copy HTML snippet in one place, paste it in another place and have it de-serealized into an analogous DOM
How do I do serialization now
- Call
element.outerHTML
on a container element- I’ve also tried using
new XMLSerializer().serializeToString(element)
with the same result
- I’ve also tried using
The issue
When I serialize style
nodes that contain the css like:
.a > .b { color: red }
They actually get serialized like
.a > .b { color: red }
Which is not a valid CSS and so does not get parsed properly.
The problem with greater sign is the only one I observe, but it makes me wonder about other potential serialization issues.
Question: How do I get serialize the style nodes in a way that does not break CSS in them?
Advertisement
Answer
So it seems that this has to do with creating the style node dynamically on a new document.
The easiest reproduction is as follows:
const doc = new Document() const style = doc.createElement('style') style.textContent = '.a>.b { color: red; }' console.log(style.outerHTML)
Which yields <style>.a>.b {color:red}</style>
It seems that being part of actively rendered document/or just generally being added to a document and not just created using it has some side-effect on the style node, which causes it to be serialized properly though. So now I do the following instead as a workaround, which is a bit ugly but works:
const doc = new DOMParser().parseFromString('<html><head></head><body></body></html>', 'text/html') const style = doc.createElement('style') style.textContent = '.a>.b { color: red; }' doc.body.append(style) console.log(style.outerHTML) doc.body.removeChild(style)
Which produces an appropriately serialized <style>.a>.b { color: red; }</style>
Now this solves my problem, but I’d still really like to understand what is happening here in more detail (e.g. what is the side-effect exactly and how/when is it triggered), so would appreciate comments on that!