posthtml / htmlnano

Modular HTML minifier, built on top of the PostHTML

Home Page:https://htmlnano.netlify.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CDATA in SVG script causing trouble

cyqsimon opened this issue · comments

The version of svgo used by htmlnano has issues with parsing script tags.
When using both minifyJS, and minifySvg, there's an issue with parsing script tags inside svg tags.
Specifically, CDATA declaration is removed when it is necessary:

<script>//<![CDATA[  //]]></script>

is parsed into:

<script></script>

This causes SVGs like this to fail validation:

<svg xmlns='http://www.w3.org/2000/svg'>
  <script>//<![CDATA[
    const x = '<>';
  //]]></script>
</svg>

with the error:

Trace: Error in parsing SVG: Unencoded <

This is not an issue of svgo:

svgo -s "<svg xmlns='http://www.w3.org/2000/svg'><script>//<![CDATA[const x='<>';//]]></script></svg>"

returns:

<svg xmlns="http://www.w3.org/2000/svg"><script>//<![CDATA[const x='<>';//]]></script></svg>

It is also possible that htmlnano removed CDATA before invoking svgo. However I cannot be certain of this without reading your code.

Update: I think I found the issue. It actually has nothing to do with svgo.
minifyJs is invoked before minifySvg, but minifyJS seems to look inside svg tags for script tags as well. So it is actually minifyJs that's removing CDATA, thereby causing minifySvg to throw.

A potential solution is to exclude svg tags from the application scope of minifyJs module, if that's possible.

Thanks for the detailed info! I'll look into it in the following days.

For now, I've found no better solution than check for //<![CDATA[ //]] and then add it manually after the JS minification.

@Scrum if I have a node (e.g., <script>) is it possible to detect if one of its ancestors is <svg>?

@maltsev Hi, from the options I can suggest making a match for the svg element and in this match make a match on script

let me know if it's not very clear, I'll sketch an example

It might be a good idea to check for namespace switching instead of hard-coding for svg only.

I'm thinking of the possibility of some other element using a strict XML syntax for its internal DOM just like SVG, although I cannot come up with a concrete example at the moment.