Showing posts with label Firefox. Show all posts
Showing posts with label Firefox. Show all posts

OMG, more browsers are coming

The EU commission has reached an interesting agreement with Microsoft: Microsoft will present European users with a choice screen allowing them to select one of many browsers as their default browser. In principle, this is a great idea, if they could decide to offer users three or four browsers; very probably the users will have 10+ choices.

While this is supposedly good for users (and excellent for niche browser vendors), increased market share of currently irrelevant browsers might spell trouble for web developers using non-mainstream technologies (my favorite example: client-side XSLT transformation). For example, the percentage of users not using Firefox, IE or Chrome (yes, in that order) on one of my web sites is well below 5%, so I don’t care too much whether every little details works as it should. The situation would change drastically if they “minor” browsers would represent 20% of my users.

A nasty Firebug “surprise”

If you happen to believe that the client-side XSLT transformations are a good thing (I am firmly footed in that camp), Firefox 3.x brings nothing but disappointments. Now it's Firebug's turn: they’ve managed to mangle the console.log function. It worked a while ago, but then a brilliant mind decided to re-implement it with a hidden DIV between the HEAD and the BODY element:

<div id="_firebugConsole" style="display: none;" FirebugVersion="1.4.5"/>

This DIV is created automatically for regular (X)HTML pages, but not for XSLT-generated content, so the output of console.log gets sent to /dev/null (plus you get loads of weird error messages).

Firefox 3.5 XHTML support stinks

Continuing my Firefox “quality” rants: I just found the willpower to completely redesign my AJAX framework, going from IFRAMEs to jQuery AJAX calls (replacing straightforward and quite elegant XSL transformations with pages of convoluted JavaScript code) to work around the bugs in FF3.0, only to find out that FF3.5 is even worse and introduced numerous additional “features”.

For example, FF3.5 requires an explicit </script> tag within an XHTML document with proper DOCTYPE. The following document was validated with W3C XHTML validator …

<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Test</title>
  <script src="… source URL … " type="text/javascript" />
</head>
<body id="body">
</body>
</html>

… but it does not load the script in FF3.5.

Before anyone starts telling me that it’s not so hard to include the closing </script> tag in your source – try telling that to the database with native XML support where I’m storing snippets of the code. I had to convert the field from XML to TEXT (and lose all XML goodies I might eventually get) just to avoid the elimination of the explicit closing tag.

May I make a quick suggestion to the FF developers: maybe, just maybe, you might want to consider supporting existing web applications in parallel with adding new features that not too many people can use (because no other browser supports them yet).

Opinion: Is the Firefox development model really better than Microsoft’s?

Everyone loves bashing Microsoft and preaching the vast superiority of Firefox over IE, particularly its near-perfect implementation of W3C standards. Unfortunately, that might be true as long as you’re doing what the most vocal advocates (the CSS folks) are doing, if you happen to rely on some other “supported” standard, you might find yourself in deep ****.

As my regular readers know, I happened to make a decision to use client-side XSLT a while ago. From the technology standpoint, it was a perfect solution … until Firefox 3 came out. It has so many XSLT-related problems that it’s almost impossible to get the right combination of relevant parameters to have the same XSLT stylesheet working on Firefox, IE, Chrome and the web server (for non-XSLT-capable clients).

OK, one would understand that every major software project has bugs. But it’s hard to understand that so many of the XSLT bugs are untouched after several years. For example: generic ticket describing XSLT result document problems (4 years), HTML-DOM initialization issues (5 years), Firefox crashing when combining XSLT with document.write (6 years), Firebug not working on XSLT-generated pages (1,5 year).

I’ve heard all about limited resources and priorities in my “previous life”, but let’s face the reality: once the motivation (let’s beat IE) wears off and the platform accumulates years of old sins and bad decisions, the development model doesn’t matter. Firefox is becoming no better than IE.

Firefox XSLT errors

When I decided to use server-side XML output and client-side XSLT transformations a while ago, Firefox 2 was the ideal development platform – reliable, well implemented browser with excellent debugging capabilities (Firebug). Since then, the XSLT ignorami contributing code to Firefox have managed to break so many things I simply have to document everything I know to be broken in one place:

On top of everything else, Firebug does not work.

It breaks my heart, but I have to admit that with the rollout of Firefox 3 Internet Explorer 7 does a better job of handling client-side XSLT than Firefox.

Firebug does not work on XSLT-translated pages

