﻿// JScript File

function XmlDom() {

    if (window.ActiveXObject) {
        var arrSignatures = ['MSXML2.DOMDocument.5.0', 'MSXML2.DOMDocument.4.0','MSXML2.DOMDocument.3.0', 'MSXML2.DOMDocument','Microsoft.XmlDom'];
        
        for (var i=0; i < arrSignatures.length; i++) {
            try {
                var oXmlDom = new ActiveXObject(arrSignatures[i]);
                
                return oXmlDom;
            } catch (oError) {
                //ignore
            }
        }
    } else if (document.implementation && document.implementation.createDocument) {
        var oXmlDom = document.implementation.createDocument('','',null);
        
        oXmlDom.parseError = {
            valueOf: function () { return this.errorCode; },
            toString: function () { return this.errorCode.toString() }
        };
        
        oXmlDom.__initError__();
        
        oXmlDom.addEventListener('load',
                                 function (){
                                    this.__checkForErrors__();
                                    this.__changeReadyState__(4);
                                 }, 
                                 false);
        
        return oXmlDom;
    }
    
    throw new Error('Your browser doesn’t support an XML DOM object.');
}

var sUserAgent = navigator.userAgent;
var isKHTML = (sUserAgent.indexOf('KHTML') > -1) || (sUserAgent.indexOf('Konqueror') > -1) || (sUserAgent.indexOf('AppleWebKit') > -1);
var isMoz = (sUserAgent.indexOf('Gecko') > -1) && (!isKHTML);

if (isMoz) {
    Document.prototype.readyState = 0;
    Document.prototype.onreadystatechange = null;
    Document.prototype.__changeReadyState__ = function (iReadyState) {
        this.readyState = iReadyState;
    
        if (typeof this.onreadystatechange == 'function') {
            this.onreadystatechange();
        }
    };

    Document.prototype.__initError__ = function () {
        this.parseError.errorCode = 0;
        this.parseError.filepos = -1;
        this.parseError.line = -1;
        this.parseError.linepos = -1;
        this.parseError.reason = null;
        this.parseError.srcText = null;
        this.parseError.url = null;
    };

    Document.prototype.__checkForErrors__ = function () {
        if (this.documentElement.tagName == 'parsererror') {
            var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
            reError.test(this.xml);

            this.parseError.errorCode = -999999;
            this.parseError.reason = RegExp.$1;
            this.parseError.url = RegExp.$2;
            this.parseError.line = parseInt(RegExp.$3);
            this.parseError.linepos = parseInt(RegExp.$4);
            this.parseError.srcText = RegExp.$5;
        }
    };

    Document.prototype.__load__ = Document.prototype.load;

    Document.prototype.loadXML = function (sXml) {
        var ok;
    
        this.__initError__();
        this.__changeReadyState__(1);
        
        try{
            var oParser = new DOMParser();
            var oXmlDom = oParser.parseFromString(sXml, 'text/xml');
            
            while (this.firstChild) {
                this.removeChild(this.firstChild);
            }
            
            for (var i=0; i < oXmlDom.childNodes.length; i++) {
                var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
                this.appendChild(oNewNode);
            }
            ok = true
        }catch(e){
            ok = false
        }finally{
            this.__checkForErrors__();
            this.__changeReadyState__(4);
        
            return ok
        }
    };

    Document.prototype.createNode = function (a,b,c) {
        var newNode = this.createElement(b);
        return newNode;
    };
    
    Element.prototype.createNode = function (a,b,c) {
        var newNode = this.ownerDocument.createNode(a,b,c);
        return newNode;
    };
           
    
    Document.prototype.load = function (sURL) {
        this.__initError__();
        this.__changeReadyState__(1);
        this.__load__(sURL);
    };

    Node.prototype.__defineGetter__('xml', 
                                        function () {
                                            var oSerializer = new XMLSerializer();
                                            return oSerializer.serializeToString(this, 'text/xml');
                                        }
    );
    
    Element.prototype.selectNodes = function (sXPath) {
        var oEvaluator = new XPathEvaluator();
        var oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
        var aNodes = new Array;
        
        if (oResult != null) {
            var oElement = oResult.iterateNext();
            while(oElement) {
                aNodes.push(oElement);
                oElement = oResult.iterateNext();
            }
        }
        
        return aNodes;
    };
    
    Document.prototype.selectNodes = function (sXPath) {
        if (sXPath.indexOf("/") > 0)
        {
            var snewXPath = sXPath.substring(sXPath.indexOf("/")+1, sXPath.length)
            if (snewXPath.length > 0)
                return this.documentElement.selectNodes(snewXPath)
        }
        return this.documentElement
    };
        
    Element.prototype.selectSingleNode = function (sXPath) {
        var oEvaluator = new XPathEvaluator();
        var oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
        if (oResult != null) {
            return oResult.singleNodeValue;
        } else {
            return null;
        }
    };
    
    Document.prototype.selectSingleNode = function (sXPath) {
        if (sXPath.indexOf("/") > 0)
        {
            var snewXPath = sXPath.substring(sXPath.indexOf("/")+1, sXPath.length)
            if (snewXPath.length > 0)
                return this.documentElement.selectSingleNode(snewXPath)
        }
        return this.documentElement
    };
    
    Element.prototype.__defineGetter__('text', 
                                        function(){  
                                            var i, a=[];
                                            var nodes = this.childNodes;
                                            
                                            for (i=0; i<nodes.length; i++) {
                                                a[i] = nodes[i].text
                                            }
                                            
                                            return a.join("");
                                        }
    );
           
    Text.prototype.__defineGetter__('text',
                                    function(){
                                        return this.nodeValue
                                    }
    );
    
    Text.prototype.__defineSetter__('text',
                                    function(v){
                                        this.nodeValue = v;
                                    }
    );
    
    Node.prototype.__defineSetter__('text',
                                    function(v){
                                        this.nodeValue = v;
                                    }
    );
    
    Element.prototype.__defineSetter__('text',
                                    function(v){
                                        this.nodeValue = v;
										this.textContent = v;
                                    }
    );
}
