User:Tyrok1/monobook.js: Difference between revisions

From Rosetta Code
Content added Content deleted
(Fixing long lines and escaping problem)
(Trying out "link directly to language example" script)
Line 1: Line 1:
/*========================================
/*========================================
This comparison script was written by
This comparison script was written by
Tyrok1, and has been tested on Fx 3.6.6,
Tyrok1, and has been tested on IE 5.5,
IE 6, IE 7, IE 8, Fx 3.6.2, and
Cr 5.0.375.99, Epiphany 2.30.2,
Midori 0.2.2
Fe 4.0.280.
========================================*/
========================================*/


function SectionLinkCreateLoadClosure(request)
var gadgetsAvailable = [
{
return function() {
if(request.readyState == 4)
{
//done loading
//initialize the "languages with link information" array
if(typeof localStorage == "undefined")
{
{
window.localStorage = new Array();
id: "LanguageComparison",
}
name: "Language comparison",
if(typeof localStorage.languageLinks = "undefined")
url: "http://rosettacode.org/mw/index.php" +
"?title=Rosetta_Code:Language_comparison_script" +
"&action=raw&ctype=text/javascript",
prefix: "Compare"
},
{
{
localStorage.languageLinks = new Array();
id: "UtilityButtonBar",
}
name: "Utility button bar",
url: "http://rosettacode.org/mw/index.php" +
//skip the toc
"?title=Rosetta_Code:Per-Code_Example_Buttonbar" +
var text = request.responseText;
"&action=raw&ctype=text/javascript",
var curPos = text.indexOf(" id=\"toctitle\"");
prefix: "ButtonBar"
var catLinksStart = text.indexOf("catlinks");
curPos = text.indexOf("</table>", curPos);
//start looking for anchor tags with name attributes
while((curPos = text.indexOf("a name=\"", curPos)) >= 0)
{
//isolate the name attribute
curPos += ("a name=\"").length;
var endPos = text.indexOf("\"", curPos);
var curAName = text.substring(curPos, endPos);
//find the next anchor with a name attribute so we know where the next section is
var nextA = text.indexOf("a name=\"", endPos);
//look for a language header
var headlinePos = text.indexOf("mw-headline", endPos);
if(nextA < headlinePos || text.substring(endPos, headlinePos).indexOf("h3") >= 0)
{
//no <h2> header
//not a full language section
continue;
}
//look for the end of the header and isolate the content of the header
var headlineEnd = text.indexOf("</h2>", headlinePos);
var headline = text.substring(headlinePos, headlineEnd);
//isolate the language category page it links to
var hrefStart = headline.indexOf(" href=\"") + (" href=\"").length;
var hrefEnd = headline.indexOf("\"", hrefStart);
var curHREF = headline.substring(hrefStart, hrefEnd);
//isolate the displayed text name of the language
var titleStart = headline.indexOf(" title=\"Category:") + (" title=\"Category:").length;
var titleEnd = headline.indexOf("\"", titleStart);
var curTitle = headline.substring(titleStart, titleEnd);
//check to make sure we have all the information we need about this language
if(curAName == "" || curHREF == "" || curTitle == "")
{
//something's missing
continue;
}
//add the language to our array for later use
localStorage.languageLinks[curTitle] = { aName: curAName, href: curHREF, title: curTitle };
}
//and if we've got a function to call when we're done, call it
if(request.callback)
{
request.callback();
}
}
];

function GadgetsAddHandler(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 GadgetsScriptLoad(g)
{
//see if we need to load it
//if we don't, there's not much point in loading it again
if(!document.getElementById("GadgetScript" + g))
{
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);
}
}

function GadgetsScriptActivate(g)
{
//check to see if the script's finished loading
if(eval("typeof " + gadgetsAvailable[g].prefix + "Activate") == "undefined")
{
//not finished yet - try reactivating in another 0.5s
setTimeout(function() { GadgetsScriptActivate(g); }, 500);
}
else
{
//run the activation function
eval(gadgetsAvailable[g].prefix + "Activate();");
}
}

function GadgetsScriptDeactivate(g)
{
//check to see if the specified script has a deactivation function
if(eval("typeof " + gadgetsAvailable[g].prefix + "Deactivate") != "undefined")
{
//it does - run it
eval(gadgetsAvailable[g].prefix + "Deactivate();");
}
else
{
//pop up a warning to the user to let them know
//the plugin will be disabled when they reload
alert("This script will be disabled on next page load");
}
}

function GadgetsCreateCheckboxClosure(el)
{
//create an onclick handler for the script checkboxes
return function() {
//save the checkboxes to the cookie for next page load
GadgetsSaveCheckboxes();
//check to see if we need to activate or deactivate
if(el.checked)
{
//load and activate the script
GadgetsScriptLoad(el.value);
GadgetsScriptActivate(el.value);
}
else
{
//deactivate the script
GadgetsScriptDeactivate(el.value);
}
}
};
};
}
}


