
/*

	Script to convert IE document to valid XHTML

	Note this can be a slow process on a big page

	Jason 10 - 3 - 2003


	- function now records every node it process and records next node with already processed nodes thereby avoiding duplication of nodes


*/

	// Add item to array then return index
	if (!new Array().push) {
		Array.prototype.push = function() {
			for (var i = 0; i < arguments.length; i ++) this[this.length] = arguments[i];
			return this.length;
		}
	}

	// Return index of given object
	Array.prototype.indexOf = function(object){
		for(var i = 0; i< this.length ; i++)
			if(this[i] == object)
				return i
		return -1
	}

	var _checkOnceArray = []

	function convertToXML(el,node,level,_sep){
		// Clear array
		if (level == 0) _checkOnceArray = []

		// Check that node has not already been processed
		if(_checkOnceArray.indexOf(node) == -1){
			// Add node to processed list
			_checkOnceArray.push(node)

			// Sep formats the XML using sep as a spacer
			var sep = _sep || ''
			if(sep != '') sep = '\n'+ sep.repeat(level)

			var s = new BigString()
			var name = node.nodeName.toLowerCase();
			var value = false
			//switch strong to bold
			if(name == 'strong') name = 'b'

			//only if tag is not a misplaced end tag
			/*
			if(name.charAt(0) == '/')
				return ''
			*/
			//alert(name+" "+node.nodeType)
			switch (node.nodeType) {
				case 1:
					// IE5.0 and IE5.5 are weird
					if (name == "!") {	s.add(node.text); break; }

					// This node is an Element
					if(name!='a' && name!='em' )
						s.add('\n<' + name  )
					else
						s.add('<' + name  )

					// attributes
					var attrs = node.attributes;
					var l = attrs.length;

					for (var i = 0; i < l; i++) {
						if (attrs[i].specified) {
							switch(attrs[i].nodeName){

								// Attribute type is part of DOM 3 :(
								case "onsubmit":		case "onclick":			case "onblur"  :
								case "ondblclick" :		case "onkeydown"  :		case "onkeypress"  :
								case "onkeyup" :		case "onmousedown"  :	case "onmousemove"  :
								case "onmouseout" :		case "onmouseover"  :	case "onmouseup" :
								case "onfocus" :		case "onchange" :		case "for" :
									s.add(' ' + attrs[i].nodeName + '="' + attrs[i].value + '"');
									break
								case "class":
									s.add(' ' + attrs[i].nodeName + '="' + node.className + '"');
									break
								case "style":
									s.add(' style="' + (node.style.cssText) + '"');
									break
								case "src":
									// Fix image locations
									s.add(' src="' + fixURL(el,node.href || node.src) + '"');
									break
								case "href":
									// Fix link paths
									s.add(' href="' + fixURL(el,node.href) + '"');
									break
									// Form encoding
								case "encType":
									s.add(' enctype="' + node.enctype + '"')
									break;
									//Name
								case "name": 
									s.add(' name="' + node.name + '"')
								break;
								case "type":
								default :
									if(attrs[i].nodeName == 'value') value = true
									s.add(' '+ attrs[i].nodeName + '="' + node.getAttribute(attrs[i].nodeName) + '"');
									break;

							}
						}
					}
					// SPECIAL CASES ////////////////////////////////////////////
					
					if(name == 'script'){
						// ensure script has CDATA tags

						var cdataStart = '<![CDA' + 'TA[';
						var cdataEnd =  '//]' + ']>'
						
						if(node.innerHTML.indexOf('<![CDA' + 'TA[') != -1){


							s.add('>\n//' + cdataStart +'\n'+ node.innerHTML.split(cdataStart)[1].split(cdataEnd)[0]  +'\n'+ cdataEnd + '</' + name + '>');

						}
						else

							s.add('>\n//<![CDA' + 'TA[\n' + node.innerHTML + '\n//]' + ']>\n</' + name + '>');


						break;
					}else if(name == "area"){// Area map fix shape and coords
						s.add(' shape="' + node.shape + '"');
						s.add(' coords="' + node.coords + '"');

					}else if(node.selected)
						s.add(' selected="selected"');

					// Check box selected
					else if(node.checked)
						s.add(' checked="checked"');

					// Text area value
					else if(node.type == 'textarea'){
						s.add('>'+ node.value +'</textarea>');
						break;
					}
					
					
					
					// Other
					/*
					}else if(node.value && !value)
						s.add(' value="'+ node.value +'"');
					*/
					//put it out of the if-else above because radio button still has value even it is default checked.
					if(node.value && !value)
						s.add(' value="'+ node.value +'"');
					///////////////////////////////////////////////////////////




					// Child Nodes
					if ( node.canHaveChildren || node.hasChildNodes() ){
						// end start tag
						s.add('>')
					// force empty table cells to display
					if (node.tagName=='TD' && (node.innerHTML=="" ||node.innerHTML==" ")) {
						s.add ("<br />")
				}
						// Process Children
						for(var i = 0; i <  node.childNodes.length; i++){
							s.add ( convertToXML(el, node.childNodes[i], level+1,'') )
						}

						// add end tag
						//s.add(sep +'</' + name + '>');
						//if(name=='a')
							s.add('</' + name + '>');
						/*
						else
							s.add('</' + name + '>\n');
						*/
						break;
					
					}else if(name == 'iframe'){
					//Stops XCM from stripping end iframe tag.
						s.add(' ></iframe>')
					}else if(name == 'param'){
					//Stops XCM from stripping end param tag.
						s.add(' ></param>')
					}else if(name == '/embed' || name == 'embed'){
					//embed object
						//s.add(' ></embed>')
						s.add('>')
					}else if(name != 'embed'){
						s.add(' />')
					}
					break;

				case 3:
				// This is a Text Node
					if(node.nodeValue && node.nodeValue != ' ') {
						var text = String(node.nodeValue);
						text = text.replace(/&/g, '&amp;');
						var EntitieArray = ['8482','256','274','298','332','362','257','275','299','333','363','153','169','174','163','165','8364','176','224','8212','8216','8217','8220','8221','233']
						text = RE_replaceEntities(text, EntitieArray)
						s.add( sep + text.replace(/>/g, '&gt;').replace(/</g, '&lt;' ) );
					}
					break;

				case 4:
				// This is a CDATA node
					s.add('<![CDA' + 'TA[\n' + node.nodeValue + '\n]' + ']>');
					break;

			}
				

			return s.toString()
		}
			return ''
	}


	function RE_replaceEntities(text, a ){
		var i;
		var re
		for(i=0;i<a.length;i++){
		 	re = new RegExp(String.fromCharCode(a[i]),'g');
		 	text = text.replace(re,'&#' + a[i] +';')
		}
		return text
	}
