Automattic / juice

Juice inlines CSS stylesheets into your HTML source.
MIT License
3.1k stars 220 forks source link

Tag attributes change case after juicing. #331

Open kevindecapite opened 5 years ago

kevindecapite commented 5 years ago

I'm trying to use juice to inline CSS into a dynamically generated SVG drawing. It works great, but is changing the case of the viewBox attribute to all lowercase: viewbox. Since SVGs are XML, the attributes are case-sensitive. Thus viewbox isn't recognized and the SVG does not render correctly.

Here's the example: https://runkit.com/embed/9wkrxfqmgkf1

If you open the source SVG code in a viewer, you should see a 100px circle that fills the viewBox completely.

Then look at the "Full Text" drop down option after juicing and you'll notice that there's now a lowercase b in that attribute. Copy and paste that SVG code into your viewer and the circle will be clipped.

Can we pass an option to preserve all tag and attribute casing?

jrit commented 5 years ago

I don't remember where that might be getting modified, but I suspect it is in a dependency. If you can track down where that needs to be changed, I'd fully support fixing this. I don't think the case should ever be getting changed, and don't even feel like an option is necessary, the behavior you propose should be the behavior.

kevindecapite commented 5 years ago

I was able to find some calls to toLowerCase() in the css-what dependency:

I agree an option for this doesn't make much sense. I was mostly checking to make sure I didn't miss anything.

FYI, for anyone else dealing with this issue: I resolved it for the time being with .replace(/viewbox/g, 'viewBox') on juice's return string.

kevindecapite commented 5 years ago

Juice's dependency graph, in case that's needed:

├─┬ juice@5.2.0
│ ├─┬ cheerio@0.22.0
│ │ ├─┬ css-select@1.2.0
│ │ │ ├── boolbase@1.0.0
│ │ │ ├── css-what@2.1.3
│ │ │ ├─┬ domutils@1.5.1
│ │ │ │ ├── dom-serializer@0.1.1 deduped
│ │ │ │ └── domelementtype@1.3.1 deduped
│ │ │ └─┬ nth-check@1.0.2
│ │ │   └── boolbase@1.0.0 deduped
│ │ ├─┬ dom-serializer@0.1.1
│ │ │ ├── domelementtype@1.3.1
│ │ │ └── entities@1.1.2 deduped
│ │ ├── entities@1.1.2
│ │ ├─┬ htmlparser2@3.10.1
│ │ │ ├── domelementtype@1.3.1 deduped
│ │ │ ├─┬ domhandler@2.4.2
│ │ │ │ └── domelementtype@1.3.1 deduped
│ │ │ ├── domutils@1.5.1 deduped
│ │ │ ├── entities@1.1.2 deduped
│ │ │ ├── inherits@2.0.3 deduped
│ │ │ └─┬ readable-stream@3.2.0
│ │ │   ├── inherits@2.0.3 deduped
│ │ │   ├── string_decoder@1.1.1 deduped
│ │ │   └── util-deprecate@1.0.2 deduped
sermunar commented 4 years ago

I was facing the same issue, since I have some attribute manipulations after juice is getting called. I found a solution for this problem based on this issue post for cheeriojs.

So just try to enable the xmlMode in your options.

const juicedSvg = juice(svg, { xmlMode:true });