Rosetta Code:Per-Code Example Buttonbar: Difference between revisions

From Rosetta Code
Content added Content deleted
(Adding new page)
 
(Fixed bug where line break tags further down in the document tree were not converted to line breaks for use with Codepad)
Line 129: Line 129:
return outText;
return outText;
} break;
} break;
default:
case "":
{
{
//no tag name
//probably just text
outText += (preEl.childNodes[c].textContent ? preEl.childNodes[c].textContent : (preEl.childNodes[c].innerText ? preEl.childNodes[c].innerText : preEl.childNodes[c].data));
outText += (preEl.childNodes[c].textContent ? preEl.childNodes[c].textContent : (preEl.childNodes[c].innerText ? preEl.childNodes[c].innerText : preEl.childNodes[c].data));
} break;
default:
{
outText += ButtonBarGetText(preEl.childNodes[c]);
}
}
}
}

Revision as of 12:07, 13 July 2010

<lang javascript> /*======================================== This comparison script was written by Tyrok1, and has been tested on IE 7, IE 8, Fx 3.6.3, and Fe 5.0.380. ========================================*/

//define the relationship between the CSS classes and the language names var buttonBarCodepadLanguages = [ { cssClass: "c", padName: "C" }, { cssClass: "cpp", padName: "C++" }, { cssClass: "d", padName: "D" }, { cssClass: "haskell", padName: "Haskell" }, { cssClass: "lua", padName: "Lua" }, { cssClass: "ocaml", padName: "OCaml" }, { cssClass: "php", padName: "PHP" }, { cssClass: "perl", padName: "Perl" }, { cssClass: "python", padName: "Python" }, { cssClass: "ruby", padName: "Ruby" }, { cssClass: "scheme", padName: "Scheme" }, { cssClass: "tcl", padName: "Tcl" } ];

