imgurify icon indicating copy to clipboard operation
imgurify copied to clipboard

Firefox SVG support.

Open oros opened this issue 9 years ago • 10 comments

Firefox appears to have issues with the standard svg+xml, non-encoded data combination. I've found the following to work across Chrome and Firefox (IE works, but has other issues when attempting to render any SVG data to a canvas it seems.)

Based on the discussion here: https://css-tricks.com/probably-dont-base64-svg/#comment-1586152

I've had better luck dropping the encoding altogether:

var svgHead    = function(i,type) { return i == 0 ? "module.exports = 'data:image/svg+xml," : '' }

And leveraging encodeURIComponent instead of esc.

function svgStream(file, type) {
    var i = -1
    return through(
        function (buf, enc, next) { i++; this.push(svgHead(i,type)); this.push(encodeURIComponent(buf.toString('utf-8'))); next() },
        function (end) { this.push(svgTail()); end() }
    )
}

oros avatar Mar 17 '16 20:03 oros

Interesting... Looking at the spec:

The appearance of ";base64" means that the data is encoded as base64. Without 
";base64", the data (as a sequence of octets) is represented using ASCII encoding 
for octets inside the range of safe URL characters and using the standard %xx hex 
encoding of URLs for octets outside that range.

I think this ASCII encoding inside the range of safe URL characters might be exactly what you get when you do encodeURIComponent(buf.toString('utf-8')) ... ? It also seems using ;utf-8, in this regards (as I do now) is incorrect and should be data:image/svg+xml;charset=utf-8,.

I'll make some the modification in a branch and ref. this issue. Would be a great help if you could give that a try :smile: Thanks for reporting this! :+1:

asbjornenge avatar Mar 18 '16 08:03 asbjornenge

Hmmm... I wonder if encodeURIComponent makes sense only if I don't pass the charset...? I'll make a quick browsertest to make it easier to check out in browsers...

asbjornenge avatar Mar 18 '16 08:03 asbjornenge

@oros alright, so... totally forgot to branch off :stuck_out_tongue_closed_eyes: but in latest master I've removed the encoding and set the charset=utf8 correctly for the svg. Could you give it a whirl?

I've also added a testapp. npm run testapp to start it.

All images render fine for me on both chrome and firefox.

asbjornenge avatar Mar 18 '16 13:03 asbjornenge

Giving it a go.

oros avatar Mar 18 '16 16:03 oros

While running testapp, the SVG image is showing in Chrome/Firefox, however the raster images are not. The PNG output is as follows.

data:image/png;base64,77+9UE5HDQoaCgAAAA1JSERSAAAAAgAAAAIIAgAAAO+/vdSacwAAAAFzUkdCAO+/ve+/vRzvv70AAAAEZ0FNQQAA77+977+9C++/vWEFAAAACXBIWXMAAA7vv70AAA7vv70B77+9b++/vWQAAAAVSURBVBhXY3hnZO+/vVZO77+9Ae+/ve+/vdu5AgAm77+9BS9D77+977+977+9AAAAAElFTkTvv71CYO+/vQ==

EDIT: I see that compared to your orginal build.js file, your original has the correct base64 encoding, I'm not sure why mine is giving different output for raster images.

I'm leveraging imgurify in a gulp build process and with the default code, I also get a build error, specifically that there are unterminated strings.

module.exports = 'data:image/svg+xml;charset=utf8,<svg width="304.8" height="76.2" xmlns="http://www.w3.org/2000/svg">
                 ^
ParseError: Unterminated string constant

I'm not actually sure why this is the case, it's as if it's trying to prematurely evaluate it, but I had to revert to my original approach to get around this. Specifically:

  • Drop the charset altogether from svgHead; and
  • Leverage encodeURIComponent(buf.toString('utf-8')) in svgStream

It's a bit of an edge case/usage of the result, but figured I'd share.

I plan to work around the raster image by using fs.readFileSync, but I'm not sure of any drawbacks there, or even really why the output is differing from yours.

oros avatar Mar 18 '16 17:03 oros

@oros that's so weird! I was originally using budo to run the testapp, and I got that exact same broken output for the raster images. Eventually tried without budo and it worked, so I figured budo was doing something weird. Hmm... What version of browserify are you using?

asbjornenge avatar Mar 18 '16 20:03 asbjornenge

Sorry for the delay in responding, Github doesn't seem to be notifying me when I get mentioned.

Browserify looks to be version 13.0.0.

I tried it again today with a fresh clone of your repo and am getting same behaviour.

If this is all for my sake, I wouldn't spend too much time investigating as I've have made my own fork and customized it to work in my environment, it's just mighty odd that it came to it in the first place as your original implementation, by all accounts, seems like it should be working.

oros avatar Mar 29 '16 20:03 oros

@oros Yeah, it's a weird one :stuck_out_tongue: Anyway, I'll just leave this issue open until I have time to figure it out, or in case someone else comes along with similar problems. :+1:

asbjornenge avatar Mar 30 '16 07:03 asbjornenge

Well we can atleast make a note that the raster issue is related to #4 and versions of browserify > 11.2.0 :smile:

asbjornenge avatar Apr 13 '16 08:04 asbjornenge

I encountered the "Unterminated string constant" issue with SVGs, and I had a bit of code I've used before to get around IE and Firefox issues with inline SVGs as well, so I merged those things in and updated the tests - see pull request #5

felthy avatar Jan 09 '18 00:01 felthy