Posts Tagged ‘XML’
* Surfin’ Safari
Posted on October 9th, 2008 by Dave Johnson. Filed under AJAX, CSS, JavaScript, XML, completeui, quirks, safari.
For the past little while I have been busy fixing up Complete UI to work in Safari. The big problem for us in getting Complete UI working in the WebKit powered browser was that there was no client side XSLT JavaScript API until Safari 3.
So there were a few things I had to update to get things all working properly - and this more or less applies to Chrome now as well but I need to check on a few things.
XMLDocument::selectNodes
The first problem I came across was using the XMLDocument::selectNodes method. To get selectNodes working I had to implement my own NamespaceResolver which is usually handled for you by the browser.
I had to change the call to the XMLDocument:evaluate method a bit to look like this:
var oResult = this.evaluate( sExpr, (oContextNode?oContextNode:this), new MyNSResolver(), XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
Where the MyNSResolver class essentially implements the lookupNamespaceURI method through a switch statement returning the appropriate URI for the specified namespace prefix. Pretty easy but kinda annoying to figure out!
function MyNSResolver() {};
MyNSResolver.prototype.lookupNamespaceURI = function(prefix) {
switch (prefix) {
case "xsl":
return "http://www.w3.org/1999/XSL/Transform";
break;
case "ntb":
return "http://www.nitobi.com";
break;
default:
return null;
}
}
XSLT Transformations
Then there was the actual act of performing an XSLT transformation. Doing the transformations was fine but getting the output node or string from the transformations - depending on if the <xsl:output /> was text, html or xml - was rather different than both Firefox and Internet Explorer. Go figure.
For transforming to an XMLDocument here is what I found to be the output of an XML transformation for the various output methods.
Text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<pre>innerText</pre>
</body>
</html>
XML:
<output>innerText</output>
HTML:
<html>
<body>
<output>innerText</output>
</body>
</html>
XSLT Parameters
There is also one difference in how the Safari XSLT processor deals with parameters. Rather than casting true / false to 1 / 0 the Safari XSLT processor does not recognize true or false values and requires the inputs to be 1 / 0. I have started setting all my XSLT params like this:
oXsltProc.addParameter("paramName", val+0, "");
Events and Focus
There were some other small issues that I came across regarding implementing rich keyboard navigation and events in general.
For example, in our Grid component I had to change the HTML element that we used to “focus” the Grid so that we could capture key presses from a <DIV> to an <INPUT>. Apparently you can’t call Element:focus on a <DIV> element from JavaScript but you can on an <INPUT> (even with a tabIndex set but I try to avoid those for accessibility reasons anyhow).
However, that was not my only problem with keyboard navigation. The other problem was that the focusable element (the newly created <INPUT> in this case) was still not getting focus due to a small code snippet like this:
oMyInput.focus();
cancelEvent(evt);
That second line where I cancel the event (wrapped nicely in a cross browser library call) somehow prevents the <INPUT> from getting the focus. Never figured out a workaround aside from a browser check before calling cancelEvent.
CSS
Finally, in some of our components we also generate CSS using XSTL and dynamically insert it into the page. For example, the developer defined column widths in a Grid produce dynamically generated CSS. However, WebKit does not seem to support the bulk creation of stylesheets neither using the document.createStylesheet method of Internet Explorer nor the hacky way of doing in Firefox by creating a <STYLE> element and setting the innerText. Instead Safari requires that you use the uber slow DOM API for adding rules to stylesheets
Miscellany
You will often see the “xml namespace prefix mapped to wrong URI” error when working with XSLT in Safari.
Be careful that you are using double quotes in your XSLT for attributes etc and only use single quotes in attribute values.
Of course you also have to be very careful about the nodes that you are transforming / selecting as you are also likely to get the “WRONG_DOCUMENT_ERR” fairly frequently.
Oh yah and depending on the application expect a lot of random “Stack overflow” errors!
Recent Posts
- BlackBerry JavaScript Oddities
- JavaScript Event Merging
- Smart Grid Utilities
- PhoneGap Desktop
- Crockford Facts
Archives
- July 2010
- June 2010
- April 2010
- March 2010
- February 2010
- January 2010
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005
- November 2005
- October 2005
- September 2005
- August 2005
- July 2005
- June 2005
- May 2005
