/* Client Side JavaScript XSL based XML parser
/* By Brian Hill, hillb@yosemite.edu.
/* http://hillb.staff.yosemite.edu
/* Version 1.1
/* See xmlpost.txt for use information.


/* flag to figure out what type of browser we're dealing with */
var isMSXML = (window.ActiveXObject); //Browsers using the MSXML engine.
var isFirefox = (document.implementation && document.implementation.createDocument); //Browsers using the Firefox model


function xmlPost(xmlPath, xslPath, postTarget, preserve) {

	/* First execute the webkit compatible model, but block ff */
	if ((navigator.userAgent.indexOf("Firefox") == -1)){
		   setXml(xmlPath);
		   setXslt(xslPath);
		   transform(postTarget, preserve);
	} 

	if(isMSXML){
		/*IE */
		var newHTML = genHTML(xmlPath, xslPath);
		postHTML(postTarget, newHTML, preserve);
	} else {
		var processor = new XSLTProcessor();

		 /*filter out webkit browsers using the FF model to prevent duplicate execution*/
		if (typeof processor.transformDocument == "function") {
			
			var newHTML = genHTML(xmlPath, xslPath);
			postHTML(postTarget, newHTML, preserve);
		}


	}
}

/* ORIGINAL REVISION OF CODE


inserts text into page*/
//function postHTML(postTarget, newHTML, preserve){
//	var outputHTML = newHTML; //var will hold our final output	
//    var oldHTML = document.getElementById(postTarget).innerHTML; //copy existing content from div
//	
//	/* if call wants to preserve existing content, we need to append it to the beginning of the newly generated data*/
//	if (preserve && isMSXML) { /* MSXML treats the new data as text, so we just append the old content to the beginning of the string*/
//		outputHTML = oldHTML + newHTML;	
//	} else if (preserve && isFirefox) { /* FF treats the new data as a fragment, so we need to create a second fragment and merge them */
//		var fragment = document.createDocumentFragment();
//		var contents = fragment.appendChild(document.createElement('div'));
//		contents.appendChild(document.createTextNode(oldHTML));
//		contents.appendChild(newHTML);
//		outputHTML = contents;
//	}
//		
//	/* Post final data to target */
//	document.getElementById(postTarget).textContent = ""; // clear the existing div contents
//	if (isMSXML){
//		document.getElementById(postTarget).innerHTML = outputHTML; // for IE, replace div contents with new output. 
//	} else if (isFirefox){
//		document.getElementById(postTarget).appendChild(outputHTML); // for FF we append the fragment to the target div
//	} 
//}


/*inserts text into page*/
function postHTML(postTarget, newHTML, preserve){
	var outputHTML = newHTML; //var will hold our final output	
    var oldHTML = document.getElementById(postTarget).innerHTML; //copy existing content from div
	
	
	if (! preserve) {
		document.getElementById(postTarget).textContent = ""; // clear the existing div contents only if preserve not specified
	}

	if (isMSXML && preserve) { /* MSXML treats the new data as text, so we just append the old content to the beginning of the string*/
		document.getElementById(postTarget).textContent = ""; // always clear existing div contents for MSIE
		outputHTML = oldHTML + newHTML;	
	} else if (isMSXML && (! preserve)) {
		document.getElementById(postTarget).textContent = ""; //div contents must always be cleared for MSIE
	}
	
	/* Post final data to target */

	if (isMSXML){
		document.getElementById(postTarget).innerHTML = outputHTML; // for IE, replace div contents with new output. 
	} else if (isFirefox){
		document.getElementById(postTarget).appendChild(outputHTML); // for FF we append the fragment to the target div
	} 
}

/*generates and returns code to be inserted into page */
function genHTML(xmlPath, xslPath){
	var inXSL = loadXML(cleanURL(xslPath));
	var inXML = loadXML(cleanURL(xmlPath));
	var htmlCode;
	var readXML = null;

	if (! isMSXML){
		var xsltProcessor=new XSLTProcessor();
		xsltProcessor.importStylesheet(inXSL);
		htmlCode = xsltProcessor.transformToFragment(inXML,document);
	} else {
		htmlCode = inXML.transformNode(inXSL);
	}

return htmlCode;

}

/* obtain and load the XML from the remote file */
function loadXML(xmlPath) {
  
  var readXML = null;

  if (! isMSXML) {
		readXML=document.implementation.createDocument("","",null);
  } else {
		readXML=new ActiveXObject("Microsoft.XMLDOM");

  }
	readXML.async=false;
	readXML.load(xmlPath);

	return(readXML);
}

/* block external addresses for security. */
function cleanURL(inURL) {
	var testURL = inURL.toLowerCase();
	if (testURL.indexOf("http://") == 0){
		return "Path Format Error"; /*It's improbable that the string could be cleaned up without breaking the path, so just fail.*/	
	}	
	return inURL;
}


/******
/* WebKit based browsers must be treated differently. These vars and functions are specific to WebKit rendering
/* Credit to Johann Burkard <http://eaio.com> for handling model
*******/
    var xml;    
    var xmlDoc;
    var xslt;
    var xsltDoc;
    var transformed = false;
	
    function getXml(){ return xml;}
    function getXmlDocument() { return xmlDoc}
    function setXml(x) { xml = x;}
    function getXslt() { return xslt;}
    function getXsltDocument() { return xsltDoc;}
    function setXslt(x) { xslt = x;}


    function transform(target, preserve) {
        var str = /^\s*</;
          if (! document.recalc) {
           var transformed = false;

            var xm = {
                readyState: 4
            };
            var xs = {
                readyState: 4
            };
            function change() {
                if (xm.readyState == 4 && xs.readyState == 4 && !transformed) {
                    xmlDoc = xm.responseXML;
                    xsltDoc = xs.responseXML;
                    var resultDoc;
                    var processor = new XSLTProcessor();
                                       
                    if (typeof processor.transformDocument != "function") {
                        processor.importStylesheet(xs.responseXML);
                        resultDoc = processor.transformToFragment(xm.responseXML, document);
						if (! preserve)
						{
							document.getElementById(target).innerHTML = "";
							document.getElementById(target).appendChild(resultDoc);
						} else {

							document.getElementById(target).appendChild(resultDoc);
						}
                    }
                    
                    transformed = true;
                }
            }; 

            if (str.test(xml)) {
                xm.responseXML = new DOMParser().parseFromString(xml, "text/xml");
            }
            else {
                xm = new XMLHttpRequest();
                xm.onreadystatechange = change;
                xm.open("GET", xml);
                xm.send(null);
            }

            if (str.test(xslt)) {
                xs.responseXML = new DOMParser().parseFromString(xslt, "text/xml");
                change();
            }
            else {
                xs = new XMLHttpRequest();
                xs.onreadystatechange = change;
                xs.open("GET", xslt);
                xs.send(null);
            }
        }
    }
