User:GoRight/Wordcount.js

	// ***************************************************************** //
	//		  	   Word count tool			     //
	//		  	     Version 1.0			     //
	// For quick installation, add					     //
	// importScript('User:Shubinator/DYKcheck.js');			     //
	// to your monobook.js						     //
	// See [[User:Shubinator/DYKcheck]] for more info, including	     //
	// configurable options and how to use the tool without installation //
	// or logging in.						     //
	// First version written by Shubinator in February 2009	     //
	// ***************************************************************** //

var onTTDYK, nextSection, urlJump, sections, currentTitle;
var partsProcessing, articleTitles, dates, nom5x;
var dateFormat, hookLengthYellow, hookLengthRed, check5xNoms, unlock, fixedSidebar; //configurable options
if (!hookLengthYellow) hookLengthYellow = 200;
if (!hookLengthRed) hookLengthRed = 220;
if (!check5xNoms) check5xNoms = "ifnom5x";
if (!fixedSidebar) fixedSidebar = "onttydk";

function scanArticle(title, output, html) {
	// the meat of the DYKcheck tool
	// calculates prose size of the given html
	// checks for inline citations and stub templates in the given html
	// passes info to checkTalk(), getFirstRevision(), checkMove(), and checkExpansion()
	
	// if (!onTTDYK || (check5xNoms == "always") || (check5xNoms == "ifnom5x" && nom5x)) {
		// partsProcessing = new Array(4);
	// } else {
		// partsProcessing = new Array(3);
	// }
	// dates = new Array(3);

	var proseDisp = document.createElement("li");
	proseDisp.id = "dyk-prose";
	output.appendChild(proseDisp);

	// calculate prose size
	// var prose = calculateProse(html, true);
	var prose = calculateProse(html, false);
	var pList = html.getElementsByTagName("p");
	var word_count = 0;
	for (var i=0;i < pList.length; i++) {
		var para = pList[i];
		if (para.parentNode == html) {
			word_count += para.innerHTML.replace(/(<([^>]+)>)/ig,"").split(' ').length;
		}
	}
	proseDisp.innerHTML='<b>Prose size (text only): </b>' + prose + '&nbsp;B (' +
			word_count + ' words) "readable prose size"';
	// if (prose < 1500) {
		// proseDisp.style.cssText = "background-color:pink";
	// }
	
	// // check for inline citations
	// if (html.innerHTML.indexOf('id="cite_ref-') == -1 && html.innerHTML.indexOf('id=cite_ref-') == -1) {
		// var noref = document.createElement("li");
		// noref.id = "no-ref";
		// output.appendChild(noref);
		// noref.innerHTML = 'No inline citations';
		// noref.style.cssText = "background-color:pink";
	// }
	
	// // check if article is stub or if it has appeared in DYK or ITN
	// if (html.innerHTML.indexOf('id="stub"') != -1 || html.innerHTML.indexOf('id=stub') != -1) {
		// var stubAlert = document.createElement("li");
		// stubAlert.id = "stub-alert";
		// output.appendChild(stubAlert);
		// stubAlert.innerHTML = 'Article is classified as a stub';
		// stubAlert.style.cssText = "background-color:yellow";
	// }
	// checkTalk(title, output); //check talk page
	
	// // check for various tags
	// var alertColor = "yellow";
	// var tagsFound = "";
	// var imageList = new Array("Text_document_with_red_question_mark.svg", 
			// "Question book-new.svg", "Ambox content.png", "Ambox style.png", 
			// "Imbox style.png", "Copyright-problem.svg", "Copyright-problem paste.svg", 
			// "Ambox globe content.svg", "Unbalanced scales.svg", "Ambox scales.svg", 
			// "Ambox_contradict.svg", "Ambox warning orange.svg", "Acap.svg");
	// var tagList = new Array("unverified content", "insufficient citations", "dispute", "cleanup", "cleanup",
			// "copyright violations", "copyright violations", "globalization", "neutrality", 
			// "neutrality", "contradiction", "dispute", "copyedit");
	// if (html.innerHTML.indexOf("This article is being considered for deletion in accordance with Wikipedia's") != -1) {
		// var afdIndex = html.innerHTML.indexOf('title="Wikipedia:Articles for deletion/') + 7;
		// var afdLink = html.innerHTML.substring(afdIndex, html.innerHTML.indexOf('"', afdIndex));
		// tagsFound += 'Article has been <b><a href="http://en.wikipedia.org/wiki/' + afdLink + '">nominated for deletion</a></b>. '
		// alertColor = "pink";			
	// } else if ((html.innerHTML.toLowerCase().indexOf('<table class="plainlinks ombox ombox-speedy"') != -1) || 
			// (html.innerHTML.toLowerCase().indexOf('<table class="plainlinks ambox ambox-speedy"') != -1) || 
			// (html.innerHTML.toLowerCase().indexOf('<table class="metadata plainlinks ombox ombox-speedy"') != -1) ||
			// (html.innerHTML.toLowerCase().indexOf('<table class="metadata plainlinks ambox ambox-speedy"') != -1)) {
		// tagsFound += "Article has been <b>tagged for speedy deletion</b>. "
		// alertColor = "pink";
	// }
	// for (var i=0; i < imageList.length; i++) {
		// if (html.innerHTML.indexOf(imageList[i]) != -1) {
			// tagsFound += "Article has a " + tagList[i] + " tag. ";
		// }
	// }
	// if (tagsFound != "") {
		// var tagAlert = document.createElement("li");
		// tagAlert.id = "tag-alert";
		// output.appendChild(tagAlert);
		// tagAlert.innerHTML = tagsFound;
		// tagAlert.style.cssText = "background-color:" + alertColor;
	// }
		
	// // find creator of article and date
	// getFirstRevision(title, output);
	
	// // check if the article has been moved from userspace within last 100 edits
	// if (wgNamespaceNumber != 2) {
		// checkMove(title, output);
	// } else {
		// partsProcessing[2] = true;
	// }
	
	// // check for expansion start date, assuming now expanded to 5x (last 500 edits)
	// if (!onTTDYK || (check5xNoms == "always") || (check5xNoms == "ifnom5x" && nom5x)) {
		// checkExpansion(title, output, prose);
	// }
}

