Showing posts with label Chrome. Show all posts
Showing posts with label Chrome. 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.

Chrome does not hide an element that is not attached to the document

In IE, FF and Opera, the following code hides a DIV element, starts loading the content in it and appends the hidden DIV to the body:

$("<div id='loginDialog'>").hide().load(url).appendTo("body");

In Chrome, the element is created, content is loaded into it, it appears at the end of the document, but it’s not hidden. To make the same code work in Chrome, you have to switch the order of operations: append first, hide later:

$("<div id='loginDialog'>").appendTo("body").load(url).hide();

Detect whether your browser has a working XSLT implementation

After I’ve finally managed to persuade IE7, FF and Transform jQuery plugin to work with my XSL documents, I’ve started testing the other two browsers I have: Opera and Chrome. The latest release of Opera might occasionally work. Chrome fails (as expected) as it doesn’t support xsl:import. Welcome to the next round of browser incompatibilities.

I’ve decided to ignore Chrome until the great minds @ Google decide to implement XSLT properly. Visitors using it will have reduced experience … but of course I have to detect whether I should use XSLT or not.

Here’s a small Christmas gift if you have similar issues: a jQuery extension that checks whether the current visitor can use XSLT transformations.

jQuery.xslt = {
  need: function(success,url,xml) {
    var componentCount = 0;
    var xslt;
    var el;
    var debug=1;
    
    function tryTransform() {
      if (typeof(xslt) != 'object') return; // XSL did not parse into XML object
      var html = $.transform({xmlstr: xml, xslobj: xslt, async: false});
      alert("html="+html);
      if (!html) return;
    }

    function gotScript() {

      function transformFail(html,xsl,xml,obj,ex) { 
        if(debug) alert ("$.xslt.need failed:"+ex.message); }
    
      function transfromDone(html,xsl,xml,obj) { 
        $.xslt.has = html.search($.xslt.expectedResult) >= 0;
        if ($.xslt.has && success) success();
      }
      
      el = $("<div>");
      el.transform({xmlstr: xml, xsl: url, 
        success: transfromDone, error: transformFail});
    }
    
    url = url ? url : $.xslt.defaultURL;
    xml = xml ? xml : $.xslt.defaultXML;
    $.getScript($.xslt.transformScript,gotScript);
  },
  has: false,
  
  defaultURL: "/forms/xml/static.xsl",
  defaultXML: "<section />",
  transformScript: "/common/js/jquery.transform.packed.js",
  expectedResult:  /table/i
}

The extension implements a simple function and a property: $.xslt.need() and $.xslt.has. You can pass the URL to the sample XSL document and the sample XML markup to the need function; it also supports a success callback to tell you whether you should install XSL-related action handlers.

The need function loads the jQuery Transform plugin (reducing the load time if the page does not need the XSLT functionality) and tries to transform a sample XSL document. The sample transformation should be as complex as possible: you should use xsl:import, xsl:include or the document() function if you use them in other transformations.

You could change the default parameters in the source code or write a setup function.

Poor man's AJAX: Browser-side XSLT transformation in IFRAME

One of the oldest methods to provide AJAX-like functionality in a browser that does not support XmlHttpRequest object is loading the dynamic content into a hidden IFRAME. It’s an unreliable technique that should not be used, but it can still provide a viable workaround in scenarios where you need to perform browser-side XSLT transformation in browsers with lousy JavaScript-based XSLT support (it looks like Chrome is still in this category).

This is a conceptual step-by-step description of the process:

  • Create a hidden IFRAME in the main page.
  • Define a callback function in the main page that will receive the results of the transformation. This callback function will have to insert the transformation results into the main page’s HTML/DOM structure.
  • When you need to download additional content, set the IFRAME.href attribute to the URL of the dynamic content.

You should use a timeout in the main page to capture failed loads of the dynamic content. The timeout code should display an error message and kill the download process in IFRAME by resetting the IFRAME.href attribute.

  • The dynamic content loaded into the IFRAME should have XML MIME type and contain the xml-stylesheet processing instruction. This will cause the browser to perform XSLT transformation on the XML data.
  • The resulting HTML should include JavaScript call of the callback function in the parent frame, for example <body onload="parent.callback(document.body.innerHTML)">

Alternatively, you can use the onload handler in the IFRAME element to call the callback function.

Chrome: first impressions

I've just downloaded Chrome (the new browser from Google), tested it on my applications and got immediately impressed - they all worked, even the client-side XSLT transformation driven by the xsl-stylesheet directive. Then I did a few more random tests and my enthusiasm was drastically reduced:
  • The inter-line spacing on table heading texts was way too large: <th valign='bottom'>Line 1<br />Line 2</th> produced a blank line between the two text lines. I did not investigate what the root cause might be as all the other major browsers render it almost identically, so I don't really care what upset Chrome.
  • The top line of our corporate Wiki (the Login text) is misplaced.
  • The View source window does not display processing instructions in XML documents.
  • And the worst offender: Blogger in draft works way better, faster and more reliable in Firefox or Internet Explorer than in Chrome.
Summary: I will have Chrome installed to test my applications (some visitors are already using it), but will not use it in the near future.