User:Tyrok1/monobook.js: Difference between revisions

From Rosetta Code
Content added Content deleted
(Testing My Scripts script)
(Testing JavaScript syntax highlight changer)
Line 2: Line 2:
/*========================================
/*========================================
This comparison script was written by
This comparison script was written by
Tyrok1.
Tyrok1, and has been tested on Fx 3.6.6,
Cr 5.0.375.99, Epiphany 2.30.2,
Midori 0.2.2
========================================*/
========================================*/


//define the relationship between the CSS classes and what they do
var gadgetsAvailable = [
var highlightClasses = [
{
{ cssBase: "co", description: "Comments" },
id: "LanguageComparison",
{ cssBase: "nu", description: "Numbers" },
name: "Language comparison",
{ cssBase: "kw", description: "Keywords" },
url: "http://rosettacode.org/mw/index.php" +
{ cssBase: "sy", description: "Operators" },
"?title=Rosetta_Code:Language_comparison_script" +
{ cssBase: "st", description: "Strings" },
"&action=raw&ctype=text/javascript",
{ cssBase: "re", description: "Variables/Erlang Funs" },
prefix: "Compare"
{ cssBase: "br", description: "Brackets/Parens" },
},
{ cssBase: "co", description: "Comments/Compiler directives" },
{
{ cssBase: "me", description: "Class methods" }
id: "UtilityButtonBar",
name: "Utility button bar",
url: "http://rosettacode.org/mw/index.php" +
"?title=Rosetta_Code:Per-Code_Example_Buttonbar" +
"&action=raw&ctype=text/javascript",
prefix: "ButtonBar"
}
];
];


function GadgetsAddHandler(el, handlerType, func)
function AddHandler(el, handlerType, func)
{
{
//add an event handler in a more cross-browser way
//add an event handler in a more cross-browser way
Line 43: Line 35:
}
}


function GadgetsScriptLoad(g)
function IsChild(parent, child)
{
{
//see if we need to load it
//check to see if an element is a child of another element
while(child && child != parent)
//if we don't, there's not much point in loading it again
if(!document.getElementById("GadgetScript" + g))
{
{
child = child.parentNode;
var scriptEl = document.createElement("script");
scriptEl.setAttribute("id", "GadgetScript" + g);
scriptEl.setAttribute("type", "text/javascript");
scriptEl.setAttribute("src", gadgetsAvailable[g].url);
document.documentElement.appendChild(scriptEl);
}
}
return (child == parent);
}
}


function GadgetsScriptActivate(g)
function HighlightCode(codeEl)
{
{
//find all instances of elements with the classes given and update their colors
//check to see if the script's finished loading
var allSpans = codeEl.getElementsByTagName("span");
if(eval("typeof " + gadgetsAvailable[g].prefix + "Activate") == "undefined")
for(var s = 0; s < allSpans.length; ++s)
{
{
if(allSpans[s].className)
//not finished yet - try reactivating in another 0.5s
{
setTimeout(function() { GadgetsScriptActivate(g); }, 500);
for(var c in highlightClasses)
}
{
else
var cssBase = allSpans[s].className.substring(0, highlightClasses[c].cssBase.length);
{
if(cssBase == highlightClasses[c].cssBase)
//run the activation function
{
eval(gadgetsAvailable[g].prefix + "Activate();");
var colorEl = document.getElementById("HighlightColor" + c);
var dropdownVal = colorEl.options[colorEl.selectedIndex].value;
allSpans[s].style.color = (dropdownVal == "auto" ? null : dropdownVal);
}
}
}
}
}
}
}