function AddHandler(el, handlerType, func) { //add an event handler in a more cross-browser way if(el.addEventListener) { el.addEventListener(handlerType, func, false); } else if(el.attachEvent) { el.attachEvent("on" + handlerType, func); } else { eval("el.on" + handlerType + " = func;"); } }

function IsChild(parent, child) { //check to see if an element is a child of another element while(child && child != parent) { child = child.parentNode; } return (child == parent); }

function ButtonBarSelectAll(preEl) {

//select all code within a given

 element
	var range = null;
	var menuEl = preEl.getElementsByTagName("ul")[0];
	if(((document.createRange && (range = document.createRange())) || (document.selection.createRange && (range = document.selection.createRange()))) && range.selectNodeContents)
	{
		//for Fx, Fe, and other more standards-compliant browsers
		range.selectNodeContents(preEl);
		range.setEndBefore(menuEl);
		var sel = window.getSelection();
		if(sel.setBaseAndExtent)
		{
			//odd variant of a few of the WebKit browsers
			sel.setBaseAndExtent(preEl, 0, menuEl, 0);
		}
		else
		{
			sel.removeAllRanges();
			sel.addRange(range);
		}
	}
	else
	{
		//for IE
		range = document.body.createTextRange();
		range.moveToElementText(preEl);
		var menuRange = document.body.createTextRange();
		menuRange.moveToElementText(menuEl);
		
		//deselect the popup menu
		while(range.compareEndPoints("EndToStart", menuRange) > 0)
		{
			range.moveEnd("word", -1);
		}
		range.select();
	}
	
	//return the range so other functions can use it
	return range;
}

function ButtonBarCreateSelectAll(preEl)
{
	return function() {
				//select all of the text in the pre element
				ButtonBarSelectAll(preEl);
			};
}

function ButtonBarCreateCopy(preEl)
{
	return function() {
				//copy all of the text in the pre element
				//IE-only at this point
				var range = ButtonBarSelectAll(preEl);
				range.execCommand("Copy");
			};
}

function ButtonBarGetText(preEl)
{
	//get the code from inside of a 
 element
	var outText = "";
	for(var c = 0; c < preEl.childNodes.length; ++c)
	{
		switch(preEl.childNodes[c].tagName ? preEl.childNodes[c].tagName.toLowerCase() : "")
		{
			case "br":
			{
				outText += "\n";
			} break;
			case "ul":
			{
				//get rid of  s
				outText = outText.replace(/\xA0/g, " ");
				
				//return the cleaned text
				return outText;
			} break;
			case "":
			{
				//no tag name
				//probably just text
				outText += (preEl.childNodes[c].textContent ? preEl.childNodes[c].textContent : (preEl.childNodes[c].innerText ? preEl.childNodes[c].innerText : preEl.childNodes[c].data));
			} break;
			default:
			{
				outText += ButtonBarGetText(preEl.childNodes[c]);
			}
		}
	}
	
	//get rid of  s
	outText = outText.replace(/\xA0/g, " ");
	
	//return the cleaned text
	return outText;
}

function ButtonBarAddSpacer(ulEl)
{
	//add a spacer bullet item to the menu list
	var spacerEl = ulEl.appendChild(document.createElement("li"));
	spacerEl.appendChild(document.createTextNode("\u2022"));
	spacerEl.style.display = "inline";
	spacerEl.style.marginLeft = "0.5em";
	spacerEl.style.marginRight = "0.5em";
}

function ButtonBarCreateMouseOver(preEl)
{
	//the mouseover event handler for 
 elements
	return function() {
				//if there's already a menu, don't add another
				if(preEl.getElementsByTagName("ul").length > 0)
				{
					return false;
				}
				
				//style the 
 and add the menu
				preEl.style.position = "relative";
				var ulEl = preEl.appendChild(document.createElement("ul"));
				ulEl.className = "ButtonBar";
				ulEl.style.position = "absolute";
				ulEl.style.right = 0;
				ulEl.style.top = 0;
				ulEl.style.whitespace = "nowrap";
				ulEl.style.marginRight = "0.5em";
				
				//define actions we want to add
				var listItems = [
								{title:"Select All",code:ButtonBarCreateSelectAll(preEl)}
							];
				if(window.clipboardData)
				{
					listItems[listItems.length] = {title:"Copy to Clipboard",code:ButtonBarCreateCopy(preEl)};
				}
				
				//add the standard menu items
				for(var i = 0; i < listItems.length; ++i)
				{
					//if it's not the first one, add a spacer
					if(i > 0)
					{
						ButtonBarAddSpacer(ulEl);
					}
					var liEl = ulEl.appendChild(document.createElement("li"));
					liEl.appendChild(document.createTextNode(listItems[i].title));
					liEl.style.cursor = "pointer";
					liEl.style.display = "inline";
					liEl.style.fontFamily = "sans-serif";
					liEl.style.textDecoration = "underline";
					AddHandler(liEl, "click", listItems[i].code);
				}
				
				//check for a codepad-supported language
				var langClass = preEl.className.split(" ")[0];
				for(var l = 0; l < buttonBarCodepadLanguages.length; ++l)
				{
					if(langClass == buttonBarCodepadLanguages[l].cssClass)
					{
						//found the language
						//add 
  • s ButtonBarAddSpacer(ulEl); var liEl = ulEl.appendChild(document.createElement("li")); liEl.style.display = "inline"; //build a form to submit to codepad var formEl = liEl.appendChild(document.createElement("form")); formEl.target = "_blank"; formEl.method = "post"; formEl.action = "http://codepad.org"; formEl.style.display = "inline"; var inputValues = [ { name: "lang", value: buttonBarCodepadLanguages[l].padName }, { name: "code", value: ButtonBarGetText(preEl) }, { name: "run", value: "True" }, { name: "private", value: "True" } ]; for(var i = 0; i < inputValues.length; ++i) { var inputEl = document.createElement("input"); inputEl.setAttribute("type", "hidden"); inputEl.setAttribute("name", inputValues[i].name); inputEl.setAttribute("value", inputValues[i].value); formEl.appendChild(inputEl); } //add and style the submit button to look like the other items var inputEl = document.createElement("input"); inputEl.setAttribute("type", "submit"); inputEl.setAttribute("name", "submit"); inputEl.setAttribute("value", "Try on Codepad"); inputEl.style.border = "none"; inputEl.style.background = "transparent"; inputEl.style.cursor = "pointer"; inputEl.style.textDecoration = "underline"; inputEl.style.display = "inline-block"; inputEl.style.padding = 0; formEl.appendChild(inputEl); break; } } return false; }; } function ButtonBarCreateMouseOut(preEl) { //mouseout handler return function(e) { //if we're moving to another element inside of the same
    , add a mouseout handler and return
    			if(!e) e = window.event;
    			var target = e.relatedTarget || e.toElement;
    			if(IsChild(preEl, target))
    			{
    				AddHandler(target, "mouseout", ButtonBarCreateMouseOut);
    				return false;
    			}
    			
    			//we're moving away from the container 
    , so we need to remove all menu lists
    			var ulEls = preEl.getElementsByTagName("ul");
    			for(var u = 0; u < ulEls.length; ++u)
    			{
    				ulEls[u].parentNode.removeChild(ulEls[u]);
    			}
    			return false;
    		};
    }
    
    function ButtonBarActivate()
    {
    	//check to see if we're looking at a task page
    	var catLinksEl = document.getElementById("catlinks");
    	var isTask = false;
    	if(catLinksEl)
    	{
    		var aEls = catLinksEl.getElementsByTagName("a");
    		for(var a = 0; a < aEls.length; ++a)
    		{
    			if(aEls[a].getAttribute("title") == "Category:Programming Tasks")
    			{
    				//it's a task
    				isTask = true;
    				break;
    			}
    		}
    	}
    	if(!isTask)
    	{
    		return;
    	}
    	
    	//look for language examples
    	var allPres = document.getElementsByTagName("pre");
    	for(var p = 0; p < allPres.length; ++p)
    	{
    		if(allPres[p].className && allPres[p].className.indexOf("highlighted_source") >= 0)
    		{
    			//set up the onmouseover, onmousleave events to show/hide the button bar
    			AddHandler(allPres[p], "mouseover", ButtonBarCreateMouseOver(allPres[p]));
    			AddHandler(allPres[p], "mouseout", ButtonBarCreateMouseOut(allPres[p]));
    		}
    	}
    }
    
    //register the comparison script with the window's load event
    AddHandler(window, "load", ButtonBarActivate);
    
    </lang>