This has been a major problem for all our XHTML projects. Briefly, the problem is this:
- XHTML documents must be served with the mime type "application/xhtml+xml", because the W3C says so.
- If we do serve documents with this mime type, two problems occur:
- Internet Explorer doesn't display the document; it just offers to save it. Even IE7 has this problem: it was a policy decision by IE's developers.
- Safari quite logically refuses to allow the use of innerHTML when the mime type is not text/html.
I now have a solution to #1: using Cocoon's built-in browser selector in Cocoon's sitemap, we can serve pages to IE with the wrong mime type, but serve the correct mime type to all the other browsers. It works like this:
<map:select type="browser">
<map:when test="explorer">
<!-- for IE, we have to serve text/html :-( -->
<map:serialize type="xhtml11_compat" />
</map:when>
<map:otherwise>
<map:serialize type="xhtml11"/>
</map:otherwise>
</map:select>
The "xhtml11_compat" serializer is a custom serializer we've added to the root sitemap of Cocoon, which looks like this:
<map:serializer logger="sitemap.serializer.xhtml" mime-type="text/html" name="xhtml11_compat" pool-grow="2" pool-max="64" pool-min="2" src="org.apache.cocoon.serialization.XMLSerializer">
<doctype-public>-//W3C//DTD XHTML 1.1//EN</doctype-public>
<doctype-system>http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd</doctype-system>
<encoding>UTF-8</encoding>
</map:serializer>
This just serializes the document as XML with an XHTML doctype, but with a mime type of text/html. It's a hack, but it's IE's fault, and we're only breaking the rules for IE; other browsers see the correct mime type.
The second problem remains, but I have an angle on it, as reported previously, by using XMLHttpRequest.responseXML and DOM methods to add AJAX-retrieved elements to the page DOM instead of using innerHTML. On that topic, I noticed this quote on the release notes for Firefox Gran Paradiso Alpha 2 (meaning the latest alpha for Firefox 3):
Moving DOM nodes between documents now requires a call to importNode or adoptNode as per the DOM specification.
I need to make sure that I'm testing for the availability of those methods, and using them if they're there, before falling back to cloneNode, appendChild, copyNode or whatever simpler (but incorrect) options are currently supported in browsers such as Firefox 2.