// AJAX-JSF AJAX-like library, for communicate with view Tree on server side.
// In case of XMLHttpRequest don't worked, use :
// JSHttpRequest v1.12. (C) Dmitry Koterov, 2005-01-27. 
// http://forum.dklab.ru/users/DmitryKoterov/
//
// Do not remove this comment if you want to use script!
// ?? ???????? ?????? ???????????, ???? ?? ?????? ???????????? ??????!
//
// Modified by Alexander J. Smirnov to use as JSF AJAX-like components. 

// DOM - like elements for JSRequest. JS serialiser encode
// XML sax events to creation of corresponding objects.  
JSNode =  function() {
};

JSNode.ED = function(empty) {
	this.empty = empty
};
JSNode.eltt = {
	'a' :new JSNode.ED(false),
	'abbr' :new JSNode.ED(false),
	'acronym' :new JSNode.ED(false),
	'address' :new JSNode.ED(false),
	'applet' :new JSNode.ED(false),
	'area' :new JSNode.ED(true),
	'b' :new JSNode.ED(false),
	'base' :new JSNode.ED(true),
	'basefont' :new JSNode.ED(true),
	'bdo' :new JSNode.ED(false),
	'big' :new JSNode.ED(false),
	'blockquote' :new JSNode.ED(false),
	'body' :new JSNode.ED(false),
	'br' :new JSNode.ED(true),
	'button' :new JSNode.ED(false),
	'caption' :new JSNode.ED(false),
	'center' :new JSNode.ED(false),
	'cite' :new JSNode.ED(false),
	'code' :new JSNode.ED(false),
	'col' :new JSNode.ED(true),
	'colgroup' :new JSNode.ED(false),
	'dd' :new JSNode.ED(false),
	'del' :new JSNode.ED(false),
	'dfn' :new JSNode.ED(false),
	'dir' :new JSNode.ED(false),
	'div' :new JSNode.ED(false),
	'dl' :new JSNode.ED(false),
	'dt' :new JSNode.ED(false),
	'em' :new JSNode.ED(false),
	'fieldset' :new JSNode.ED(false),
	'font' :new JSNode.ED(false),
	'form' :new JSNode.ED(false),
	'h1' :new JSNode.ED(false),
	'h2' :new JSNode.ED(false),
	'h3' :new JSNode.ED(false),
	'h4' :new JSNode.ED(false),
	'h5' :new JSNode.ED(false),
	'h6' :new JSNode.ED(false),
	'head' :new JSNode.ED(false),
	'hr' :new JSNode.ED(true),
	'html' :new JSNode.ED(false),
	'i' :new JSNode.ED(false),
	'iframe' :new JSNode.ED(false),
	'img' :new JSNode.ED(true),
	'input' :new JSNode.ED(true),
	'ins' :new JSNode.ED(false),
	'isindex' :new JSNode.ED(true),
	'kbd' :new JSNode.ED(false),
	'label' :new JSNode.ED(false),
	'legend' :new JSNode.ED(false),
	'li' :new JSNode.ED(false),
	'link' :new JSNode.ED(true),
	'map' :new JSNode.ED(false),
	'menu' :new JSNode.ED(false),
	'meta' :new JSNode.ED(true),
	'noframes' :new JSNode.ED(false),
	'noscript' :new JSNode.ED(false),
	'object' :new JSNode.ED(false),
	'ol' :new JSNode.ED(false),
	'optgroup' :new JSNode.ED(false),
	'option' :new JSNode.ED(false),
	'p' :new JSNode.ED(false),
	'param' :new JSNode.ED(true),
	'pre' :new JSNode.ED(false),
	'q' :new JSNode.ED(false),
	's' :new JSNode.ED(false),
	'samp' :new JSNode.ED(false),
	'script' :new JSNode.ED(false),
	'select' :new JSNode.ED(false),
	'small' :new JSNode.ED(false),
	'span' :new JSNode.ED(false),
	'strike' :new JSNode.ED(false),
	'strong' :new JSNode.ED(false),
	'style' :new JSNode.ED(false),
	'sub' :new JSNode.ED(false),
	'sup' :new JSNode.ED(false),
	'table' :new JSNode.ED(false),
	'tbody' :new JSNode.ED(false),
	'td' :new JSNode.ED(false),
	'textarea' :new JSNode.ED(false),
	'tfoot' :new JSNode.ED(false),
	'th' :new JSNode.ED(false),
	'thead' :new JSNode.ED(false),
	'title' :new JSNode.ED(false),
	'tr' :new JSNode.ED(false),
	'tt' :new JSNode.ED(false),
	'u' :new JSNode.ED(false),
	'ul' :new JSNode.ED(false),
	'var' :new JSNode.ED(false)
};


// Base node  
JSNode.prototype = {
	tag : null,
	attrs : {},
	childs : [],
	value : "",
	_symbols : {
			'&':"&amp;",
			'<':"&lt;",
			'>':"&gt;",
			'"':"&quot;",
			'\'':"&apos;",
			'\u00A0':"&nbsp;"
	}, 
	// Public functions
	getInnerHTML : function(context) {
		var html = "";
		for (var i = 0; i < this.childs.length; i++)
			html += this.childs[i].getContent(context);
		return html;
	},
	// Escape XML symbols - < > & ' ...
	xmlEscape : function(value) {
		var text = value ? value.toString() : "";
		/*for(var i in this._symbols ) {
			text = text.replace(i,this._symbols[i]);
		
		*/
		return text.escapeHTML();
	}
};

// Element node
E = function(tagname,attributes,childnodes) {
	this.tag = tagname;
	if (attributes) this.attrs = attributes;
	if(childnodes) this.childs = childnodes;
};

E.prototype = new JSNode();
E.prototype.getContent = function(context) {
	var html = "<"+this.tag;
	var inner = this.getInnerHTML(context);
	if (inner=='') this.isEmpty = true; else this.isEmpty=false;
	for(var i in this.attrs) {
		if (!this.attrs.hasOwnProperty(i)) {
			continue ;
		}

		var attrValue = this.attrs[i];
		
		if (typeof attrValue == "function")
			attrValue = attrValue.call(this, context);
		
		if (attrValue) 
			html += " "+(i=='className'?'class':i)+'="'+this.xmlEscape(attrValue)+'"';
	}
	if(inner == "" && JSNode.eltt[this.tag.toLowerCase()].empty) {
		html+= "/>";
	} else {
		html+= ">"+inner+"</"+this.tag+">";
	}
	return html;
};

// Escaped Text node
ET = function(text) {
	this.value = text;
};


//ET.prototype = new JSNode();
ET.prototype.getContent = function(context) {
  	var value = this.value;
  	if (typeof value=="function") value=value(context);
  	if (value && value.getContent) {
		value = value.getContent(context);
	}
	
	if (value) return value;
  
	return "";
};

// Text node
T = function(text) {
	this.value = text;
};

T.prototype = new JSNode();
T.prototype.getContent = function(context) {
  	var value = this.value;
  	if (typeof value=="function") value=value(context);
  		
	if (value) return this.xmlEscape(value);

	return "";
};

// Comment node
C = function(text) {
	this.value = text;
};

//C.prototype = new JSNode();
C.prototype.getContent = function(context) {
	return "<!--"+this.value+"-->";
};
  
// CDATA Section node.
D = function(text) {
	this.value = text;
};
  
//D.prototype = new JSNode();
D.prototype.getContent = function(context) {
	return "<![CDATA["+this.value+"]]>";
};

