// Wrapper around Firefox's insanely difficult XML functionality

// evaluate the xpath expression on the node.
function queryPath(node, xpath)
{
var document;

if(node.ownerDocument)
{
document = node.ownerDocument;
}
else
{
document = node;
}

var evaluator = new XPathEvaluator(), ANY = XPathResult.ANY_TYPE;
var resolver = evaluator.createNSResolver(document);

return document.evaluate(xpath, node, resolver, ANY, null);
}

// simulates the ie6 way of select nodes in xml documents.
function FFSelectNodes(xpath)
{
var queryResult;
var thisNode;
var nodeArray = [];
var count = 0;
var self = this;

queryResult = queryPath( this, xpath );

// put the nodes into an array
thisNode = queryResult.iterateNext();

while( thisNode )
{
nodeArray.push( thisNode );
thisNode = queryResult.iterateNext();
count++;
}

return nodeArray;
}
XMLDocument.prototype.selectNodes = FFSelectNodes;

// This function expects a xsl document object
function FFTransformNode(aXSLRef)
{
var xsltProc = new XSLTProcessor();
// load the xsl file synchronous, sucks but no work around
xsltProc.importStylesheet(aXSLRef);
return xsltProc.transformToFragment( this, document );
}
XMLDocument.prototype.transformNode = FFTransformNode;

function FFGetXSLDoc(aFileRef, handler)
{
var xslDoc = document.implementation.createDocument("", "", null);
xslDoc.onload = function() { handler(xslDoc) };
xslDoc.load(aFileRef);
return xslDoc;
}

// Convenience, takes a string and a target node to append to
function FFTransformNodeInto(aXSLRef, target)
{
var selfRef = this;

// once again closures
// so useful when working asynchronously
function handleXSL( xslDoc )
{
var fragment = selfRef.transformNode( xslDoc );

$(target).innerHTML = "";
$(target).appendChild( fragment );
}

// this takes a text file reference a calls your
// handler with a real xslDocument
FFGetXSLDoc( aXSLRef, handleXSL );
}
XMLDocument.prototype.transformNodeInto = FFTransformNodeInto;