// 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.wiki.x.io/wiki/Special:BetterHistory?article='+title+'&offset='+(offset-100)+'">Go forward 100 revisions.</a><br />'+
'<a href="http://en.wiki.x.io/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.wiki.x.io/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.wiki.x.io/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.wiki.x.io/w/index.php?title="+title+"&oldid="+oldids[oldidIndex]+"&action=raw", true);
// Selected revision
else
xmlhttp.open("GET", "http://en.wiki.x.io/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.wiki.x.io/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.wiki.x.io/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;