If you want to use Firebug with Firefox 3 on pages using client-side XSLT transformation, you’re out of luck. Firebug simply does not work; the only way to a half-working environment is the following:

  • Restart the browser
  • Open an XML page with the xml-stylesheet directive.
  • Open a new tab and load a regular page into it.
  • Switch back to the previous tab. Firebug works within the context of the currently loaded page.

What’s really sad is that this has been reported by one of the Firebug developers almost two years ago … and nobody found it important enough to change the bug status from NEW to anything else.

The inconsistent consistencies are driving me crazy

Here’s a simple question: what’s wrong with this code?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:xf="http://www.example.com/common/xslforms">
...
<input type="button" value="X" id="tb_0" onClick="callX(0)" />

Among other things, this is not valid XHTML (as claimed in DOCTYPE) because the onClick attribute should be spelled in all-lowercase (onclick).

Now the trick question: why am I so annoyed by this code? Because it works in IE7, FF2 and FF3 if the server serves HTML to the client and fails only in FF3 if the client performs XSLT transformation using a stylesheet similar to this one:

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

<xsl:output method="html" encoding="utf-8"
  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<xsl:template match="/">
  <html xmlns:xf="http://www.plezanje.net/common/xslforms">
…
  <input type="button" value="X" id="tb_0" onClick="callX(0)" />
…
</xsl:template>

The ever-more-crazy implementation of XSLT in Firefox will persuade me to:

  • Stop using client-side XSLT transformations or
  • Stop supporting Firefox and recommend everyone to use IE or Chrome.

OMG: jQuery tag selectors are case sensitive

… if you use Firefox and client-side XSLT transformations. This is the scenario:

If you use tags in jQuery selectors, for example $(".pulldownMenu P A").click(handler), the tag names are case insensitive if you use IE or server-side transformation with Firefox but become case sensitive if Firefox performs client-side transformation regardless of xsl:output settings. To ensure your jQuery code works in all cases, write exactly the same tag names in jQuery selectors and XSLT stylesheet.

Firefox forgets to create document.body object on Linux

If you use client-side XSLT transformations driven by xml-stylesheet pseudo-instruction in XML documents, you might encounter interesting problems when using Firefox 2 on Linux. When the  HTML page is created with XSLT transformation, Firefox does not create the document.body object, causing JavaScript libraries (for example, jQuery) to break.

Workaround: add an ID to your body tag (for example, <body id="body">) and fix the document.body object after the DOM is ready. To do it in jQuery, use the following code:

$(function() {   if (!document.body) document.body = $('#body').get(0); }

Multiple style attributes in IE and FF

I've just stumbled across an interesting discovery today: if you use the style attribute multiple times in a single HTML tag (which you should not do, BTW, but it could happen if you write HTML code by hand), Internet Explorer will merge the style definitions whereas Firefox will ignore the second style attribute.

Reliability of client-side XSLT transformations

I've received an interesting question on my “Search Engine Optimization in XML+XSLT designs” post:
Are there considerable browser-specific differences in xsl transformation, or am I being overly cautious?
I've been using browser-side XSLT processing for three years. Although I had initial share of problems with IE5 and some releases of IE6 (finally forcing me to perform server-side transformations for IE5), IE6/7 and Firefox behave almost identically as long as your XSLT is valid. Firefox is a bit more relaxed in error handling, so it might survive an invalid stylesheet and ignore the error. Handling XML/XSLT errors on IE is a nightmare: if the XSLT transformation fails, it's almost impossible to reload the document without closing the browser (obviously IE has some serious caching problems with XML documents). To test new XSLT transformations, I usually force server-side transformations and receive good error messages from server's MSXML.

Opera is a different story. It didn't support XSLT until pretty recently and even then the document() function was broken. I have simply decided not to offer XML data to Opera visitors (they are a minority anyway) and Safari is not widespread enough in my customer base to notice.

This post is part of You've asked for it series of articles.

Firefox vulnerabilities when using data: or jar: protocols

Just stumbled across two articles describing vulnerabilities in the ways Firefox handles the data: and jar: protocols. If you're at least a bit interested in securing web applications (or your network), read them (and try to understand what's going on). It looks like the data: protocol vulnerability is a bug, but the jar: thing is a clear FAD (Functions-As-Designed).

XSLT-generated documents are never rendered in quirks mode in Firefox

I'm a heavy user of browser-side XSLT transformations (you can learn more about the techniques I'm using in the article I wrote for InformIT.com). While I'm usually generating HTML 4.0 (or event XHTML-) compliant transformation results, every now and then I would like to put the browser in quirks mode, for example, when I would like the text of my page to span the whole browser window (which is easily done with a TABLE with height set to 100% in quirks mode).

