Firefox can’t DOEY!

Posted Thursday, September 7th, 2006 at 10:38 pm

If you are writing an XSL for some particular XML data you have to be outputted into HTML, you may run into a problem when you view your XML data with your XSL transformation applied to it in Firefox. The reason for this is because the Firefox developers have chosen not to implement part of the XSLT specification for disable-output-escape (DOEY).

To get around this, one must make quite a bit of changes to their XSL to accomodate Firefox. This smells alot like what alot of people have to do often for MSIE, except with Firefox being the ugly one this time.

Click to see my example XSL sheet below for a rough reference on how this can be achieved.



<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html"/>

<xsl:template match="/">

  <html>
    <head>
      <title>My XSLT + Firefox + DOEY Webpage</title>

      <!-- Mozilla ignores disable-output-escaping
      so we must convert it ourselves. Boohiss @ Firefox...-->

      <script type="text/javascript">
	  // <![CDATA[
	  // http://www.quirksmode.org/js/detect.html Detect if Firefox.
			var BrowserDetect = {
			init: function () {
				this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
				this.version = this.searchVersion(navigator.userAgent)
					|| this.searchVersion(navigator.appVersion)
					|| "an unknown version";
				this.OS = this.searchString(this.dataOS) || "an unknown OS";
			},
			searchString: function (data) {
				for (var i=0;i<data.length;i++)	{
					var dataString = data[i].string;
					var dataProp = data[i].prop;
					this.versionSearchString = data[i].versionSearch || data[i].identity;
					if (dataString) {
						if (dataString.indexOf(data[i].subString) != -1)
							return data[i].identity;
					}
					else if (dataProp)
						return data[i].identity;
				}
			},
			searchVersion: function (dataString) {
				var index = dataString.indexOf(this.versionSearchString);
				if (index == -1) return;
				return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
			},
			dataBrowser: [
				{
					string: navigator.userAgent,
					subString: "Firefox",
					identity: "Firefox"
				}
				// clipped other browsers from original code for brevity.
			],
			dataOS : [
				{
					string: navigator.platform,
					subString: "Win",
					identity: "Windows"
				},
				{
					string: navigator.platform,
					subString: "Mac",
					identity: "Mac"
				},
				{
					string: navigator.platform,
					subString: "Linux",
					identity: "Linux"
				}
			]

		};
		BrowserDetect.init();

	   //Some credit here: http://sonic64.com/2005-03-19.html
	   //But I'm not sure if they were the original author of this method.
       function fixlinksforfirefox() {
			if(BrowserDetect.browser == 'Firefox'){
					var elements = document.getElementsByTagName('div');
					for (var i = 0; i < elements.length; i++) {
						var el = elements[i];
						if (el.className == 'decodeable') {
							el.innerHTML = el.firstChild.data;
						}
					}
			}
       }
      // ]]>
      </script>  

    </head>
     <body onload="fixlinksforfirefox()">

      <h1>Hello World</h1>

		<div class="decodeable">
			<xsl:text disable-output-escaping="yes"><![CDATA[<a href="#]]></xsl:text>
				<xsl:value-of select="@sometag"/><xsl:text disable-output-escaping="yes"><![CDATA[">]]></xsl:text>
			<xsl:value-of select="@sometag"/><xsl:text disable-output-escaping="yes"><![CDATA[</a>]]></xsl:text>
		</div>

      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>

</xsl:stylesheet>



Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word