Friday, February 5, 2010

Fixing the XPath problem in Firefox 3.6

In Greasemonkey development, it is a common practice to use GM_xmlhttpRequest + DOM Document Wrapper + XPath to process cross-origin content. However in Firefox 3.6, the XPath query stop working. Here is the fix:

Firefox 3.5 code

var doc = document.implementation.createDocument("", "", null);
div.innerHTML = html;
doc.appendChild(div);
var res = doc.evaluate("//p[@class='content']/span", div, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
// res is null

Firefox 3.6 code

var isFF36up = false;
if (navigator.userAgent) {
var ffver = navigator.userAgent.match(/Firefox\/3\.(\d+)/);
isFF36up = ffver && parseInt(ffver[1], 10) >= 6;
}

var nsResolver = {
lookupNamespaceURI:function (prefix) {
if (isFF36up && prefix == "ns") {
return "http://www.w3.org/1999/xhtml";
}
else {
return "";
}
}
};

var doc = document.implementation.createDocument("", "", null);
div.innerHTML = html;
doc.appendChild(div);
var res = doc.evaluate("//ns:p[@class='content']/ns:span", div, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;