While this trick works nicely in Internet Explorer, Firefox produces standards mode layout (with TABLE contents condensed at the top of the screen) regardless of the HTML output the XSLT transformation generates. Probably this is due to the fact that the XSLT transformation in Firefox does not produce interim HTML string, but transforms DOM tree into another DOM tree.

Firefox hides the ?xml processing instruction

When I was testing the DOM handling of the XML processing instructions in various browsers, I've found an interesting inconsistency: Internet Explorer includes the <?xml ?> processing instruction in the DOM tree, while Firefox hides it.

For example, when the following XML document ...
<?xml version="1.0" encoding="windows-1250"?>

<?xml-stylesheet href="countryPage.xsl" type="text/xsl"?>

<Test />
... is transformed into a DOM tree and processed with this JavaScript function:
function testPI(dom) {

var topNodes = dom.childNodes;

for (var i = 0; i < topNodes.length; i++) {

var node = topNodes[i];

wr("nodeType="+node.nodeType);

if (node.nodeType == 7) {

wr("PI="+node.target+" ... "+node.data);

}

}
... Internet Explorer generates the following text:
nodeType=7
PI=xml ... version="1.0" encoding="windows-1250"
nodeType=7
PI=xml-stylesheet ... href="countryPage.xsl" type="text/xsl"
nodeType=1
... while Firefox skips the <?xml ?> processing instruction:
nodeType=7
PI=xml-stylesheet ... href="countryPage.xsl" type="text/xsl"
nodeType=1


You cannot disable output escaping in Firefox

This is probably well known to all experienced XSLT users, but if this will save a few readers the headaches I've had, it's well worth writing :) In Internet Explorer you can disable output escaping when using XSLT in the browser, thus being able to generate HTML tags from the text content of XML nodes. You cannot do the same in Firefox, as Firefox (or any Gecko-based browser) uses XSLT to transform input tree directly into output (DOM) tree, whereas XSLT transformation in Internet Explorer generates an intermediate string which is later re-parsed into HTML DOM tree.

Firefox does not generate any error when encountering the disable-output-escaping attribute (it's allowed by the XSLT standard) but simply ignores it and inserts the quoted < and > characters into the output stream.

Firefox document object lacks DOM properties in XSLT-generated pages

I started working on a keyboard-shortcut library and knew (somewhere in the hidden inaccessible depths of my mind) that I had a problem with document.body property a while ago. As it's required by the HTML DOM standard, I immediately suspected that it was an IE problem ... and chased that ghost for a while, until I've realized how wrong I was.

The buggy browser was Firefox: if you create a web page with local XSLT transformation (dictated by the xml-stylesheet instruction in the XML document returned from the server) in Firefox (up to at least 2.0.0.6), everything looks normal, but document.body is null and document.forms, document.links and other similar array are empty.

To make matters more confusing, all other HTML DOM calls work (it's a different bug from this one), so I had to substitute the links array with document.getElementsByTagName("A") and the body property with the document.getElementsById("body") (and used the id attribute on the body tag).

Firefox: HTML DOM fails if a local XSL transformation does not specify xsl:output

This nasty beast took me a while to figure out: if you do local XSL transforms in Firefox 1.5 and don't have the xsl:output directive in your main XSL stylesheet, HTML-specific DOM calls might not work.

The results are weird: for example, whatever is produced with the XSL transformation behaves like a HTML DOM object, but if you create a new element, it lacks HTML-specific DOM calls.

And the obvious solution: make sure you're always including ...
<xsl:output method="html" encoding="utf-8"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
... in your XSL stylesheet.

Firefox 1.5 bug: table.rows property is empty when using XSL

If you generate a table in Firefox 1.5 with an XSL stylesheet within the browser from an XML document loaded from the server, the table's rows property will contain no rows. You can still get the rows using the childNodes property though.

To make matters worse, Firefox does not generate an implicit TBODY element in the DOM tree, but IE7 and Opera do. Makes for a nice nightmare if you aim at cross-browser support ... the workaround code is included below:
function recurseChildNodes(parent,tag,callback) {
if (! parent.nodeName) return;
if (parent.nodeName.toLowerCase() == tag) { callback(parent); return; }
if (! parent.childNodes) return;

for (var i = 0; i < parent.childNodes.length; i++) {
recurseChildNodes(parent.childNodes[i],tag,callback);
}
}


recurseChildNodes(table,"tr",callbackFunction);