function GadgetsScriptDeactivate(g)
function HighlightUpdate()
{
{
//look for language examples
//check to see if the specified script has a deactivation function
var allPres = document.getElementsByTagName("pre");
if(eval("typeof " + gadgetsAvailable[g].prefix + "Deactivate") != "undefined")
for(var p = 0; p < allPres.length; ++p)
{
{
if(allPres[p].className && allPres[p].className.indexOf("highlighted_source") >= 0)
//it does - run it
{
eval(gadgetsAvailable[g].prefix + "Deactivate();");
HighlightCode(allPres[p]);
}
}
}
else
//save defaults to cookie
var defaults = "";
for(var c in highlightClasses)
{
{
var colorEl = document.getElementById("HighlightColor" + c);
//pop up a warning to the user to let them know
defaults += (defaults == "" ? "" : ",") + highlightClasses[c].cssBase + "-" + colorEl.options[colorEl.selectedIndex].value;
//the plugin will be disabled when they reload
alert("This script will be disabled on next page load");
}
}
document.cookie = ("highlightDefaults=" + defaults + "; expires=" + (new Date((new Date()).getTime() + 1000 * 60 * 60 * 24 * 365)).toGMTString() + "; path=/");
}
}


function GadgetsCreateCheckboxClosure(el)
function HighlightAddToolbox()
{
{
//check the cookie for default colors from last time
//create an onclick handler for the script checkboxes
var cookies = document.cookie.split(";");
return function() {
for(var c in cookies)
//save the checkboxes to the cookie for next page load
{
GadgetsSaveCheckboxes();
var nameVal = cookies[c].split("=", 2);
if(nameVal[0] == "highlightDefaults")
//check to see if we need to activate or deactivate
{
if(el.checked)
var defaults = nameVal[1].split(",");
for(var d in defaults)
{
var defaultNameVal = defaults[d].split("-", 2);
for(var h in highlightClasses)
{
{
if(highlightClasses[h].cssBase == defaultNameVal[0])
//load and activate the script
{
GadgetsScriptLoad(el.value);
highlightClasses[h].defaultColor = defaultNameVal[1];
GadgetsScriptActivate(el.value);
}
}
}
else
}
{
}
}
//deactivate the script
GadgetsScriptDeactivate(el.value);
}
};
}

function GadgetsMouseOver()
{
//show the scripts dropdown
document.getElementById("pt-jsgadgets-list").style.display = "block";
}

function GadgetsMouseOut()
{
//hide the scripts dropdown
document.getElementById("pt-jsgadgets-list").style.display = "none";
}

function GadgetsSaveCheckboxes()
{
var checkedBoxes = "", checkboxEl = null;
//add the toolbox
//build a string representation of all of the checked boxes to save to the cookie
var hexDigits = ["0", "3", "6", "9", "c", "f"];
for(var c = 0; checkboxEl = document.getElementById("pt-jsgadgets-gadget" + c); ++c)
var sideColumn = document.getElementById("column-one");
var portletEl = sideColumn.appendChild(document.createElement("div"));
portletEl.className = "portlet";
portletEl.id = "HighlightToolbox";
portletEl.style.position = "relative";
portletEl.appendChild(document.createElement("h5")).appendChild(document.createTextNode("Highlight Colors"));
var pBodyEl = portletEl.appendChild(document.createElement("div"));
pBodyEl.className = "pBody";
var dlEl = pBodyEl.appendChild(document.createElement("dl"));
for(var c in highlightClasses)
{
{
var labelEl = dlEl.appendChild(document.createElement("dt")).appendChild(document.createElement("label"));
if(checkboxEl.checked)
labelEl.setAttribute("for", "HighlightColor" + c);
labelEl.appendChild(document.createTextNode(highlightClasses[c].description));
var inputEl = document.createElement("select");
inputEl.id = "HighlightColor" + c;
inputEl = dlEl.appendChild(document.createElement("dd")).appendChild(inputEl);
inputEl.onclick = HighlightUpdate;
inputEl.onchange = HighlightUpdate;
inputEl.onkeyup = HighlightUpdate;
var optionEl = inputEl.appendChild(document.createElement("option"));
optionEl.value = "auto";
optionEl.appendChild(document.createTextNode("(Default)"));
var optionNum = 1;
for(h1 in hexDigits)
{
{
if(checkedBoxes != "")
for(h2 in hexDigits)
{
{
for(h3 in hexDigits)
checkedBoxes += ",";
{
var optionEl = inputEl.appendChild(document.createElement("option"));
var color = "#" + hexDigits[h1] + hexDigits[h2] + hexDigits[h3];
optionEl.value = color;
optionEl.style.color = color;
optionEl.appendChild(document.createTextNode(color));
if(highlightClasses[c].defaultColor && color.toLowerCase() == highlightClasses[c].defaultColor.toLowerCase())
{
inputEl.selectedIndex = optionNum;
}
++optionNum;
}
}
}
checkedBoxes += gadgetsAvailable[c].id;
}
}
}
}
//set an expiry date 1000 years into the future
var expireDate = new Date();
expireDate.setFullYear(expireDate.getFullYear() + 1000);
//store the cookie
document.cookie = "jsGadgets=" + escape(checkedBoxes) +
"; expires=" + expireDate.toUTCString();
}
}