function checkDocument() {
	// prepares for scan and passes info to scanArticle()
	onTTDYK = false;
	if (document.getElementById("dyk-stats-0")) {
		clearStats();
	} else {
		var output = document.createElement("ul");
		output.id = "dyk-stats-0";
		var dummy = document.getElementById("siteSub");
		dummy.parentNode.insertBefore(output, dummy.nextSibling);
		createHeaderAndProcessing(output);
		currentTitle = 0;
		var normalizedTitle = wgTitle.replace(/\%/g,"%25").replace(/\+/g, "%2B").replace(/\//g,"%2F");
		normalizedTitle = normalizedTitle.replace(/\?/g,"%3F").replace(/\#/g,"%23").replace(/\&/g,"%26");
		if (wgNamespaceNumber == 2) {
			normalizedTitle = "User:" + normalizedTitle;
		}
		scanArticle(normalizedTitle, output, getBody());
		doneProcessing();
	}
}

function checkTTDYK() {
	// finds the current nomination
	// can jump to a section if it shows up in the URL (i.e. http://en.wikipedia.org/wiki/T:TDYK#Older_nominations)
	// prepares for scan and passes info to checkHooks() and scanArticle() (through pit stop)
	
	onTTDYK = true;
	if (sections == null) {
		sections = document.getElementsByTagName("h4");
		nextSection = 0;
	}
	// Jumping code
	if (window.location.hash) {
		var sectionAt = window.location.hash;
		if (sectionAt != urlJump) {
			var jump = document.getElementById(sectionAt.substring(1, sectionAt.length));
			var next = jump.parentNode.nextSibling;
			while (next.nodeName.toLowerCase() != "h4") {
				next = next.nextSibling;
			}
			for (var i=0; i < sections.length; i++) {
				if (sections[i] == next) {
					nextSection = i;
					urlJump = sectionAt;
					break;
				}
			}
		}
	}
	
	if (nextSection == sections.length) {
		alert("Reached end of nominations; looping to beginning");
		nextSection = 0;
	}
	if (document.getElementById("dyk-stats-0")) {
		clearStats();
	}
	var firstOutput = document.createElement("ul");
	firstOutput.id = "dyk-stats-0";
	sections[nextSection].parentNode.insertBefore(firstOutput, sections[nextSection].previousSibling);
	var hook = checkHooks(firstOutput);
	if (!hook) {
		var errorDisp = document.createElement("div");
		errorDisp.id = "error-disp";
		errorDisp.style.cssText = 'color:red; font-weight:bold;';
		errorDisp.innerHTML = 'Error: Hook is not formatted correctly';
		firstOutput.parentNode.insertBefore(errorDisp, firstOutput);
		nextSection++;
		return;
	}
	createHeaderAndProcessing(document.getElementById("dyk-stats-0"));
	var tempHolder = document.createElement("div");
	tempHolder.id = "temp-holder";
	tempHolder.innerHTML = hook;
	var bolded = tempHolder.getElementsByTagName("b");
	articleTitlesTemp = new Array(bolded.length);
	var titlesCounter = 0;
	for (var i=0; i < bolded.length; i++) {
		var links = bolded[i].getElementsByTagName("a");
		if (links.length > 0) {
			for (var j=0; j < links.length; j++) {
				var title = links[j].getAttribute("title");
				articleTitlesTemp[titlesCounter] = title;
				titlesCounter++;
			}
		} else {
			var pointer = bolded[i];
			while (pointer != tempHolder) {
				if (pointer.nodeName.toLowerCase() == "a") {
					var title = pointer.getAttribute("title");
					articleTitlesTemp[titlesCounter] = title;
					titlesCounter++;
				}
				pointer = pointer.parentNode;
			}
		}
	}
	currentTitle = 0;
	articleTitles = new Array(titlesCounter);
	var hookOutput = document.getElementById("hook-container");
	for (var i=0; i < titlesCounter; i++) {
		var output;
		if (i == 0) {
			output = firstOutput;
		} else {
			output = document.createElement("ul");
			output.id = "dyk-stats-" + i;
			hookOutput.parentNode.insertBefore(output, hookOutput);
		}
		var articleDisp = document.createElement("li");
		articleDisp.id = "article-title" + i;
		output.appendChild(articleDisp);
		articleDisp.innerHTML = '<b>Article ' + (i+1) + ':</b> ' + articleTitlesTemp[i];
		articleTitles[i] = articleTitlesTemp[i];
	}
	if (titlesCounter == 1) {
		document.getElementById("article-title0").innerHTML = '<b>Article:</b> ' + articleTitles[0];
	} else if (titlesCounter == 0) {
		if (document.getElementById("dyk-processing")) {
			var processing = document.getElementById("dyk-processing");
			processing.parentNode.removeChild(processing);
		}
		var errorDisp = document.createElement("div");
		errorDisp.id = "error-disp";
		errorDisp.style.cssText = 'color:red; font-weight:bold;';
		errorDisp.innerHTML = 'Error: The nominated article must appear in bold';
		sections[nextSection].parentNode.insertBefore(errorDisp, firstOutput);
		nextSection++;
		return;
	}
	nextSection++;
	redirectPitStop(articleTitles[0], firstOutput, 0);
}

function checkHooks(output) {
	// gets the nomination section (complete with comments, etc) and passes this to helper function
	var hookOutput = document.createElement("ul");
	hookOutput.id = "hook-container";
	output.parentNode.insertBefore(hookOutput, output.nextSibling);
	var bodyHTML = getBody().innerHTML;
	var thisSection;
	if (nextSection != sections.length - 1) {
		thisSection = bodyHTML.substring(bodyHTML.indexOf(sections[nextSection].innerHTML) + sections[nextSection].innerHTML.length, 
				bodyHTML.indexOf(sections[nextSection+1].innerHTML));
	} else {
		thisSection = bodyHTML.substring(bodyHTML.indexOf(sections[nextSection].innerHTML) + sections[nextSection].innerHTML.length, 
				bodyHTML.indexOf('NewPP limit report'));
	}
	thisSection = thisSection.replace('that,', 'that ').replace('...that ', '... that ');
	if (thisSection.indexOf("5x expan") != -1) {
		nom5x = true;
	} else {
		nom5x = false;
	}
	return checkHooksHelper(hookOutput, thisSection, 0);
}

function checkHooksHelper(hookOutput, whatsLeft, num) {
	// recursively finds proposed hooks for a nom
	// identifies hooks starting with " ... that " and ending with "?"
	// does not count "... " or "(pictured)" in hook character count
	var questionIndex = whatsLeft.indexOf("?");
	var whatsLeftLowerCase = whatsLeft.toLowerCase();
	while ((whatsLeftLowerCase.indexOf("<a ", questionIndex) > 
			whatsLeftLowerCase.indexOf("</a>", questionIndex)) || 
			((whatsLeftLowerCase.indexOf("<a ", questionIndex) == -1) && 
			(whatsLeftLowerCase.indexOf("</a>", questionIndex) != -1)) ||
			(whatsLeftLowerCase.indexOf("<i>", questionIndex) > 
			whatsLeftLowerCase.indexOf("</i>", questionIndex)) || 
			((whatsLeftLowerCase.indexOf("<i>", questionIndex) == -1) && 
			(whatsLeftLowerCase.indexOf("</i>", questionIndex) != -1))) {
		questionIndex = whatsLeft.indexOf("?", questionIndex + 1);
	}
	if (whatsLeft.indexOf("... that ") != -1 && questionIndex != -1) {
		if (whatsLeft.indexOf("... that ") < questionIndex) {
			var hook = whatsLeft.substring(whatsLeft.indexOf("... that ") + 4, 
					questionIndex + 1);
			var hookTemp = document.createElement("div");
			hookTemp.id = "hook-temp";
			hookTemp.innerHTML = "<p>" + hook + "</p>";
			var hookLength = calculateProse(hookTemp, false);
			if (hookTemp.innerHTML.indexOf("pictured)") != -1 || 
					hookTemp.innerHTML.indexOf("(pictured") != -1) {
				hookLength = hookLength - 10;
			}
			var hookDisp = document.createElement("li");
			hookDisp.id = "hooks-" + num;
			if (num == 0) {
				hookDisp.innerHTML = '<b>Original Hook:</b> ' + hookLength + ' characters';
			} else {
				hookDisp.innerHTML = '<b>Alternate Hook '+num+'</b>: '+hookLength+' characters';
			}
			if (hookLength > hookLengthRed) {
				hookDisp.style.cssText = 'background-color:pink';
			} else if (hookLength > hookLengthYellow) {
				hookDisp.style.cssText = 'background-color:yellow';
			}
			hookOutput.appendChild(hookDisp);
			num = num + 1;
		}
		var parsed = whatsLeft.substring(questionIndex + 1, whatsLeft.length - 1);
		var lastHook = checkHooksHelper(hookOutput, parsed, num);
		if (!lastHook && hook) {
			lastHook = hook;
		}
		return lastHook;
	}
	return;
}

function redirectPitStop(title, output, i) {
	// checks if the nominated article is a redirect, passes info to checkTitle()
	var api = sajax_init_object();
	api.open('GET', wgScriptPath + '/api.php?action=query&titles=' + title + '&redirects&format=xml', true);
	api.onreadystatechange = function() {
		if (api.readyState  == 4) {
			if (api.status  == 200) {
				var response = api.responseXML.documentElement;
				var rs = response.getElementsByTagName("r");
				if (rs[0]) {
					title = rs[0].getAttribute("to");
				}
				checkTitle(title, output, i);
			} else {
				alert("XML error");
			}
		}
	};
	api.send(null);
}

function checkTitle(title, output, i) {
	// gets the given title from Wikipedia's server and passes it to scanArticle()
	var normalizedTitle = title.replace(/\%/g,"%25").replace(/\+/g, "%2B").replace(/\//g,"%2F");
	normalizedTitle = normalizedTitle.replace(/\?/g,"%3F").replace(/\#/g,"%23").replace(/\&/g,"%26");
	var api = sajax_init_object();
	api.open('GET', wgScriptPath + '/index.php?title=' + normalizedTitle + '&action=render', true);
	api.onreadystatechange = function() {
		if (api.readyState  == 4) {
			if (api.status  == 200) {
				var ttdykTemp = document.createElement("div");
				ttdykTemp.id = "ttdyk-temp" + i;
				ttdykTemp.innerHTML = api.responseText;
				scanArticle(normalizedTitle, output, ttdykTemp);
			} else {
				alert("XML error");
			}
		}
	};
	api.send(null);
}

function clearStats() {
	// if scan results already exist, turn them off and remove highlighting
	if (!onTTDYK) {
		var oldStyle = document.getElementById("dyk-stats-0").className;
		var mainContent = getBody();
		var pList = mainContent.getElementsByTagName("p");
		for (var i=0; i < pList.length; i++) {
			if (pList[i].parentNode == mainContent) pList[i].style.cssText = oldStyle;
		}
	}
	if (document.getElementById("error-disp")) {
		var errorDisp = document.getElementById("error-disp");
		errorDisp.parentNode.removeChild(errorDisp);
	}
	var i=0;
	while (document.getElementById("dyk-stats-" + i)) {
		var output = document.getElementById("dyk-stats-" + i);
		output.parentNode.removeChild(output);
		i++;
	}
	if (document.getElementById("hook-container")) {
		var hookOutput = document.getElementById("hook-container");
		hookOutput.parentNode.removeChild(hookOutput);
	}
	if (document.getElementById("dyk-header")) {
		var header = document.getElementById("dyk-header");
		header.parentNode.removeChild(header);
	}
	if (document.getElementById("dyk-processing")) {
		var processing = document.getElementById("dyk-processing");
		processing.parentNode.removeChild(processing);
	}
}

function calculateProse(doc, highlight) {
	// calculates the prose of a given document
	// this function and its helper below are modified versions of
	// the prosesize tool (http://en.wikipedia.org/wiki/User:Dr_pda/prosesize.js)
	var pList = doc.getElementsByTagName("p");
	var prose_size = 0;
	for (var i=0; i < pList.length; i++) {
		if (pList[i].parentNode == doc) {
			prose_size += getReadable(pList[i], highlight);
			if (!onTTDYK && highlight) {
				pList[i].style.cssText = 'background-color:yellow';
			}
		}
	}
	return prose_size;
}

function getReadable(id, dehighlight) {
	// helper method for calculateProse()
	var textReadable = 0;
	for (var i=0; i < id.childNodes.length; i++) {
		if (id.childNodes[i].nodeName == '#text') {
			textReadable += id.childNodes[i].nodeValue.length;
		} else if (id.childNodes[i].className != 'reference' && id.childNodes[i].id != 'coordinates') {
			textReadable += getReadable(id.childNodes[i], dehighlight);
		} else if (dehighlight) { //if the node's className is reference
			if (document.getElementById("dyk-stats-0").className != "") {
				id.childNodes[i].style.cssText = document.getElementById("dyk-stats-0").className;
			} else {
				id.childNodes[i].style.cssText = 'background-color:white';
			}	
		}
	}
	return textReadable;
}

function checkExpansion(title, output, current) {  
	// finds the start of expansion date (last 500 edits)
	// gets the last 500 unique revision ids for past revisions of the article and passes to helper function
	var api = sajax_init_object();
	api.open('GET', wgScriptPath + '/api.php?action=query&prop=revisions&titles=' + 
			title + '&&rvlimit=500&rvprop=ids|timestamp&rvdir=older&format=xml', true);
	api.onreadystatechange = function() {
		if (api.readyState  == 4) {
			if (api.status  == 200) {
				var expandTemp = document.createElement("div");
				expandTemp.id = "expand-temp";
				var response = api.responseXML.documentElement;
				var revIds = response.getElementsByTagName('rev');
				checkExpansionHelper(title, current, output, expandTemp, revIds, 0, revIds.length-1, -1);
			} else {
				alert("XML error");
			}
		}
	};
	api.send(null);
}

function checkExpansionHelper(title, current, output, expandTemp, revIds, min, max, expandIndex) {
	// helper for expansion check, used recursively
	// searches for start of expansion date using a binary search algorithm
	// assumes the article has been more or less increasing in size all the time
	// if the article length has yoyo-ed, this function won't give accurate results
	var mid = Math.ceil((max + min)/2);
	if ((((max - min) < 2) && (max != revIds.length - 1 || expandIndex != -1)) || expandIndex == -2) {
		var expandResult = document.createElement("li");
		expandResult.id = "expand-result";
		output.appendChild(expandResult);
		if (expandIndex < 0) {
			if (revIds.length == 500) {
				expandResult.innerHTML = 'Article has not been expanded 5x in the last 500 edits';
			} else {
				expandResult.innerHTML = 'Article has not been expanded 5x since it was created';
			}
		} else {
			var date = revIds[expandIndex-1].getAttribute('timestamp');
			expandResult.innerHTML = 'Assuming article is at 5x now, expansion began ' + 
					expandIndex + ' edits ago on ' + toNormalDate(date.substring(0,10));
			dates[2] = toDateObject(date);
		}
		partsProcessing[3] = true;
		doneProcessing();
		return;
	} else if ((max - min) < 2 && max == revIds.length - 1) {
		expandIndex = -2;
	}
	var api = sajax_init_object();
	api.open('GET', wgScriptPath + '/index.php?title=' + title + 
			'&action=render&redirect=no&oldid=' + revIds[mid].getAttribute('revid'), true);
	api.onreadystatechange = function() {
		if (api.readyState  == 4) {
			if (api.status  == 200) {
				expandTemp.innerHTML = api.responseText;
				var prose = calculateProse(expandTemp, false);
				// alert("Prose: " + prose + " 1x: " + current/5 + " Mid: " + mid + " Expand index: " + expandIndex); 
				// use above line to debug the expansion check
				if (prose < (current/5.0)) {
					if ((expandIndex > mid) || (expandIndex < 0)) {
						expandIndex = mid;
					}
					checkExpansionHelper(title, current, output, expandTemp, revIds, min, mid, expandIndex);
				} else {
					checkExpansionHelper(title, current, output, expandTemp, revIds, mid, max, expandIndex);
				}
			} else {
				alert("XML error");
				partsProcessing[3] = true;
				doneProcessing();
			}
		}
	};
	api.send(null);
}

function checkTalk(title, output) { 
	// checks the talk page of the article for DYK, ITN, or stub templates
	if (wgNamespaceNumber != 2) {
		title = "Talk:" + title;
	} else {
		title = title.replace("User:", "User talk:");
	}
	var api = sajax_init_object();
	api.open('GET', wgScriptPath + '/api.php?action=query&prop=revisions&format=xml&titles=' + 
			title + '&rvprop=content', true);
	api.onreadystatechange = function() { 
		if (api.readyState  == 4) {
			if (api.status  == 200) {
				var response = api.responseXML.documentElement;
				var revisions = response.getElementsByTagName('rev');
				var talkPage = revisions[0].firstChild.nodeValue;
				var result = '';
				var color = 'yellow';
				if ((talkPage.indexOf('class=stub') != -1 || talkPage.indexOf('class=Stub') != -1) && 
						(document.getElementById("stub-alert") == null)) {
					result += 'Article is classified as a stub ';
				}
				if (talkPage.indexOf('{{dyktalk') != -1) {
					result += 'Article has appeared on Did You Know before ';
					color = 'pink';
				}
				if (talkPage.indexOf('{{ITNtalk') != -1) {
					result += 'Article has appeared on In The News before ';
					color = 'pink';
				}
				if (result != '') {
					var talkResult = document.createElement("li");
					talkResult.id = "talk-result";
					output.appendChild(talkResult);
					talkResult.innerHTML = result;
					talkResult.style.cssText = 'background-color:' + color;
				}
				partsProcessing[0] = true;
				doneProcessing();
			} else {
				alert("XML error");
				partsProcessing[0] = true;
				doneProcessing();
			}
		} else {
			partsProcessing[0] = true;
			doneProcessing();
		}
	};
	api.send(null);
}

function getFirstRevision(title, output) {
	// finds the creator of the article, and the date created
	// also checks if the article was created as a redirect, finds non-redirect date if so
	var created = document.createElement("li");
	created.id = "creation-info";
	output.appendChild(created);
		
	var api = sajax_init_object();
	api.open('GET', wgScriptPath + '/api.php?action=query&prop=revisions&format=xml&titles=' + 
			title + '&rvlimit=4&rvprop=timestamp|user|content&rvdir=newer&redirect=no', true);
	api.onreadystatechange = function() { 
		if (api.readyState  == 4) {
			if (api.status  == 200) {
				var response = api.responseXML.documentElement;
				var revisions = response.getElementsByTagName('rev');
				var user = revisions[0].getAttribute('user');
				var timestamp = revisions[0].getAttribute('timestamp');
				created.innerHTML='<b>Article created </b> by ' + user + 
						' on ' + toNormalDate(timestamp.substring(0,10));
				dates[0] = toDateObject(timestamp);
				for (var i=0; i < revisions.length; i++) {
					if (revisions[i].firstChild) {
						var content = revisions[i].firstChild.nodeValue.replace(' ', '').replace(':', '').toUpperCase();
						if (content.indexOf('#REDIRECT[[') != -1 && i == 0) {
							created.innerHTML = created.innerHTML + ' as a redirect';
						} else if (content.indexOf('#REDIRECT[[') == -1) {
							if (i != 0) {
								var unRedirect = document.createElement("li");
								unRedirect.id = "expanded-from-redirect";
								output.appendChild(unRedirect);
								var urUser = revisions[i].getAttribute('user');
								var urTimestamp = revisions[i].getAttribute('timestamp');
								unRedirect.innerHTML = 'Article became a non-redirect on ' + 
										toNormalDate(urTimestamp.substring(0,10)) + ' by ' + urUser;
								dates[0] = toDateObject(urTimestamp);
							}
							break;
						}
					}
				}
				partsProcessing[1] = true;
				doneProcessing();
			} else {
				alert("XML error");
				partsProcessing[1] = true;
				doneProcessing();
			}
		}
	};
	api.send(null);
}

function checkMove(title, output) { 
	//checks the last 100 edits of an article for a move from userspace to current location
	var api = sajax_init_object();
	api.open('GET', wgScriptPath + '/api.php?action=query&prop=revisions&format=xml&titles=' + 
			title + '&rvlimit=100&rvprop=flags|timestamp|comment&rvdir=older', true);
	api.onreadystatechange = function() { 
		if (api.readyState  == 4) {
			if (api.status  == 200) {
				var response = api.responseXML.documentElement;
				var revisions = response.getElementsByTagName('rev');
				for (var i=0; i < revisions.length; i++) {
					if (revisions[i].getAttribute('comment')) {
						var comment = revisions[i].getAttribute('comment');
						if ((revisions[i].getAttribute('minor') == "") && (comment.substring(0,13) == "moved [[User:") 
								&& (comment.indexOf("to [[") != -1)) {
							var movedFrom = comment.substring(8, comment.indexOf("to [[") - 3);
							var date = revisions[i].getAttribute('timestamp');
							var moved = document.createElement("li");
							moved.id = "moved-userspace";
							output.appendChild(moved);
							moved.innerHTML = '<b>Article moved</b> from ' + movedFrom + 
									' on ' + toNormalDate(date.substring(0,10));
							dates[1] = toDateObject(date);
							break;
						}
					}
				}
				partsProcessing[2] = true;
				doneProcessing();
			} else {
				alert("XML error");
				partsProcessing[2] = true;
				doneProcessing();
			}
		}
	};
	api.send(null);
}

function doneProcessing() {
	// checks if all parts are done processing
	// if they are, the dates of creation and expansion are checked for within 10 days (rounded down, in nominator's favor)
	// then the next title (for multiple article noms) is processed (required to combat asynchronous threads)
	// if there are no more titles left (or not on T:TDYK), the processing message is removed
	var titleComplete = true;
	// for (i=0; i < partsProcessing.length; i++) {
		// if (partsProcessing[i] != true) {
			// titleComplete = false;
			// break;
		// }
	// }
	if (document.getElementById("dyk-processing") && titleComplete) {
		var curDate = new Date();
		var round1Winner = new Date();
		var winner = new Date();
		// if (dates[1]) {
			// round1Winner = dates[1]; 
		// } else {
			// round1Winner = dates[0];
		// }
		// if (dates[2] > round1Winner) {
			// winner = dates[2];
		// } else {
			// winner = round1Winner;
		// }
		// var dateDifference = Math.floor((curDate.getTime() - winner.getTime())/(1000*60*60*24));
		// if (dateDifference > 10) {
			// var output = document.getElementById("dyk-stats-" + currentTitle);
			// var notRecent = document.createElement("li");
			// notRecent.id = "not-recent";
			// output.appendChild(notRecent);
			// if (!onTTDYK || (check5xNoms == "always") || (check5xNoms == "ifnom5x" && nom5x)) {
				// notRecent.innerHTML = "Article has not been created or expanded 5x within the past 10 days (" + 
						// dateDifference + " days)" + " <small>DYKcheck does not account for previous versions with " +
						// '<a href="http://en.wikipedia.org/wiki/Wikipedia:Split">splits</a> or ' +
						// '<a href="http://en.wikipedia.org/wiki/Wikipedia:Copyright_violations">copyright violations</a>.</small>';
			// } else {
				// notRecent.innerHTML = "Article was not created within the past 10 days (" + dateDifference + " days)";
			// }
			// notRecent.style.cssText = 'background-color:pink';
		// }
		// if (onTTDYK && currentTitle < (articleTitles.length - 1)) {
			// currentTitle++;
			// redirectPitStop(articleTitles[currentTitle], 
					// document.getElementById("dyk-stats-" + (currentTitle)), currentTitle);
		// } else {
			var processing = document.getElementById("dyk-processing");
			processing.parentNode.removeChild(processing);
		// }
	}
}

function getBody() { 
	// gets the HTML body of the page
	// taken from the prosesize tool (http://en.wikipedia.org/wiki/User:Dr_pda/prosesize.js)
	var contentName;
	if (skin == 'monobook' || skin == 'chick' || skin == 'myskin' || skin == 'simple') {
		contentName = 'bodyContent';
	} else if (skin == 'modern') {
		contentName = 'mw_contentholder';
	} else if (skin == 'standard' || skin == 'cologneblue' || skin == 'nostalgia') {
		contentName = 'article';
	} else {
		// fallback case; the above covers all currently existing skins
		contentName = 'bodyContent';
	}
	// Same for all skins if previewing page
	if (wgAction == 'submit') contentName = 'wikiPreview';
	return document.getElementById(contentName);
}

function createHeaderAndProcessing(output) { 
	// makes the header above the scan results
	var header = document.createElement("span");
	header.id = "dyk-header";
	header.innerHTML = '<b><br/>DYK eligibility scan results: <small><i>(See <a href="http://en.wikipedia.org/wiki/' + 
			'User:Shubinator/DYKcheck">here</a> for details.)<i></small></b>';
	output.parentNode.insertBefore(header,output);
	var processing = document.createElement("span");
	processing.id = "dyk-processing";
	processing.innerHTML = '<br /><b><font color="crimson"> Processing... </font></b>';
	output.parentNode.insertBefore(processing, header);
}

function toNormalDate(utc) { 
	// converts the date part of a Wikipedia timestamp to a readable date
	var months=new Array("blank","January","February", "March", "April", "May", "June", 
			"July", "August", "September", "October", "November", "December");
	if (dateFormat == "british") {
		return (utc.substring(8,10) * 1) + ' ' + months[utc.substring(5,7) * 1] + ' ' + utc.substring(0,4);
	} else {
		return months[utc.substring(5,7) * 1] + ' ' + (utc.substring(8,10) * 1) + ', ' + utc.substring(0,4);
	}
}

function toDateObject(timestamp) { 
	// converts a Wikipedia timestamp to a Javascript Date object
	var date = new Date();
	date.setUTCFullYear(timestamp.substring(0,4), timestamp.substring(5,7) - 1, timestamp.substring(8,10));
	date.setUTCHours(timestamp.substring(11,13), timestamp.substring(14,16), timestamp.substring(17,19));
	return date;
}

function fixSidebar() { // part of the code to fix the sidebar; the rest is below the addOnloadHook function
	var content = document.getElementById("column-content");    // Find the main content column

	var footer = document.getElementById("footer");  // Find the footer
	footer.parentNode.removeChild(footer);    // Remove the footer from the global wrapper
	content.appendChild(footer);    // Place footer at the end of the content column;

	var tabs = document.getElementById("p-cactions");   // Find the top tab list
	tabs.parentNode.removeChild(tabs);    // Remove the tab list from the side column
	content.insertBefore(tabs,content.firstChild);    // Place tab list at the beginning of the content column

	var personal = document.getElementById("p-personal");   // Find the personal links list
	personal.parentNode.removeChild(personal);    // Remove the personal links list from the side column
	content.insertBefore(personal,content.firstChild);    // Place personal links list at the beginning of the content column
}

function dykCheck() { 
	// this function for casual use and anons
	if (((wgAction == 'view' || wgAction == 'submit' || wgAction == 'purge') && 
			(wgNamespaceNumber == 0 || wgNamespaceNumber == 2)) || unlock) {
		checkDocument();
	} else if (wgPageName == 'Template_talk:Did_you_know') {
		checkTTDYK();
	}
}

addOnloadHook(function () {
	if (((wgAction == 'view' || wgAction == 'submit' || wgAction == 'purge') && 
			(wgNamespaceNumber == 0 || wgNamespaceNumber == 2)) || unlock) {
		mw.util.addPortletLink('p-tb', 'javascript:checkDocument()', 'Word count', 
				't-dyk-check', 'Provide a word count', '', '');
	} else if (wgPageName == 'Template_talk:Did_you_know') {
		mw.util.addPortletLink('p-tb', 'javascript:checkTTDYK()', 'DYK check', 
				't-dyk-check', 'Check DYK nominations for eligibility', '', '');
	}
	if (wgUserName != null && (fixedSidebar == "always" || (fixedSidebar == "onttydk" 
			&& wgPageName == 'Template_talk:Did_you_know'))) {
		fixSidebar();
	}
});

// The code below for the fixed sidebar is a blend of two sources:
//		http://meta.wikimedia.org/wiki/Help:User_style/floating_quickbar 
// 		http://en.wikipedia.org/wiki/User:Omegatron/monobook.js/floatingSidebar.js
// None of the code below was written by me (Shubinator)

// This CSS should be hidden from older versions of IE using javascript instead of the attribute selector?

// Include style sheet inline so that script is self-contained:
if (wgUserName != null && (fixedSidebar == "always" || (fixedSidebar == "onttydk" 
		&& wgPageName == 'Template_talk:Did_you_know'))) {
document.write('<style type="text/css">' +
 
"   /* Fix the sidebar's position while you scroll */                           "+
'   div[id=column-one] {   /* Using the attribute selector hides this from IE */'+
'       position: fixed;                                                        '+
'       height: 100%;       /* If you shrink the browser too small, the     */  '+
'       overflow: auto;     /* side column will become scrollable, so stuff */  '+
'       z-index: 2;         /* is always accessible, albeit ugly            */  '+
'   }                                                                           '+
'                                                                               '+
'   #p-logo {               /* Make logo inline with other divs             */  '+
'       position:static;                                                        '+
'   }                                                                           '+
'                                                                               '+
'   #column-one {           /* Sidebar column start at the top screen edge  */  '+
'       padding-top: 0;                                                         '+
'   }                                                                           '+
'                                                                               '+
'   #p-lang .pBody ul{      /* Sets the language box to a fixed height and  */  '+
'       height: 6em;        /* scrollable if too long to fit on screen      */  '+
'       overflow: auto;                                                         '+
'   }                                                                           '+
'                                                                               '+
'   /* Fix the background image, too, so it looks nice as you scroll */         '+
'   body {                                                                      '+
'       background-attachment: fixed;                                           '+
'   }                                                                           '+
'                                                                               '+
"   /* Fix the footer so it looks nice and doesn't overlap the sidebar */       "+
'   #footer {                                                                   '+
'       margin-left: 13.6em;                                                    '+
'       border-left: solid 1px rgb(250, 189, 35);                               '+
'       -moz-border-radius-topleft: 1em;                                        '+
'       -moz-border-radius-bottomleft: 1em;                                     '+
'   }                                                                           '+
'                                                                               '+
'	/* Keep personal links at the top right */				'+
'	#p-personal {								'+
'		width:100%;							'+
'		white-space:nowrap;						'+
'		padding:0 0 0 0;						'+
'		margin:0;							'+
'		position:absolute;						'+
'		left:0px;							'+
'		top:0px;							'+
'		z-index: 0;							'+
'		border: none;							'+
'		background: none;						'+
'		overflow: visible;						'+
'		line-height: 1.2em;						'+
'	}									'+
'										'+
'	#p-personal h5 {							'+
'		display:none;							'+
'	}									'+
'	#p-personal .portlet,							'+
'	#p-personal .pBody {							'+
'		padding:0;							'+
'		margin:0;							'+
'		border: none;							'+
'		z-index:0;							'+
'		overflow: visible;						'+
'		background: none;						'+
'	}									'+
'	/* this is the ul contained in the portlet */				'+
'	#p-personal ul {							'+
'		border: none;							'+
'		line-height: 1.4em;						'+
'		color: #2f6fab;							'+
'		padding: 0em 2em 0 3em;						'+
'		margin: 0;							'+
'		text-align: right;						'+
'		text-transform: lowercase;					'+
'		list-style: none;						'+
'		z-index:0;							'+
'		background: none;						'+
'	}									'+
'	#p-personal li {							'+
'		z-index:0;							'+
'		border:none;							'+
'		padding:0;							'+
'		display: inline;						'+
'		color: #2f6fab;							'+
'		margin-left: 1em;						'+
'		line-height: 1.2em;						'+
'		background: none;						'+
'	}									'+
'	#p-personal li a {							'+
'		text-decoration: none;						'+
'		color: #005896;							'+
'		padding-bottom: 0.2em;						'+
'		background: none;						'+
'	}									'+
'	#p-personal li a:hover {						'+
'		background-color: White;					'+
'		padding-bottom: 0.2em;						'+
'		text-decoration: none;						'+
'	}									'+
'										'+
'<'+'/style>');
}

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.