Open SethFalco opened 4 months ago
I've written a version of the proposed splitStyles
method that doesn't use a CSS parser. This should work, or at least will be better than what we have now. Happy to open a PR, but hoping to get clarity on if you'd prefer to take the CSS parser or DIY route first.
"
or "
);
and ;
) the same as the semicolon character (;
)./**
* Split raw styles into separate properties.
*/
const splitStyles = (rawStyle: string) => {
const entries = []
let currentEntry = ''
for (const char of rawStyle) {
if (char !== ';' || /&(?:[a-zA-Z]+|#\d+)(?<!&semi|;)$/.test(currentEntry)) {
currentEntry += char
continue
}
entries.push(currentEntry)
currentEntry = ''
}
if (currentEntry.length !== 0) {
entries.push(currentEntry)
}
return entries
}
Usage would be to change:
- const entries = rawStyle.split(';')
+ const entries = splitStyles(rawStyle)
🐛 Bug Report
The
@svgr/hast-util-to-babel-ast
package doesn't split styles correctly, and so breaks some SVGs that are processed through it.It doesn't account for XML entities such as
"
or<
, which both contain a semicolon which is acceptable when styles are defined in HTML, and the semicolon should not be considered a delimiter.To Reproduce
I've written a test case for
hast-util-to-babel-ast
:packages/hast-util-to-babel-ast/src/index.test.ts
Or alternatively, a test case for
core
:packages/core/src/transform.test.ts
This currently creates the following snapshot, which is wrong but demonstrates the issue:
When SVGO serializing the
font-family
property back to a string, it uses XML entities to escape the quotes, so:SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace
becomesSFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace
Then
plugin-jsx
erroneously splits thestyle
attribute by;
, which splits the style in the middle of property values as XML entities contain a semicolon too.Expected behavior
Semicolons that are part of an XML entity should be treated as a delimiter/separator for style properties.
The best solution would probably be to use an actual CSS parser. If that's not favorable for whatever reason, then there should be a
splitStyles
method defined inpackages/hast-util-to-babel-ast/src/stringToObjectStyle.ts
which goes character by character through the raw styles to avoid XML entities.I'd be happy to look at this for you if you can confirm if you'd prefer to use a CSS parser, or a DIY solution?
Run
npx envinfo --system --binaries --npmPackages @svgr/core,@svgr/cli,@svgr/webpack,@svgr/rollup --markdown --clipboard