function GadgetsMouseOver()
function SectionLinkFetchFrom(url, callback)
{
{
//fetch the given page and store all <a name>/language pairs on the page to the cookie for later
//show the scripts dropdown
var request = new XMLHttpRequest();
document.getElementById("pt-jsgadgets-list").style.display = "block";
request.onreadystatechange = SectionLinkCreateLoadClosure(request);
request.callback = callback;
request.open("GET", url, true);
request.send("");
}
}


function GadgetsMouseOut()
function SectionLinkActivate()
{
{
//check to see if we're looking at a language page
//hide the scripts dropdown
document.getElementById("pt-jsgadgets-list").style.display = "none";
var catLinksEl = document.getElementById("catlinks");
var isLanguage = false;
}
if(catLinksEl)

function GadgetsSaveCheckboxes()
{
var checkedBoxes = "", checkboxEl = null;
//build a string representation of all of the checked boxes to save to the cookie
for(var c = 0; checkboxEl = document.getElementById("pt-jsgadgets-gadget" + c); ++c)
{
{
var aEls = catLinksEl.getElementsByTagName("a");
if(checkboxEl.checked)
for(var a = 0; a < aEls.length; ++a)
{
{
if(aEls[a].getAttribute("title") == "Category:Programming Languages")
if(checkedBoxes != "")
{
{
checkedBoxes += ",";
//it's a language
isLanguage = true;
break;
}
}
checkedBoxes += gadgetsAvailable[c].id;
}
}
}
}
if(!isLanguage)
//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()
{
//pull in the cookie and look for the jsGadgets key
var fullCookie = document.cookie;
var gadgetsPos = fullCookie.indexOf("jsGadgets=");
if(gadgetsPos < 0)
{
{
//no gadgets in the cookie
//we're not on a language page
//this script does not apply
return new Array();
return;
}
}
var endPos = fullCookie.indexOf(";", gadgetsPos);
//check this page's "firstHeading" ID content for a category name
//split the gadget IDs by comma
var firstHeadingEl = document.getElementById("firstHeading");
var jsGadgets = fullCookie.substring(gadgetsPos + ("jsGadgets=").length,
var langName = (firstHeadingEl.textContent ? firstHeadingEl.textContent : firstHeadingEl.innerText);
(endPos > 0 ? endPos : fullCookie.length));
langName = langName.substring(("Category:").length, langName.length);
var checkIDs = unescape(jsGadgets).split(",");
//translate the list of IDs to a list of array indices,
//get a list of all task pages on this page for later use
var tasksEl = document.getElementById("mw-pages");
//in keeping with the way the rest of this module works
var checkIndices = new Array();
var aEls = tasksEl.getElementsByTagName("a");
for(var g = 0; g < gadgetsAvailable.length; ++g)
//check to see if we already have link information about the current language
if(localStorage.languageLinks && localStorage.languageLinks[langName])
{
{
//we do
for(var c = 0; c < checkIDs.length; ++c)
//modify all of the links on the page to link directly to the current language's section
for(var i = 0; i < aEls.length; ++i)
{
{
if(gadgetsAvailable[g].id == checkIDs[c])
if(aEls[i].href.indexOf("#") < 0)
{
{
aEls[i].href += "#" + encodeURIComponent(localStorage.languageLinks[langName].aName);
checkIndices[checkIndices.length] = g;
break;
}
}
}
}
}
}
else
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)
{
{
//we do not have link information on the current language
var personalEl = document.getElementById("p-personal");
//start fetching task pages and searching through them, starting with the first task link on the page
if(!personalEl)
if(typeof SectionLinkActivate.linkNum == "undefined")
{
{
SectionLinkActivate.linkNum = 0;
return;
}
}
var liEls = personalEl.getElementsByTagName("li");
//only check the first five task links
if(!liEls || liEls.length < 2)
if(SectionLinkActivate.linkNum >= 5)
{
{
return;
return;
}
}
prefsEl = liEls[liEls.length - 2];
}
var jsMenuEl = prefsEl.parentNode.insertBefore(
document.createElement("li"), prefsEl.nextSibling);
jsMenuEl.setAttribute("id", "pt-jsgadgets");
//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";
//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;
//fetch and process the task, and rerun this activation function when done
//add the checkbox
SectionLinkFetchFrom(aEls[SectionLinkActivate.linkNum].href, SectionLinkActivate);
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);
//update the link number so we move on to the next link if the current one doesn't have this language
//add the label
++SectionLinkActivate.linkNum;
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 link correcting script with the window's load event
if(window.addEventListener)
GadgetsAddHandler(window, "load", GadgetsActivate);
{
window.addEventListener("load", SectionLinkActivate, false);
}
else if(window.attachEvent)
{
window.attachEvent("onload", SectionLinkActivate);
}
else if(document.addEventListener)
{
document.addEventListener("load", SectionLinkActivate, false);
}
else
{
window.onload = SectionLinkActivate;
}

Revision as of 23:54, 6 October 2010

/*========================================
This comparison script was written by
Tyrok1, and has been tested on IE 5.5,
IE 6, IE 7, IE 8, Fx 3.6.2, and
Fe 4.0.280.
========================================*/

function SectionLinkCreateLoadClosure(request)
{
	return function() {
				if(request.readyState == 4)
				{
					//done loading
					//initialize the "languages with link information" array
					if(typeof localStorage == "undefined")
					{
						window.localStorage = new Array();
					}
					if(typeof localStorage.languageLinks = "undefined")
					{
						localStorage.languageLinks = new Array();
					}
					
					//skip the toc
					var text = request.responseText;
					var curPos = text.indexOf(" id=\"toctitle\"");
					var catLinksStart = text.indexOf("catlinks");
					curPos = text.indexOf("</table>", curPos);
					
					//start looking for anchor tags with name attributes
					while((curPos = text.indexOf("a name=\"", curPos)) >= 0)
					{
						//isolate the name attribute
						curPos += ("a name=\"").length;
						var endPos = text.indexOf("\"", curPos);
						var curAName = text.substring(curPos, endPos);
						
						//find the next anchor with a name attribute so we know where the next section is
						var nextA = text.indexOf("a name=\"", endPos);
						
						//look for a language header
						var headlinePos = text.indexOf("mw-headline", endPos);
						if(nextA < headlinePos || text.substring(endPos, headlinePos).indexOf("h3") >= 0)
						{
							//no <h2> header
							//not a full language section
							continue;
						}
						
						//look for the end of the header and isolate the content of the header
						var headlineEnd = text.indexOf("</h2>", headlinePos);
						var headline = text.substring(headlinePos, headlineEnd);
						
						//isolate the language category page it links to
						var hrefStart = headline.indexOf(" href=\"") + (" href=\"").length;
						var hrefEnd = headline.indexOf("\"", hrefStart);
						var curHREF = headline.substring(hrefStart, hrefEnd);
						
						//isolate the displayed text name of the language
						var titleStart = headline.indexOf(" title=\"Category:") + (" title=\"Category:").length;
						var titleEnd = headline.indexOf("\"", titleStart);
						var curTitle = headline.substring(titleStart, titleEnd);
						
						//check to make sure we have all the information we need about this language
						if(curAName == "" || curHREF == "" || curTitle == "")
						{
							//something's missing
							continue;
						}
						
						//add the language to our array for later use
						localStorage.languageLinks[curTitle] = { aName: curAName, href: curHREF, title: curTitle };
					}
					
					//and if we've got a function to call when we're done, call it
					if(request.callback)
					{
						request.callback();
					}
				}
			};
}

function SectionLinkFetchFrom(url, callback)
{
	//fetch the given page and store all <a name>/language pairs on the page to the cookie for later
	var request = new XMLHttpRequest();
	request.onreadystatechange = SectionLinkCreateLoadClosure(request);
	request.callback = callback;
	request.open("GET", url, true);
	request.send("");
}

function SectionLinkActivate()
{
	//check to see if we're looking at a language page
	var catLinksEl = document.getElementById("catlinks");
	var isLanguage = false;
	if(catLinksEl)
	{
		var aEls = catLinksEl.getElementsByTagName("a");
		for(var a = 0; a < aEls.length; ++a)
		{
			if(aEls[a].getAttribute("title") == "Category:Programming Languages")
			{
				//it's a language
				isLanguage = true;
				break;
			}
		}
	}
	if(!isLanguage)
	{
		//we're not on a language page
		//this script does not apply
		return;
	}
	
	//check this page's "firstHeading" ID content for a category name
	var firstHeadingEl = document.getElementById("firstHeading");
	var langName = (firstHeadingEl.textContent ? firstHeadingEl.textContent : firstHeadingEl.innerText);
	langName = langName.substring(("Category:").length, langName.length);
	
	//get a list of all task pages on this page for later use
	var tasksEl = document.getElementById("mw-pages");
	var aEls = tasksEl.getElementsByTagName("a");
	
	//check to see if we already have link information about the current language
	if(localStorage.languageLinks && localStorage.languageLinks[langName])
	{
		//we do
		//modify all of the links on the page to link directly to the current language's section
		for(var i = 0; i < aEls.length; ++i)
		{
			if(aEls[i].href.indexOf("#") < 0)
			{
				aEls[i].href += "#" + encodeURIComponent(localStorage.languageLinks[langName].aName);
			}
		}
	}
	else
	{
		//we do not have link information on the current language
		//start fetching task pages and searching through them, starting with the first task link on the page
		if(typeof SectionLinkActivate.linkNum == "undefined")
		{
			SectionLinkActivate.linkNum = 0;
		}
		
		//only check the first five task links
		if(SectionLinkActivate.linkNum >= 5)
		{
			return;
		}
		
		//fetch and process the task, and rerun this activation function when done
		SectionLinkFetchFrom(aEls[SectionLinkActivate.linkNum].href, SectionLinkActivate);
		
		//update the link number so we move on to the next link if the current one doesn't have this language
		++SectionLinkActivate.linkNum;
	}
}

//register the link correcting script with the window's load event
if(window.addEventListener)
{
	window.addEventListener("load", SectionLinkActivate, false);
}
else if(window.attachEvent)
{
	window.attachEvent("onload", SectionLinkActivate);
}
else if(document.addEventListener)
{
	document.addEventListener("load", SectionLinkActivate, false);
}
else
{
	window.onload = SectionLinkActivate;
}