fe7b5dcbcdcc

Merge with the MODI change.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 01 May 2010 00:19:01 -0400
parents 37f55dfd4e5f (current diff) 2b83293c583f (diff)
children 99a89bbb955a
branches/tags (none)
files

Changes

--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/media/js/utils/modi.js	Sat May 01 00:19:01 2010 -0400
@@ -0,0 +1,941 @@
+/********
+
+	Mouseover DOM Inspector
+	version 2.0.2
+	last rev: 05.12.2005
+
+	steve@slayeroffice.com
+
+	Thanks to Aaron Barker of zelph.com for his additions to v1.x.
+	
+	Should you modify/improve upon this, please let me know about it so that
+	I can update the version hosted on slayeroffice.
+	
+	PLEASE LEAVE THIS NOTICE IN TACT
+	
+TODO:
+	-- add identifiers to MODI created objects to prevent them from appearing during manual DOM walk
+	-- fix firstChild selections
+	-- fix outline reversion
+	- Replace outline's with an abs-pos DIV to emulate the outlines. (maybe)
+********/
+
+// prevent IE from making tons of requests to background images
+if(document.execCommand && document.all && !window.opera) document.execCommand("BackgroundImageCache",false,true);
+
+var d=document;
+var mObj,cssObj;
+var isActive = false;
+var activeObj = null;
+var pause = false;
+
+var treeIndex = 0;
+var clonedObj = null;
+var mDown = false;
+var offsetX,offsetY;
+
+
+if(d.all && !window.opera) {
+	var statusImg = new Array("gray.png","");
+} else {
+	var statusImg = new Array("gray.png","outline.png","");
+}
+var keyboardObjIndex = 0;
+var modiHiddenObjects = new Array();
+var modiFocused = false;
+if(d.contentType) {
+	var isAppXML = document.contentType.indexOf("application/xhtml") > -1;
+} else {
+	var isAppXML = false;
+}
+
+// default preferences
+var pref_showAttr = true;
+var pref_showDim = true;
+var pref_showParents = true;
+var pref_highlights = 0;
+var pref_freeze = true;
+var pref_backgroundHighlightColor = "#C0C0C0";
+var pref_childHighlightColor = "#FAFAFA";
+var pref_outlineColor = "#FF0000";
+var pref_outlineWidth = "2px";
+var pref_visible = true;
+var pref_alwaysTransparent = false;
+var pref_alwaysTransparentValue = 60;
+var pref_allDataListsCollapsed = false;
+var pref_showChildren = true;
+
+var oHighlightColor = pref_backgroundHighlightColor;
+var so_host = "http://slayeroffice.com/tools/modi/v2.0/";
+var so_lbl = new Array();
+
+// See: http://www.quirksmode.org/dom/getstyles.html
+function getStyle(obj,styleProp)
+{
+	if (obj.currentStyle)
+		var y = obj.currentStyle[styleProp];
+	else if (window.getComputedStyle)
+		var y = document.defaultView.getComputedStyle(obj,null).getPropertyValue(styleProp);
+	return y;
+}
+
+function so_init() {
+	try {
+		if(prefFile != "") {
+			nPrefs = d.getElementsByTagName("head")[0].appendChild(d.createElement("script"));
+			nPrefs.type = "text/javascript";
+			nPrefs.src = prefFile;
+			oHighlightColor = pref_backgroundHighlightColor;
+		}
+	} catch(err) { }
+	d.onmousemove = so_captureMouseMoveEvent;
+	d.onkeydown = so_captureKeyDownEvent;
+	window.onscroll = so_keepModiInView;
+	so_prepInputs();
+	
+	all = d.getElementsByTagName("*");
+	for(i=0;i<all.length;i++) {
+		if(all[i].tagName != "HTML" && all[i].tagName != "BODY" && all[i].tagName != "!") {
+		 	so_prepareObjForMODI(all[i]);
+		}
+	}
+
+	cssObj = d.getElementsByTagName("head")[0].appendChild(d.createElement("link"));
+	cssObj.type = "text/css";
+	cssObj.rel = "Stylesheet";
+	cssObj.href = so_host + "modi_v2.0.css";
+	cssObj.id = "modiCSS";
+	cssObj.xid = "modi";
+	
+	mObj = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));
+	mObj.id = "modiContainer";
+	mObj.xid = "modi";
+	mObj.style.visibility = pref_visible?"visible":"hidden";
+	mObj.onmouseover = function() { modiFocused = true; so_setOpacity(mObj,99); }
+	mObj.onmouseout = function() { modiFocused = false; }
+	
+	h2 = mObj.appendChild(d.createElement("h2"));
+	h2.appendChild(d.createTextNode("Mouse-over any element to begin."));
+	h2.id = "tmp_h2";
+}
+
+function so_prepInputs() {
+	txtInput = d.getElementsByTagName("input");
+	txtArea = d.getElementsByTagName("textarea");
+	for(i=0;i<txtInput.length;i++) {
+		if(txtInput[i].getAttribute("type")=="text" || txtInput[i].getAttribute("type") == "") {
+			txtInput[i].onfocus = function() { 
+				if(pause)return;
+				pause = true; 
+				// yeah, the innerHTML is cheating. at least i'm only reading, not writing :)
+				if(d.getElementById("so_h2").innerHTML.indexOf("paused")==-1)d.getElementById("so_h2").appendChild(d.createTextNode(" [paused for input focus]"));
+			}
+			txtInput[i].onblur = function() { 
+				pause = false; 
+			}
+		}
+	}
+	for(i=0;i<txtArea.length;i++) {
+		txtArea[i].onfocus = function() {
+			if(pause)return;
+			pause = true; 
+			if(d.getElementById("so_h2").innerHTML.indexOf("paused")==-1)d.getElementById("so_h2").appendChild(d.createTextNode(" [paused for input focus]"));
+		}
+		txtArea[i].onblur = function() { 
+			pause = false; 
+		}
+	}
+}
+
+function so_keepModiInView() {
+	winHeight = d.all && !window.opera?document.documentElement.clientHeight:window.innerHeight;
+	if(mObj.offsetHeight > winHeight) return;
+	if(mObj.offsetTop < _returnScrollDimensions(1)) {
+		mObj.style.top = _returnScrollDimensions(1)+"px";
+	}
+	
+	if(mObj.offsetTop+mObj.offsetHeight > winHeight + _returnScrollDimensions(1)) {
+		mObj.style.top = (_returnScrollDimensions(1) + winHeight) - mObj.offsetHeight + "px";
+	}
+}
+
+function so_captureMouseMoveEvent(e) {
+	x=d.all?window.event.clientX:e.clientX;
+	y=d.all?window.event.clientY:e.pageY;
+
+	if(pause || pref_freeze) {
+		if(mDown) {
+			x-=offsetX;
+			y-=offsetY;
+			if(mDown) {
+				mObj.style.top = y+"px";
+				mObj.style.left = x+"px";
+			}
+			return;
+		}
+	}
+		
+	if(activeObj == null && !modiFocused) {
+		so_setOpacity(mObj,40);
+	} else {
+		so_setOpacity(mObj,99);
+	}
+	
+	if(pref_freeze) {
+		so_keepModiInView();
+		return;
+	}
+	
+	if(d.all && !window.opera) {
+		x+=_returnScrollDimensions(0);
+		y+=_returnScrollDimensions(1);
+	}
+
+	if(x+mObj.offsetWidth > d.getElementsByTagName("body")[0].offsetWidth) {
+		mObj.style.left = (x-mObj.offsetWidth)+"px";
+	} else {
+		mObj.style.left = (x+15) + "px";
+	}
+	if(mObj.offsetLeft < 0) mObj.style.left = "0px"
+	
+	yOffset = _returnScrollDimensions(1);
+	
+	if(y-mObj.offsetHeight<=0 || (y-mObj.offsetHeight)<yOffset) {
+		mObj.style.top=(y+15)+"px";
+	} else {
+		mObj.style.top = (y-mObj.offsetHeight) + "px";
+	}
+
+}
+
+function _returnScrollDimensions(which) {
+	
+	if(which) {
+		if(d.body.scrollTop != 0)return d.body.scrollTop;
+		if(d.documentElement.scrollTop != 0)return d.documentElement.scrollTop;
+	} else {
+		if(d.body.scrollLeft != 0)return d.body.scrollTop;
+		if(d.documentElement.scrollLeft != 0)return d.documentElement.scrollLeft;
+	}
+	return 0;
+}	
+	
+function so_setObjHighlight(obj) {
+	switch(pref_highlights) {
+		case 0:
+			obj.style.backgroundColor = pref_backgroundHighlightColor;
+			break;
+		case 1:
+			//activeObj.prevOutline = 
+			outline = pref_outlineWidth + " solid " + pref_outlineColor;
+			obj.style.MozOutline = outline;
+			obj.style.outline = outline;
+			break;
+		case 2:
+			return;
+			break;
+	}
+}
+
+function so_unsetObjHighlight(obj) {
+	if(!obj)return;
+	switch(pref_highlights) {
+		case 0:
+			if(obj.randomBGColor == null) {
+				obj.style.backgroundColor = obj.so_prevBGColor;
+			} else {
+				obj.style.backgroundColor = obj.randomBGColor;
+			}
+			break;
+		case 1:
+			obj.style.MozOutline = "none";
+			obj.style.outline = "none";
+			break;
+		case 2:
+			return;
+			break;
+	}
+}
+
+function so_captureKeyDownEvent(e) {
+	keyCode = d.all?window.event.keyCode:e.keyCode;
+	if(d.getElementById("htmlView")){ 
+		 switch(keyCode) {
+		 	case 27:
+				so_closeEditWindow();
+				break;
+			case 13:
+				so_applyInnerHTML(d.getElementById("htmlViewText").value,activeObj);
+				break;
+		}
+		return;
+	}
+	
+	if(pause) {
+		if(keyCode == 80) {
+			pause=false;
+			return;
+		}
+	}
+	switch(keyCode) {
+		case 27:
+			so_cleanUp();
+			break;
+		case 49:
+			so_snapWindow(0);
+			break;
+		case 50:
+			//so_snapWindow(1);
+			break;
+		case 65:
+			so_cloneObject();
+			break;
+		case 66:
+			if(pause) return;
+			so_unsetObjHighlight(activeObj);
+			pref_highlights++;
+			if(d.all && !window.opera) {
+				maxValue = 1;
+			} else {
+				maxValue = 2;
+			}
+			if(pref_highlights>maxValue) pref_highlights = 0;
+			if(activeObj) so_setObjHighlight(activeObj);
+			d.getElementById("so_h2").style.backgroundImage = "url(" + so_host +""+ statusImg[pref_highlights] + ")";
+			break;
+		case 67:
+			so_randomColor();
+			break;
+		case 68:
+			if(pause)return;
+			pref_visible = pref_visible?false:true;
+			mObj.style.visibility = pref_visible?"visible":"hidden";
+			break;
+		case 69:
+			so_removeWidth();
+			break;
+		case 70:
+			if(pause)return;
+			pref_freeze = pref_freeze?false:true;
+			if(!pref_freeze)mDown = false;
+			break;
+		case 71:
+			so_changeListState();
+			break;
+		case 72:
+			so_hideObject();
+			break;
+		case 74:
+			so_showModiHiddenObjects();
+			break;
+		case 75:
+			so_removeLables();
+			break;
+		case 76:
+			so_labelObj(activeObj);
+			break;
+		case 78:
+			so_showFirstChild();
+			break;
+		case 79:
+			if(activeObj) so_outlineObj(activeObj);
+			break;
+		case 80:
+			if(!activeObj) return;
+			pause = pause?false:true;
+			if(pause)d.getElementById("so_h2").appendChild(d.createTextNode(" [paused]"));
+			so_setOpacity(mObj,99);
+			break;
+		case 82:
+			so_removeObj();
+			break;
+		case 83:
+			so_insertClonedObj();
+			break;
+		case 84:
+			if(d.getElementsByTagName("*")[treeIndex].xid == "modi") {
+				do {
+					treeIndex++;
+					if(treeIndex>=d.getElementsByTagName("*").length)treeIndex = 0;
+				} while(d.getElementsByTagName("*")[treeIndex].xid == "modi");
+			}
+			so_walkDOMTree();
+			treeIndex++;
+			break;
+		case 85:
+				pref_alwaysTransparent = pref_alwaysTransparent?false:true;
+				so_setOpacity(mObj,pref_alwaysTransparent?60:99);
+				break;
+		case 86:
+			so_createEditWindow(activeObj);
+			break;
+		case 87:
+			so_showParentObj();
+			break;
+		case 89:
+			if(d.getElementsByTagName("*")[treeIndex].xid == "modi") {
+				do {
+					treeIndex--;
+					if(treeIndex<0)treeIndex = d.getElementsByTagName("*").length-1;
+				} while(d.getElementsByTagName("*")[treeIndex].xid == "modi");
+			}
+			so_walkDOMTree();
+			treeIndex--;
+			break;
+	}
+}
+
+function so_snapWindow(corner) {
+	if(!pref_freeze)pref_freeze = true;
+	switch(corner) {
+		case 0:
+			y = _returnScrollDimensions(1);
+			mObj.style.left = "10px";
+			mObj.style.top = y+"px";
+			break;
+		case 1:
+			
+			break;
+	}
+}
+
+function so_changeListState() {
+	if(!pref_allDataListsCollapsed) {
+ 		d.getElementById("attributeData").style.display = "none";
+ 		d.getElementById("parentData").style.display = "none";
+ 		d.getElementById("dimensionData").style.display = "none";
+ 		d.getElementById("childData").style.display = "none";
+ 		pref_showAttr = false; pref_showDim = false; pref_showParents = false; pref_showChildren = false;
+ 		pref_allDataListsCollapsed = true;
+ 	} else {
+ 		d.getElementById("attributeData").style.display = "block";
+ 		d.getElementById("parentData").style.display = "block";
+ 		d.getElementById("dimensionData").style.display = "block";
+ 		d.getElementById("childData").style.display = "block";
+ 		pref_showAttr = true; pref_showDim = true; pref_showParents = true; pref_showChildren = true;
+ 		pref_allDataListsCollapsed = false;
+ 	}
+}
+
+function so_removeLables() {
+	for(i=0;i<so_lbl.length;i++) {
+		try {
+			d.getElementsByTagName("body")[0].removeChild(so_lbl[i]);
+		} catch(err) { }
+	}
+	so_lbl = new Array();
+}
+
+function so_createEditWindow(obj) {
+	if(!activeObj)return;
+	if(pause)return;
+	pause = true;
+	if(d.all && !window.opera) {
+		if(mObj.offsetWidth<315) mObj.style.width = "318px";
+		if(mObj.offsetHeight<215) mObj.style.height = "218px";
+	}
+	editWindow = mObj.appendChild(d.createElement("div"));
+	editWindow.id = "htmlView";
+		
+	h3 = editWindow.appendChild(d.createElement("h3"));
+	h3.appendChild(d.createTextNode("HTML Source for " + obj.tagName.toLowerCase()));		
+
+	txt = editWindow.appendChild(d.createElement("textarea"));
+	txt.setAttribute("id","htmlViewText")
+	txt.value = obj.innerHTML;
+	editWindow.appendChild(d.createElement("br"));
+		
+	a = editWindow.appendChild(d.createElement("a"));
+	a.onclick = so_closeEditWindow;
+	a.className = "btn";
+	if(!isAppXML) {
+		a.appendChild(d.createTextNode("Cancel"));
+	} else {
+		a.appendChild(d.createTextNode("Close"));
+	}
+	if(!isAppXML) {
+		a = editWindow.appendChild(d.createElement("a"));
+		a.onclick = function() { so_applyInnerHTML(d.getElementById("htmlViewText").value,obj); }
+		a.className = "btn";
+		a.appendChild(d.createTextNode("Apply"));
+	}
+}
+
+function so_applyInnerHTML(mHTML,obj) {
+	if(isAppXML) {
+		so_closeEditWindow();
+		return;
+	}
+	try {
+		obj.innerHTML = mHTML;
+		so_closeEditWindow();
+	
+		all = obj.getElementsByTagName("*");
+		for(i=0;i<all.length;i++) {
+			so_prepareObjForMODI(all[i]);
+		}
+	} catch(err) { 
+		alert("An error occured while applying the innerHTML of this object. The most likely culprit is that this site is serving its content as application/xhtml+xml.\nError text was:\n\n" + err.message);
+		so_closeEditWindow();
+	}
+}
+
+
+function so_prepareObjForMODI(dObj) {
+	//dObj.onmouseover = so_showObjInfo;
+	//dObj.onmouseout = so_hideObjInfo;
+	dObj.addEventListener?dObj.addEventListener("mouseover",so_showObjInfo,false):dObj.onmouseover = so_showObjInfo;//dObj.attachEvent("onmouseover",so_showObjInfo);
+	dObj.addEventListener?dObj.addEventListener("mouseout",so_hideObjInfo,false):dObj.onmouseout = so_hideObjInfo;//dObj.attachEvent("onmouseout",so_hideObjInfo);
+	dObj.so_prevBGColor = all[i].style.backgroundColor;
+	dObj.so_prevWidth = all[i].offsetWidth;
+	dObj.so_prevTitle = all[i].getAttribute("title");
+}
+
+function so_closeEditWindow() {
+	document.getElementById("modiContainer").removeChild(document.getElementById("htmlView")) 
+	so_unsetObjHighlight(activeObj);
+	activeObj=null;
+	pause = false;
+}
+
+function so_outlineObj(obj) {
+	if(pause)return;
+	outline = pref_outlineWidth + " solid " + pref_outlineColor;
+	obj.style.MozOutline = outline;
+	obj.style.outline = outline;
+}
+
+function so_setOpacity(obj,op) {
+	if(pref_alwaysTransparent) {
+		op = pref_alwaysTransparentValue;
+	}
+	if(!d.all)op/=100;
+	obj.style.opacity = op;
+	obj.style.MozOpacity = op;
+	obj.style.filter = "alpha(opacity=" + op + ")";
+}
+
+function so_showObjInfo() {
+	if(pause)return;
+	if(isActive)return;
+	//if(pref_visible)mObj.style.display = "block";
+	activeObj = this;
+	isActive = true;
+	so_buildDataDisplay(this);
+	so_setOpacity(mObj,99);
+	so_setObjHighlight(this);
+
+}
+
+function so_hideObjInfo() {
+	if(pause)return;
+	try {
+		so_unsetObjHighlight(this);
+	} catch(err) { }
+	isActive = false;
+	activeObj = null;
+}
+
+function so_buildDataDisplay(obj) {
+	if(pause)return;
+	if(d.getElementById("tmp_h2")) mObj.removeChild(d.getElementById("tmp_h2"));
+	if(d.getElementById("sContainer")) mObj.removeChild(d.getElementById("sContainer"));
+	
+	if(!pref_visible) {
+		ttl = obj.tagName.toLowerCase();
+		if(obj.id) ttl+= " id=\"" + obj.id + "\"";
+		if(obj.className) ttl+= " class=\""+obj.className+"\"";
+		obj.setAttribute("title",ttl);
+		return;
+	}
+	
+	sObj = mObj.appendChild(d.createElement("div"));
+	sObj.setAttribute("id","sContainer");
+
+	h2 = sObj.appendChild(d.createElement("h2"));
+	h2.appendChild(d.createTextNode(obj.tagName.toLowerCase()));
+	if(pause)h2.appendChild(d.createTextNode(" [paused]"));
+	h2.onmousedown =  so_captureOffset;
+	h2.onmouseup = function() {	mDown = false; }
+	h2.id = "so_h2";
+	h2.style.backgroundImage = "url("+so_host+""+ statusImg[pref_highlights] + ")";
+	
+	// attributes
+	h3 = sObj.appendChild(d.createElement("h3"));
+	h3.appendChild(d.createTextNode("attributes"));
+	h3.className = pref_showAttr?"h3_on":"h3_off";
+	h3.onclick = function() { 
+		pref_showAttr = pref_showAttr?false:true;
+		this.className = pref_showAttr?"h3_on":"h3_off";
+		document.getElementById("attributeData").style.display = pref_showAttr?"block":"none"; 
+	}
+	
+	ul = sObj.appendChild(d.createElement("ul"));
+	ul.setAttribute("id","attributeData");
+	ul.style.display = pref_showAttr?"block":"none";
+	
+	attrCount = 0;
+	for(i=0;i<obj.attributes.length;i++) {
+		if(obj.attributes[i].specified) {
+			if(obj.attributes[i].value && obj.attributes[i].name.indexOf("so_")==-1) {
+				attrCount++;
+				li = ul.appendChild(d.createElement("li"));
+				val = so_wrapAttributeValue(obj.attributes[i].value);
+				li.appendChild(d.createTextNode(obj.attributes[i].name.toLowerCase() + " : " + val));
+			}
+		}
+	}
+	
+	if(attrCount == 0) {
+		li = ul.appendChild(d.createElement("li"));
+		li.appendChild(d.createTextNode("None Specified."));
+	}
+
+	// dimensions
+	h3 = sObj.appendChild(d.createElement("h3"));
+	h3.appendChild(d.createTextNode("dimensions"));
+	h3.className = pref_showDim?"h3_on":"h3_off";
+	h3.onclick = function() {
+		pref_showDim = pref_showDim?false:true;
+		this.className = pref_showDim?"h3_on":"h3_off";
+		document.getElementById("dimensionData").style.display = pref_showDim?"block":"none";
+	}
+	ul = sObj.appendChild(d.createElement("ul"));
+	ul.setAttribute("id","dimensionData");
+	ul.style.display = pref_showDim?"block":"none";
+	
+	li = ul.appendChild(d.createElement("li"));
+	li.appendChild(d.createTextNode("Font Size : " + getStyle(obj, 'font-size')));
+	li = ul.appendChild(d.createElement("li"));
+	li.appendChild(d.createTextNode("Width : " + obj.offsetWidth + "px"));
+	li = ul.appendChild(d.createElement("li"));
+	li.appendChild(d.createTextNode("Height : " + obj.offsetHeight + "px"));
+	li = ul.appendChild(d.createElement("li"));
+	li.appendChild(d.createTextNode("Top : " + so_findPosition(obj,0) + "px"));
+	li = ul.appendChild(d.createElement("li"));
+	li.appendChild(d.createTextNode("Left : " + so_findPosition(obj,1) + "px"));
+
+	// parents
+	h3 = sObj.appendChild(d.createElement("h3"));
+	h3.appendChild(d.createTextNode("parent structure"));
+	h3.className = pref_showParents?"h3_on":"h3_off";
+	h3.onclick = function() {
+		pref_showParents = pref_showParents?false:true;
+		this.className = pref_showParents?"h3_on":"h3_off";
+		document.getElementById("parentData").style.display = pref_showParents?"block":"none";
+	}
+	so_getParents(obj,sObj);
+
+	// children
+	if(obj.childNodes.length) {
+		h3 = sObj.appendChild(d.createElement("h3"));
+		h3.appendChild(d.createTextNode("children"));
+		h3.className = pref_showChildren?"h3_on":"h3_off";
+		h3.onclick = function() {
+			pref_showChildren = pref_showChildren?false:true;
+			this.className = pref_showChildren?"h3_on":"h3_off";
+			document.getElementById("childData").style.display = pref_showChildren?"block":"none";
+		}
+		
+		ul = sObj.appendChild(d.createElement("ul"));
+		ul.setAttribute("id","childData");
+		ul.style.display = pref_showChildren?"block":"none";
+		
+		for(i=0;i<obj.childNodes.length;i++) {
+			li = ul.appendChild(d.createElement("li"));
+			if(obj.childNodes[i].nodeType == 1) {
+				li.appendChild(d.createTextNode(obj.childNodes[i].nodeName.toLowerCase()));
+				li.className = "parentStructure";
+				li.myObj = obj.childNodes[i];
+				li.onmouseover = function() {
+					pref_backgroundHighlightColor = pref_childHighlightColor;
+					this.myObj.so_prevBGColor = this.myObj.style.backgroundColor;
+					so_setObjHighlight(this.myObj);
+				}
+				li.onmouseout = function() {
+					pref_backgroundHighlightColor = oHighlightColor;
+					so_unsetObjHighlight(this.myObj);
+				}
+				if(obj.childNodes[i].getAttribute("id")) li.appendChild(d.createTextNode(" id=\"" + obj.childNodes[i].getAttribute("id") + "\""));
+				if(obj.childNodes[i].className) li.appendChild(d.createTextNode(" class=\"" + obj.childNodes[i].className + "\""));
+			} else {
+				nodes = new Array("","Element Node","Attribute Node","#text","CDATA Node","Entity Reference Node","Entity Node","Processing Instruction Node","Comment Node","Document Node","Document Fragment Node","Notation Node");
+				li.appendChild(d.createTextNode(nodes[obj.childNodes[i].nodeType]));
+				li.setAttribute("title",obj.childNodes[i].nodeValue);
+			}
+		}
+	}
+	
+	// credits
+	div = sObj.appendChild(d.createElement("div"));
+	div.setAttribute("id","credits");
+	b = div.appendChild(d.createElement("b"));
+	//b.appendChild(d.createTextNode("[esc] to quit | "));
+	a = d.createElement("a"); 
+	a.setAttribute("href","javascript:so_cleanUp();");
+	a.appendChild(d.createTextNode("[esc] to quit"));
+	b.appendChild(a); 
+	b.appendChild(d.createTextNode(" | "));
+	
+	a = b.appendChild(d.createElement("a"));
+	a.setAttribute("title","Help!");
+	a.setAttribute("href",so_host + "modi_help.html");
+	a.setAttribute("target","_blank");
+	a.appendChild(d.createTextNode("help documentation"));
+	
+	div.appendChild(d.createElement("br"));
+	div.appendChild(d.createTextNode("Mouseover DOM Inspector"));
+	div.appendChild(d.createElement("br"));
+	div.appendChild(d.createTextNode("version 2.0.2 (05.11.2005)"));
+	div.appendChild(d.createElement("br"));
+	div.appendChild(d.createTextNode("slayeroffice.com"));
+	div.appendChild(d.createElement("br"));
+
+	so_tagAsMODI();
+	
+	if(d.all && !window.opera) {
+		// make up for IE's lack of max-width support.
+		if(mObj.offsetWidth>400) mObj.style.width="400px";
+	}
+	
+	function so_wrapAttributeValue(attrValue) {
+		// IE has a word-break css property. no need to do anything if this is IE
+		if(d.all && !window.opera) return attrValue;
+		// attribute value has a space in it. return.
+		if(attrValue.indexOf(" ")>-1) return attrValue;
+		for(ee=0;ee<attrValue.length;ee++) if(ee%50==0) attrValue = attrValue.substring(0,ee) + " " + attrValue.substring(ee,attrValue.length);
+		return attrValue;
+	}
+	
+}
+
+function so_getParents(curNode,dataContainer){
+	parents = new Array();
+	parentObjRef = new Array();
+	while(curNode.parentNode){
+		parents[parents.length] = curNode.tagName.toLowerCase();
+		parentObjRef[parentObjRef.length] = curNode;
+		curNode = curNode.parentNode;
+	}
+
+	ul = dataContainer.appendChild(d.createElement("ul"));
+	ul.setAttribute("id","parentData");
+	ul.style.display = pref_showParents?"block":"none";
+	
+	for(i=parents.length-1; i>0; i--){
+		li = ul.appendChild(d.createElement("li"));
+		li.appendChild(d.createTextNode(parents[i]));
+		if(parentObjRef[i].getAttribute("id")) li.appendChild(d.createTextNode(" id=\"" + parentObjRef[i].getAttribute("id") +"\""));
+		if(parentObjRef[i].className) li.appendChild(d.createTextNode(" class=\"" + parentObjRef[i].className + "\""));
+		
+		li.myObj = parentObjRef[i];
+		li.className = "parentStructure";
+		li.onmouseover = function() {
+			this.myObj.so_prevBGColor = this.myObj.style.backgroundColor;
+			so_setObjHighlight(this.myObj);
+		}
+		li.onmouseout = function() {
+			so_unsetObjHighlight(this.myObj);
+		}
+	}
+
+}
+
+function so_showParentObj() {
+	if(pause)return;
+	so_unsetObjHighlight(activeObj);
+	if(activeObj.parentNode && activeObj.tagName != "HTML") {
+		activeObj = activeObj.parentNode
+		activeObj.so_prevBGColor = activeObj.style.backgroundColor;
+		so_setObjHighlight(activeObj);
+		so_buildDataDisplay(activeObj);
+	}
+}
+
+function so_labelObj(obj) {
+	if(pause || !activeObj) return;
+	lblText = obj.tagName.toLowerCase();
+	len = so_lbl.length;
+	so_lbl[len] = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));
+	so_lbl[len].appendChild(d.createTextNode(lblText));
+	so_lbl[len].className = "modi_label";
+	so_lbl[len].style.top = so_findPosition(obj,0) + "px";
+	so_lbl[len].style.left = so_findPosition(obj,1) + "px";
+	so_lbl[len].onclick = function() {
+		this.parentNode.removeChild(this);
+	}
+}
+
+function so_removeObj() {
+	if(pause)return;
+	activeObj.parentNode.removeChild(activeObj);
+}
+
+function so_cleanUp() {
+	d.getElementsByTagName("head")[0].removeChild(d.getElementById("modiCSS"));
+	d.getElementsByTagName("body")[0].removeChild(d.getElementById("modiContainer"));
+	// id is "modi" if invoked on its own, "sss" if invoked from the favelet suite
+	if(d.getElementById("modi")) {
+		d.getElementsByTagName("body")[0].removeChild(d.getElementById("modi"));
+	} else {
+		d.getElementsByTagName("body")[0].removeChild(d.getElementById("sss"));
+	}
+	d.onkeydown = null;
+	d.onmousemove = null;
+
+	all = d.getElementsByTagName("*");
+	for(i=0;i<all.length;i++) {
+		//all[i].onmouseover = null;
+		//all[i].onmouseout = null;
+		all[i].removeEventListener?all[i].removeEventListener("mouseover",so_showObjInfo,false):all[i].onmouseover = null;//all[i].detachEvent("onmouseover",so_showObjInfo);
+		all[i].removeEventListener?all[i].removeEventListener("mouseout",so_hideObjInfo,false):all[i].onmouseout = null;//all[i].detachEvent("onmouseout",so_hideObjInfo);
+		all[i].style.backgroundColor = all[i].so_prevBGColor;
+		all[i].so_prevBGColor = null;
+		if(all[i].randomBGColor)all[i].randomBGColor = null;
+		all[i].setAttribute("title",all[i].so_prevTitle); 
+		all[i].style.outline = "none";
+		all[i].style.MozOutline = "none";
+	}
+
+	if(activeObj)activeObj.style.backgroundColor = activeObj.so_prevBGColor;
+}
+
+function so_randomColor() {
+	if(pause)return;
+	if(activeObj == null) return;
+	if(!activeObj.randomBGColor) {
+		r = Math.floor(Math.random() * 256);
+		g = Math.floor(Math.random() * 256);
+		b = Math.floor(Math.random() * 256);
+		rgb = "rgb(" + r + "," + g + "," + b + ")";
+		if(activeObj) {
+			activeObj.style.backgroundColor = rgb;
+			activeObj.randomBGColor = rgb;
+		}
+	} else {
+		if(activeObj.style.backgroundColor == activeObj.so_prevBGColor) {
+			activeObj.style.backgroundColor = activeObj.randomBGColor;
+		} else {
+			activeObj.style.backgroundColor = activeObj.so_prevBGColor;
+			activeObj.randomBGColor = activeObj.so_prevBGColor;
+		}
+	}
+}
+
+function so_walkDOMTree() {
+	if(pause)return;
+	if(activeObj) so_unsetObjHighlight(activeObj);
+	if(treeIndex>=d.getElementsByTagName("*").length) treeIndex = 0;
+	if(treeIndex<0) treeIndex = d.getElementsByTagName("*").length - 1;
+	
+	activeObj = d.getElementsByTagName("*")[treeIndex];
+	if(d.all && !window.opera) {
+		if(activeObj.tagName == "!") {
+			treeIndex++;
+			activeObj = d.getElementsByTagName("*")[treeIndex];
+		}
+	}
+	so_buildDataDisplay(activeObj);
+	so_setObjHighlight(activeObj);
+	if(!pref_freeze) {
+		mObj.style.top = so_findPosition(activeObj,0)+15 + "px";
+		mObj.style.left = so_findPosition(activeObj,1)+15 + "px";
+	}
+}
+
+function so_tagAsMODI() {
+	modiChildren = mObj.getElementsByTagName("*");
+	for(m=0;m<modiChildren.length;m++) modiChildren[m].xid = "modi";
+}
+	
+function so_findPosition(obj,pType) {
+	cur = 0;
+	if(obj.offsetParent) {		
+		while(obj.offsetParent) {
+			cur+=pType?obj.offsetLeft:obj.offsetTop;
+			obj = obj.offsetParent;
+		}
+	}
+	return cur;
+}
+
+function so_cloneObject() {
+	if(pause)return;
+	if(!activeObj)return;
+	clonedObj = activeObj.cloneNode(true);
+}
+
+function so_insertClonedObj() {
+	if(pause)return;
+	if(!activeObj || !clonedObj)return;
+	activeObj.appendChild(clonedObj);
+	so_prepareObjForMODI(clonedObj);
+	
+	c = clonedObj.getElementsByTagName("*");
+	for(i=0;i<c.length;i++) so_prepareObjForMODI(c[i]);
+}
+
+function so_captureOffset(e) {
+	mDown = true;
+	nx = parseInt(mObj.offsetLeft);
+	ny = parseInt(mObj.offsetTop);
+
+	if(d.all) {
+		offsetX=window.event.clientX - nx;
+		offsetY=window.event.clientY - ny;
+	} else {
+		offsetX = e.pageX - nx;
+		offsetY = e.pageY - ny;
+	}
+}
+
+function so_hideObject() {
+	if(pause || !activeObj)return;
+	if(activeObj.style.visibility == "" || activeObj.style.visibility == "visible") {
+		modiHiddenObjects[modiHiddenObjects.length] = activeObj;
+		activeObj.style.visibility = "hidden"
+		activeObj = null;
+	} 
+}
+
+function so_showModiHiddenObjects() {
+if(pause)return;
+	for(w=0;w<modiHiddenObjects.length;w++) {
+		modiHiddenObjects[w].style.visibility = "visible";
+	}
+	modiHiddenObjects = new Array();
+}
+
+function so_removeWidth() {
+	if(pause) return;
+	if(!activeObj) return;
+
+	if(activeObj.so_prevWidth != activeObj.offsetWidth) {
+		activeObj.style.width = activeObj.so_prevWidth + "px";
+		activeObj.so_prevWidth = activeObj.offsetWidth;
+	} else {
+		activeObj.style.width = "auto";
+	}
+}
+
+function so_showFirstChild() {
+	if(pause)return;
+	if(!activeObj) return;
+	n = activeObj.childNodes;
+	if(!n.length)return;
+	m=null;
+	for(k=0;k<n.length;k++) {
+		if(n[k].nodeType == 1) {
+			m = n[k];
+			break;
+		}
+	}
+	
+	if(!m) return;
+	so_unsetObjHighlight(activeObj);
+	activeObj = m;
+	so_buildDataDisplay(activeObj);
+}
+
+
+so_init();
\ No newline at end of file