function GadgetsGetCheckboxes()
function HighlightScroll(e)
{
{
var toolboxEl = document.getElementById("HighlightToolbox");
//pull in the cookie and look for the jsGadgets key
if(!toolboxEl.originalTop)
var fullCookie = document.cookie;
var gadgetsPos = fullCookie.indexOf("jsGadgets=");
if(gadgetsPos < 0)
{
{
toolboxEl.originalTop = toolboxEl.offsetTop;
//no gadgets in the cookie
return new Array();
}
}
var newTop = (document.body.scrollTop - toolboxEl.originalTop);
var endPos = fullCookie.indexOf(";", gadgetsPos);
toolboxEl.style.top = (newTop >= 0 ? newTop : 0) + "px";
}
//split the gadget IDs by comma

var jsGadgets = fullCookie.substring(gadgetsPos + ("jsGadgets=").length,
function HighlightActivate()
(endPos > 0 ? endPos : fullCookie.length));
{
var checkIDs = unescape(jsGadgets).split(",");
//check to see if we're looking at a task page
var catLinksEl = document.getElementById("catlinks");
//translate the list of IDs to a list of array indices,
var isTask = false;
//in keeping with the way the rest of this module works
if(catLinksEl)
var checkIndices = new Array();
for(var g = 0; g < gadgetsAvailable.length; ++g)
{
{
var aEls = catLinksEl.getElementsByTagName("a");
for(var c = 0; c < checkIDs.length; ++c)
for(var a = 0; a < aEls.length; ++a)
{
{
if(aEls[a].getAttribute("title") == "Category:Programming Tasks")
if(gadgetsAvailable[g].id == checkIDs[c])
{
{
//it's a task
checkIndices[checkIndices.length] = g;
isTask = true;
break;
break;
}
}
}
}
}
}
if(!isTask)
return checkIndices;
}

function GadgetsActivate()
{
//find the user preferences button and add a new list item to the right of it
var prefsEl = document.getElementById("pt-preferences");
if(!prefsEl)
{
{
return;
var personalEl = document.getElementById("p-personal");
if(!personalEl)
{
return;
}
var liEls = personalEl.getElementsByTagName("li");
if(!liEls || liEls.length < 2)
{
return;
}
prefsEl = liEls[liEls.length - 2];
}
}
var jsMenuEl = prefsEl.parentNode.insertBefore(
document.createElement("li"), prefsEl.nextSibling);
jsMenuEl.setAttribute("id", "pt-jsgadgets");
HighlightAddToolbox();
//add a new link named "My scripts" in the new list item
//from a semantics point of view, this is not great,
//but this way the styling kicks in to keep it consistent with its siblings
var jsLinkEl = jsMenuEl.appendChild(document.createElement("a"));
jsLinkEl.appendChild(document.createTextNode("My scripts"));
jsLinkEl.setAttribute("href", "javascript: void(0);");
jsLinkEl.style.position = "relative";
HighlightUpdate();
//add handlers for showing on mouseover and hiding on mouseout
GadgetsAddHandler(jsLinkEl, "mouseover", GadgetsMouseOver);
GadgetsAddHandler(jsLinkEl, "mouseout", GadgetsMouseOut);
//build a list for showing available JS gadgets
var modulesListEl = jsLinkEl.appendChild(document.createElement("ol"));
modulesListEl.setAttribute("id", "pt-jsgadgets-list");
modulesListEl.style.listStyle = "none";
modulesListEl.style.margin = 0;
modulesListEl.style.padding = 0;
modulesListEl.style.position = "absolute";
modulesListEl.style.top = "100%";
modulesListEl.style.left = 0;
modulesListEl.style.backgroundColor = "#fff";
modulesListEl.style.border = "1px solid #69c";
modulesListEl.style.padding = "0.5em";
modulesListEl.style.display = "none";
//raise the zIndex of the new button (as well as
//a few parents) so the menu overlaps the page
var zEl = modulesListEl;
for(var z = 0; z < 6 && zEl && zEl.style; ++z, zEl = zEl.parentNode)
{
zEl.style.zIndex = 100;
}
//add each of the gadgets to the list
for(var m = 0; m < gadgetsAvailable.length; ++m)
{
//add the list item element
var liEl = modulesListEl.appendChild(document.createElement("li"));
liEl.style.display = "block";
liEl.style.cssFloat = "none";
liEl.style.right = "auto";
liEl.style.left = 0;
liEl.style.textAlign = "left";
liEl.style.margin = 0;
liEl.style.padding = 0;
//add the checkbox
var inputEl = document.createElement("input");
var checkboxId = "pt-jsgadgets-gadget" + m;
inputEl.setAttribute("type", "checkbox");
inputEl.setAttribute("id", checkboxId);
inputEl.setAttribute("value", m);
GadgetsAddHandler(inputEl, "click", GadgetsCreateCheckboxClosure(inputEl));
liEl.appendChild(inputEl);
//add the label
var labelEl = document.createElement("label");
labelEl.setAttribute("for", checkboxId);
labelEl.appendChild(document.createTextNode(gadgetsAvailable[m].name));
labelEl.style.paddingLeft = "1em";
liEl.appendChild(labelEl);
}
//fetch the saved checkboxes from the cookie
var checks = GadgetsGetCheckboxes();
for(var c = 0; c < checks.length; ++c)
{
//for each one that should be checked on page load,
//check the box, load, and activate it
document.getElementById("pt-jsgadgets-gadget" + checks[c]).checked = true;
GadgetsScriptLoad(checks[c]);
GadgetsScriptActivate(checks[c]);
}
}
}


