User:Tyrok1/monobook.js

From Rosetta Code
Revision as of 05:16, 7 October 2010 by rosettacode>Tyrok1 (Let's try a cookie instead of an HTML5 data store)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/*========================================
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 SectionLinkLoad()
{
	//load cached language link info from the cookie
	if((typeof JSON != "undefined") && (typeof JSON.parse != "undefined"))
	{
		var cookieStart = document.cookie.indexOf("languageLinks=");
		window.languageLinks = new Object();
		if(cookieStart >= 0)
		{
			var cookieEnd = document.cookie.indexOf(";", cookieStart);
			cookieStart += ("languageLinks=").length;
			cookieEnd = (cookieEnd >= 0 ? cookieEnd : document.cookie.length);
			var cookieVal = document.cookie.substring(cookieStart, cookieEnd);
			window.languageLinks = JSON.parse(decodeURIComponent(cookieVal));
		}
	}
}

function SectionLinkSave()
{
	//save language link info to the cookie for later use
	if((typeof JSON != "undefined") && (typeof JSON.stringify != "undefined"))
	{
		var data = encodeURIComponent(JSON.stringify(window.languageLinks));
		document.cookie = "languageLinks=" + data;
	}
}

function SectionLinkCreateLoadClosure(request)
{
	return function() {
				if(request.readyState == 4)
				{
					//done loading
					//initialize the "languages with link information" array
					if(typeof window.languageLinks == "undefined" || !window.languageLinks || !window.languageLinks.length)
					{
						window.languageLinks = new Object();
					}
					
					//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
						window.languageLinks[curTitle] = { aName: curAName, href: curHREF, title: curTitle };
					}
					
					//save the link data, if possible,
					//to reduce the number of requests
					SectionLinkSave();
					
					//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;
	}
	
	//load stored data to reduce requests
	SectionLinkLoad();
	
	//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(window.languageLinks && window.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(window.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;
}