User:Colin Hill/monobook.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
The accompanying .css page for this skin can be added at User:Colin Hill/monobook.css. |
// BetterHistory v0.6
// Copyright (c) 2005 by Colin Hill (colin@colinhill.us)
// This is 100% free code. Use it for anything.
// Arrays to hold revision info
oldids=new Array(100);
revisions=new Array(100);
var title="Error";
var offset=0;
// Object that will soon be the slider button
var handleImg;
// Diff status (determines which pages to request)
// 0 Current revision html
// 1 Diff w/ most recent revision
// 2 Diff w/ previous revision
// 3 Raw wikicode (doesn't work in Opera yet)
var diffStatus = 0;
/* Updates diff status */
function ChangeDiffStatus(newStatus)
{
if(diffStatus != newStatus){
diffStatus=newStatus;
SetArticle(currentArticle);
}
else
diffStatus=newStatus;
}
/* Returns an XMLHttpRequest object */
function CreateXMLHTTPObject(){
var object=false;
// Internet Explorer
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try{
object = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e){
try{
object = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e2){
object = false;
}
}
@end @*/
// Other UAs
if(!object && typeof XMLHttpRequest!='undefined'){
object = new XMLHttpRequest();
}
return object;
}
function NullPage(){
return '<br /><center>This is the end.<br /><br />'+
'<a href="http://en.wikipedia.org/wiki/Special:BetterHistory?article='+title+'&offset='+(offset-100)+'">Go forward 100 revisions.</a><br />'+
'<a href="http://en.wikipedia.org/wiki/Special:BetterHistory?article='+title+'&offset='+(offset-(-100))+'">Go back 100 revisions.</a>'+
'</center>';
}
/* Extract & format revision strings from history page */
function ExtractRevisions(string)
{
// Extract revision strings
var insideTagPair=false;
var substring="";
var currentRevision = 0;
for(i=0; i<string.length; i++){
// Start of tag pair?
if(!insideTagPair){
if((""+string.charAt(i)) == "<")
if(string.substr(i, 4) == "<li>"){
// Skip past the starting li tag
i+=3; // strlen("<li>")
insideTagPair=true;
continue;
}
}
// End of tag pair?
else{
// Check for ending tag
if((""+string.charAt(i)) == "<")
if(string.substr(i, 5) == "</li>"){
// Append the extracted revision to the array
revisions[currentRevision] = substring;
currentRevision++;
substring="";
insideTagPair=false;
continue;
}
}
// Append current char?
if(insideTagPair)
substring+=string.charAt(i);
}
// Remove all the radio buttons from the strings
for(x=0; x<100; x++){
var blanking=false;
var temp="";
currentRevision=revisions[x]
for(i=0; i<currentRevision.length; i++){
// Not blanking?
if(!blanking){
// Start blanking?
if(currentRevision.substr(i, 7) == "<input ")
blanking=true;
// Continue not blanking
else
temp+=currentRevision.charAt(i);
}
// Blanking
else {
// Check for ending tag
if((""+currentRevision.charAt(i)) == "/")
if((""+currentRevision.charAt(i+1)) == ">"){
// Skip last char of the tag
i++;
// Stop blanking chars
blanking=false;
}
}
}
revisions[x]=temp;
}
// Extract oldids, add to array
var matches=null;
var validRevision = new RegExp("oldid=([0-9]+)");
for(i=0; i<100; i++)
if(matches = validRevision.exec(revisions[i]))
oldids[i]=matches[1];
}
/* Extracts articles from surrounding html */
function ExtractArticle(string)
{
var firstChar = string.indexOf("<!-- start content -->");
var lastChar = string.indexOf("<!-- end content -->");
return string.substring(firstChar, lastChar);
}
var currentArticle;
/* Download & show an article */
function SetArticle(oldidIndex)
{
currentArticle=oldidIndex;
var xmlhttp = CreateXMLHTTPObject();
document.getElementById("articleHTML").innerHTML="<br /><center><b>Loading...</b></center>";
// Diff w/ most recent revision
if(diffStatus == 1)
xmlhttp.open("GET", "http://en.wikipedia.org/w/index.php?title="+title+"&diff=0&oldid="+oldids[oldidIndex], true);
// Diff w/ previous revision
else if((diffStatus == 2) && oldids[oldidIndex] && oldids[oldidIndex+1])
xmlhttp.open("GET", "http://en.wikipedia.org/w/index.php?title="+title+"&diff="+oldids[oldidIndex]+"&oldid="+oldids[oldidIndex+1], true);
// This revision's wikicode
else if(diffStatus == 3)
xmlhttp.open("GET", "http://en.wikipedia.org/w/index.php?title="+title+"&oldid="+oldids[oldidIndex]+"&action=raw", true);
// Selected revision
else
xmlhttp.open("GET", "http://en.wikipedia.org/w/index.php?title="+title+"&oldid="+oldids[oldidIndex], true);
// Function to handle results
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4){
// Show raw if viewing wikicode
if(diffStatus != 3)
document.getElementById("articleHTML").innerHTML=ExtractArticle(xmlhttp.responseText);
else
document.getElementById("articleHTML").innerHTML="<pre>"+xmlhttp.responseText+"</pre>";
// Page resizes when new article loads. Snap onto notch again.
Snap(true);
}
}
// Send request
xmlhttp.send(null);
}
// Keeps track of the mouse button's status
var mousedown=false;
/* Returns the x coordinate of a specific notch */
function NotchCoord(notch){
return 6*notch;
}
/* Returns the number of the nearest slider notch */
function NearestNotch(x){
return Math.round(x/6.0);
}
// Current x pos on the track
currentX = NotchCoord(100);
/* Snaps slider button onto the nearest notch */
function Snap(butDontLoad){
// Get X position of the track
var object=document.getElementById("track");
var trackPos = 0;
while (object.offsetParent){
trackPos += object.offsetLeft
object = object.offsetParent;
}
// Snap to the nearest notch
handleImg.style.left=""+(trackPos+NotchCoord(NearestNotch(currentX))-(12/2))+"px";
// Update the currentX position
currentX=NotchCoord(NearestNotch(currentX));
// Null page
if(NearestNotch(currentX) == 0)
document.getElementById("articleHTML").innerHTML=NullPage();
// Older revision
else
if(!butDontLoad) SetArticle(100-NearestNotch(currentX));
}
/* Moves the slider button to a new position */
function Slideto(x)
{
// If the the mouse isn't dragging the button, return.
if(!mousedown)
return;
// Get X position of the track
var object=document.getElementById("track");
var trackPos = 0;
while (object.offsetParent){
trackPos += object.offsetLeft
object = object.offsetParent;
}
// Too far to the left?
if(x<trackPos){
currentX=0;
handleImg.style.left=""+(trackPos-6)+"px"; // on the mouse pointer
}
// Too far to the right?
else if(x>(trackPos+600)){
currentX=600;
handleImg.style.left=""+(trackPos+600-6)+"px";
}
else{
currentX=x-trackPos;
handleImg.style.left=""+(x-7)+"px";
}
// Show the current revision string
if(NearestNotch(currentX) != 0)
document.getElementById('link').innerHTML = revisions[100-NearestNotch(currentX)];
else
document.getElementById('link').innerHTML = "Change offset?";
}
/* Handles all mouse movement */
function onmousemove_Handler(event){
// Firefox
if(event)
Slideto(event.clientX);
// Internet Explorer & Opera
else
Slideto(window.event.clientX);
}
document.onmousemove=onmousemove_Handler;
/* Handles mouseup events */
function onmouseup_Handler(){
if(mousedown)
Snap(false);
mousedown=false;
}
document.onmouseup=onmouseup_Handler;
function onmousedown_Handler(e){
var focusObject = !document.all ? e.target : event.srcElement;
var topElement = !document.all ? "HTML" : "BODY";
if (focusObject.id=="handleImg"){
mousedown = true;
return false;
}
}
document.onmousedown=onmousedown_Handler;
/* Takes over the page if URL is for certain pages */
function CheckPage(){
// Put a link on the normal history page
var validHistoryURL = new RegExp(".+action=history.*");
if(validHistoryURL.exec(location.href)){
// What article?
var matches;
var titleExp = new RegExp("title=([^&]+)");
if(matches = titleExp.exec(location.href))
title = matches[1];
// Offset?
var matches;
var offsetExp = new RegExp("offset=([^&]+)");
if(matches = offsetExp.exec(location.href))
offset = matches[1];
document.getElementById("contentSub").innerHTML+=' <a href="http://en.wikipedia.org/wiki/Special:BetterHistory?article='+title+'&offset='+offset+'">BetterHistory</a>';
}
validHistoryURL = new RegExp(".+Special:BetterHistory.*");
if(validHistoryURL.exec(location.href)){
// What article to request?
var matches;
var titleExp = new RegExp("article=([^&]+)");
if(matches = titleExp.exec(location.href))
title = matches[1];
// Offset?
var matches;
var offsetExp = new RegExp("offset=([^&]+)");
if(matches = offsetExp.exec(location.href))
offset = matches[1];
// Set window title
document.title=title+" - BetterHistory - Wikipedia, the free encyclopedia"
// Update weird little tab thingie
document.getElementById("ca-article").innerHTML="<a href=\"\">BetterHistory</a>";
document.getElementById("content").style.position="relative";
document.getElementById("content").innerHTML =
// Start of new body content
'<!-- Options -->'+
'<center><table border="0" cellpadding="0" cellspacing="0" width="100%" height="30"><tr><td align="center">'+
'<form><input type="radio" name="diffStatus" checked onclick="ChangeDiffStatus(0);"/>This revision <input type="radio" name="diffStatus" onclick="ChangeDiffStatus(1);"/>Diff w/ most recent <input type="radio" name="diffStatus" onclick="ChangeDiffStatus(2);"/>Diff w/ previous <input type="radio" name="diffStatus" onclick="ChangeDiffStatus(3);"/>Raw wikicode</form>'+
'</td></tr></table></center>'+
'<!-- Header -->'+
'<center><table border="0" cellpadding="0" cellspacing="0" width="75%" height="40"><tr><td align="center"><span id="link">Downloading...</span></td></tr></table></center>'+
'<!-- Slider track -->'+
'<center><img id="track" src="http://gladstone.uoregon.edu/~chill1/betterhistory/slider_track.png"></center>'+
'<!-- Spacer image -->'+
'<div id="spacer" style="position:relative;"><br /></div>'+
'<!-- Article area -->'+
'<div id="articleHTML" style="position:relative;"></div>';
// End of body content
}
// Get X position of the track
var object=document.getElementById("track");
var xPos=0;
var yPos=0;
while (object.offsetParent){
xPos += object.offsetLeft
yPos += object.offsetTop
object = object.offsetParent;
}
// Create the slider button
handleImg=document.createElement('img');
handleImg.style.position="absolute";
handleImg.id="handleImg";
handleImg.style.left=""+(594+xPos)+"px";
handleImg.style.top=""+(6+yPos)+"px";
handleImg.style.zIndex="10000";
handleImg.setAttribute("src", "http://gladstone.uoregon.edu/~chill1/betterhistory/slider_button.gif");
handleImg.ondragstart=function(){window.event.returnValue = false;}
document.body.appendChild(handleImg);
// Create XMLHttpRequest object
var xmlhttp = CreateXMLHTTPObject();
document.getElementById("articleHTML").innerHTML="<br /><center><b>Loading...</b></center>";
// Make request for history page
xmlhttp.open("GET", "http://en.wikipedia.org/w/index.php?title="+title+"&action=history&limit=100&offset="+offset);
// Function to handle results
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4){
ExtractRevisions(xmlhttp.responseText);
document.getElementById('link').innerHTML = revisions[0];
// Set article to current revision
SetArticle(0);
}
}
// Send request
xmlhttp.send(null);
}
window.onload=CheckPage;