//register the comparison script with the window's load event
//register the comparison script with the window's load event
GadgetsAddHandler(window, "load", GadgetsActivate);
AddHandler(window, "load", HighlightActivate);
AddHandler(window, "scroll", HighlightScroll);

//</lang>
//</lang>

Revision as of 19:04, 3 July 2011

//<lang javascript>
/*========================================
This comparison script was written by
Tyrok1.
========================================*/

//define the relationship between the CSS classes and what they do
var highlightClasses = [
					{ cssBase: "co", description: "Comments" },
					{ cssBase: "nu", description: "Numbers" },
					{ cssBase: "kw", description: "Keywords" },
					{ cssBase: "sy", description: "Operators" },
					{ cssBase: "st", description: "Strings" },
					{ cssBase: "re", description: "Variables/Erlang Funs" },
					{ cssBase: "br", description: "Brackets/Parens" },
					{ cssBase: "co", description: "Comments/Compiler directives" },
					{ cssBase: "me", description: "Class methods" }
				];

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 HighlightCode(codeEl)
{
	//find all instances of elements with the classes given and update their colors
	var allSpans = codeEl.getElementsByTagName("span");
	for(var s = 0; s < allSpans.length; ++s)
	{
		if(allSpans[s].className)
		{
			for(var c in highlightClasses)
			{
				var cssBase = allSpans[s].className.substring(0, highlightClasses[c].cssBase.length);
				if(cssBase == highlightClasses[c].cssBase)
				{
					var colorEl = document.getElementById("HighlightColor" + c);
					var dropdownVal = colorEl.options[colorEl.selectedIndex].value;
					allSpans[s].style.color = (dropdownVal == "auto" ? null : dropdownVal);
				}				
			}
		}
	}
}

