The problem I've encountered so far when deploying SVG content is that, of the various major configurations of SVG-enabled browsers out there, the most popular configuration (Internet Explorer + Adobe SVG Viewer 3.0) only seems to work nicely with the <embed> tag, but all other implementations (Opera and Mozilla Firefox) work nicely (and sometimes ONLY) with the <object> tag and NONE currently work at all with the <img> tag. What a hairy mess! Let's come up with a simple solution...
We can write off <img> support for awhile until Opera and Firefox fix their bugs, so I'll just concentrate on being able to provide the <embed> tag instead of the <object> when we have Internet Explorer + ASV. I'd like to author my (X)HTML document by putting my SVG bits inside an <object> tag and then have a simple JavaScript function that will transmogrify any <object> tags into <embed> tags if the user agent is Internet Explorer and the Adobe SVG Viewer is installed. Such a solution is the best out of several lesser alternatives because:
- The <embed> tag is non-standard and should be deprecated where possible. In the far future my script should not be necessary and can be simply removed while the underlying <object> markup will still function.
- Authoring with <embed> tags would mean there is no way to present alternate content should the user agent be unable to display SVG. The <noembed> tag doesn't help us, since the contents of the <noembed> are only displayed if the user agent does not support the <embed> tag (not SVG content, a big difference).
- A pure JavaScript solution would prevent search engines from indexing the content
I came across this article from Design-Ireland.net that gives an example of how to detect IE and ASV. Adobe also has their versions of this here and here page. The Adobe find is especially intriguing because it explains how the Adobe SVG Viewer can be detected and if not installed, how to automatically download via a user prompt. Looking at these Adobe pages, it is obvious that the code is a little out of date: the MIME type is "image/svg-xml" and there are now a couple native SVG choices (Opera and Firefox 1.1) but it does have an example of how to detect if ASV is installed by checking for the ActiveX object. I may use a version of this Adobe code to eventually help automate the install of ASV on my website.
Both of the above examples use a bit of VBScript to do this, but I decided to keep everything as JavaScript (at the cost of breaking compatibility with older browsers due to the try-catch block needed). The code is posted at http://www.codedread.com/lib/svglib.js.
An author would write their HTML like:
<head>
<script type="text/javascript" src="http://www.codedread.com/lib/svglib.js"></script>
</head>
<body onload="cleanSvg()">
<object data="button.svg" type="image/svg+xml" width="100" height="50">
<p style="color:red">Error! You need to have a browser that supports <strong>SVG</strong>, go download....</p>
</object>
</body>
</html>
In the IE+ASV case, the above HTML code will get transmuted into the following code:
<head>
<script type="text/javascript" src="http://www.codedread.com/lib/svglib.js"></script>
</head>
<body onload="cleanSvg()">
<embed class="svgex" src="button.svg" type="image/svg+xml" width="100" height="50">
<noembed>
<p style="color:red">Error! You need to have a browser that supports <strong>SVG</strong>, go download....</p>
</noembed>
</embed>
</body>
</html>
One enhancement I will have to make eventually is to transform the <param> elements within the <object> element into applicable attributes within the <embed> element. This will be especially useful for the pluginspage parameter.
Looks great, you keep the content on the page as much as possible and only replace what you need to.
I take it this means you’ve decided to stick with passive browser sniffing? I’d throw in something to track which combination of viewer and browser is being used, but we’ll see how it goes when I finally get around to it.
I still haven’t wrapped up my whole browser sniffing thing in my head. Adobe has a pretty complex example, though it’s aged and would have to be updated. Anyway, as far as I can tell, there’s no way to find out the actual SVG renderer being used from within a JS environment. For instance, in Fx I can use this extension to disable the native rendering and use something else (ASV) for instance. And if you’re talking about logging the combination then that would have to be done at the server-side, which is another layer removed from the actual user experience/environment.
Where’s the http://yourserver.com/automatically_stuff_in_the_javascript.php?URL=http://myserver.com/mycontent.svg
?
steltenpower: I’m not sure I follow the question exactly. I guess you are proposing that I write a PHP script that will create a page from a given SVG URI but wrap the given SVG URI into an object (in most cases) or an embed (in the IE+ASV case)? Kind of like a “HTML harness” for SVG. This isn’t a bad idea, good for other authors to test it out, but my script doesn’t do anything particularly fancy. My concern was more for authoring my own SVG content embedded already in HTML (via object tags) and then have some client-side script that transforms it into embed tags in the case of IE+ASV.
Maybe you can clarify what you want the PHP file for…
Sorry, i didn’t really write down what i was thinking. Maybe i’m more awake this time:
I meant
http://yourserver.com/automatically_stuff_in_the_javascript.php?URL=http://myserver.com/my_html_with_svg_objects_in_it.html
Recently stumbled upon two links that help implementing this idea without using the embed nor conditional comment hacks:
* http://my.opera.com/Andrew%20Gregory/blog/2007/08/04/svgs-on-web-pages
(original post where this was seen in the first place)
* http://joliclic.free.fr/html/object-tag/en/object-svg.html
(source link where above link is based on)
I’ve made a few experiments and this seems to do the trick, at least in IE+ASV, Firefox, Safari and Opera.
Hope this helps,
Helder Magalhães
Thanks Helder for the links. I personally don’t use SVG within IE anymore (a statement more than a technical hurdle), but I hope your comment reaches those people that do.