Friday, February 5, 2010

Fix 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

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

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;