// $Id: dom.js 25 2007-07-24 03:33:10Z unicinfo $
// Copyright (c) 2004 Kurt M. Brown, x2ii.info.
// This file is subject to the terms and conditions of the GNU General Public
// License. See the file COPYING for more details.

xi.dom = {}; // namespace dom

Document.prototype.__defineGetter__(
    'xml',
    function() {
        return (new XMLSerializer()).serializeToString(this);
    }
);
Node.prototype.__defineGetter__(
    'xml',
    function () {
        return (new XMLSerializer()).serializeToString(this);
    }
);
Document.prototype.selectNodes = function(xpath, contextNode)
{
    var result = this.evaluate(
        xpath,
        (contextNode == undefined ? this.documentElement : contextNode),
        this.createNSResolver(this.documentElement),
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    );
    var nodeList = new Array(result.snapshotLength);
    nodeList.expr = xpath;
    for (var i = 0; i < nodeList.length; ++i)
        nodeList[i] = result.snapshotItem(i);

    return nodeList;
}
Document.prototype.selectSingleNode = function(xpath, contextNode)
{
    var nodeList = this.selectNodes(xpath + '[1]', contextNode);
    return (nodeList.length > 0) ? nodeList[0] : null;
}
Element.prototype.removeAllChildren = function()
{
    while (this.hasChildNodes())
        this.removeChild(this.firstChild);

}
Element.prototype.selectNodes = function(xpath)
{
    return this.ownerDocument.selectNodes(xpath, this);
}
Element.prototype.selectSingleNode = function(xpath)
{
    return this.ownerDocument.selectSingleNode(xpath, this);
}
Element.prototype.setIntOrNothing = function(name, value)
{
    const val = parseInt(value, 10);
    if (!isNaN(val))
        this.setAttribute(name, val);
}
Element.prototype.setFloatOrNothing = function(name, value)
{
    const val = parseFloat(value);
    if (!isNaN(val))
        this.setAttribute(name, val);
}
Element.prototype.setBoolean = function(name, value)
{
    this.setAttribute(name, value ? 'true' : 'false');
}
Element.prototype.getAttributeOrNull = function(name) {
    // treat the lack of an attribute (getAttribute() returns null) as null
    // or an attribute equal to a blank "" as null.
    const value = this.getAttribute(name);
    return value == null ? null : (value == '' ? null : value);
}
Element.prototype.getBoolean = function(name)
{
    return this.getAttribute(name) == 'true';
}
Element.prototype.getBooleanOrNull = function(name)
{
    const value = this.getAttribute(name);
    return value == null ? null : (value == '' ? null : (value == 'true'));
}
Element.prototype.getNumber = function(name)
{
    // Number(null) == 0
    return new Number(this.getAttribute(name));
}
Element.prototype.getNumberOrNull = function(name)
{
    const value = parseFloat(this.getAttribute(name));
    return isNaN(value) ? null : new Number(value);
}

xi.dom.toString = function(xDoc)
{
    return new XMLSerializer().serializeToString(xDoc);
}
xi.dom.quoteStr = function(sIn)
{
    var qs = new String();
    if (sIn != null) {
        var s = new String(sIn);
        for (var i = 0; i < s.length; ++i) {
            if (s.charAt(i) == '<')
                qs += "&lt;";
            else if (s.charAt(i) == '>')
                qs += "&gt;";
            else if (s.charAt(i) == '&')
                qs += "&amp;";
            else if (s.charAt(i) == '"')
                qs += "&quot;";
            else if (s.charAt(i) == "'")
                qs += "&apos;";
            else
                qs += s.charAt(i);
        }
    }
    return qs;
}
xi.dom.create = function(str)
{
    return new DOMParser().parseFromString(str, 'text/xml');
}