function HighlightUpdate()
{
	//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)
		{
			HighlightCode(allPres[p]);
		}
	}
	
	//save defaults to cookie
	var defaults = "";
	for(var c in highlightClasses)
	{
		var colorEl = document.getElementById("HighlightColor" + c);
		defaults += (defaults == "" ? "" : ",") + highlightClasses[c].cssBase + "-" + colorEl.options[colorEl.selectedIndex].value;
	}
	document.cookie = ("highlightDefaults=" + defaults + "; expires=" + (new Date((new Date()).getTime() + 1000 * 60 * 60 * 24 * 365)).toGMTString() + "; path=/");
}

function HighlightAddToolbox()
{
	//check the cookie for default colors from last time
	var cookies = document.cookie.split(";");
	for(var c in cookies)
	{
		var nameVal = cookies[c].split("=", 2);
		if(nameVal[0] == "highlightDefaults")
		{
			var defaults = nameVal[1].split(",");
			for(var d in defaults)
			{
				var defaultNameVal = defaults[d].split("-", 2);
				for(var h in highlightClasses)
				{
					if(highlightClasses[h].cssBase == defaultNameVal[0])
					{
						highlightClasses[h].defaultColor = defaultNameVal[1];
					}
				}
			}
		}
	}
	
	//add the toolbox
	var hexDigits = ["0", "3", "6", "9", "c", "f"];
	var sideColumn = document.getElementById("column-one");
	var portletEl = sideColumn.appendChild(document.createElement("div"));
	portletEl.className = "portlet";
	portletEl.id = "HighlightToolbox";
	portletEl.style.position = "relative";
	portletEl.appendChild(document.createElement("h5")).appendChild(document.createTextNode("Highlight Colors"));
	var pBodyEl = portletEl.appendChild(document.createElement("div"));
	pBodyEl.className = "pBody";
	var dlEl = pBodyEl.appendChild(document.createElement("dl"));
	for(var c in highlightClasses)
	{
		var labelEl = dlEl.appendChild(document.createElement("dt")).appendChild(document.createElement("label"));
		labelEl.setAttribute("for", "HighlightColor" + c);
		labelEl.appendChild(document.createTextNode(highlightClasses[c].description));
		var inputEl = document.createElement("select");
		inputEl.id = "HighlightColor" + c;
		inputEl = dlEl.appendChild(document.createElement("dd")).appendChild(inputEl);
		inputEl.onclick = HighlightUpdate;
		inputEl.onchange = HighlightUpdate;
		inputEl.onkeyup = HighlightUpdate;
		var optionEl = inputEl.appendChild(document.createElement("option"));
		optionEl.value = "auto";
		optionEl.appendChild(document.createTextNode("(Default)"));
		
		var optionNum = 1;
		for(h1 in hexDigits)
		{
			for(h2 in hexDigits)
			{
				for(h3 in hexDigits)
				{
					var optionEl = inputEl.appendChild(document.createElement("option"));
					var color = "#" + hexDigits[h1] + hexDigits[h2] + hexDigits[h3];
					optionEl.value = color;
					optionEl.style.color = color;
					optionEl.appendChild(document.createTextNode(color));
					if(highlightClasses[c].defaultColor && color.toLowerCase() == highlightClasses[c].defaultColor.toLowerCase())
					{
						inputEl.selectedIndex = optionNum;
					}
					++optionNum;
				}
			}
		}
	}
}

function HighlightScroll(e)
{
	var toolboxEl = document.getElementById("HighlightToolbox");
	if(!toolboxEl.originalTop)
	{
		toolboxEl.originalTop = toolboxEl.offsetTop;
	}
	var newTop = (document.body.scrollTop - toolboxEl.originalTop);
	toolboxEl.style.top = (newTop >= 0 ? newTop : 0) + "px";
}

function HighlightActivate()
{
	//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;
	}
	
	HighlightAddToolbox();
	
	HighlightUpdate();
}

//register the comparison script with the window's load event
AddHandler(window, "load", HighlightActivate);
AddHandler(window, "scroll", HighlightScroll);

//</lang>