Wikipedia:WikiProject User scripts/Scripts/TimeTraveller.js

/* Timetravel, version [0.2.0]

Documentation: Wikipedia:WikiProject User scripts/Scripts/TimeTraveller

Notes:

  • Does not take into account:
  • Old versions of templates, images
  • Moved page titles
  • Renamed users
  • Time-sensitive magic words
  • /

//to be localised

tt_currentrevision = 'Current revision';

tt_history='History';

//

// this code deals with the first access to an old page

// We have the revision id, but not the timetravel timestamp --> need to find it and set tt_timetravel

//

if(queryString('oldid') && !queryString('timetravel') && !queryString('diff') && mw.config.get('wgAction') == 'view') addOnloadHook(addTimetravelButton)

function addTimetravelButton() {

var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?maxage=300&smaxage=300&action=query&prop=revisions&rvprop=timestamp|ids&format=json&callback=addTimetravelCB&revids=' + queryString('oldid');

mw.loader.load(url);

}

var tt_timetravel=false;

function addTimetravelCB(obj) {

if(!obj['query'] || !obj['query']['pages'] || !obj['query']['pages'][mw.config.get('wgArticleId')]) return

var rev = obj['query']['pages'][mw.config.get('wgArticleId')]['revisions'];

var ts ='';

for(var i in rev) {

if(rev[i]['revid'] == queryString('oldid')) {

ts = rev[i]['timestamp'];

}

}

tt_timetravel=ts;

engageTimetravelLinks();

}

//

// this code deals with the old pages accessed from another old one

// We thus have the tt_timetravel parameter

//

if(queryString('timetravel') && mw.config.get('wgAction') == 'view') addOnloadHook(engageTimetravelLinks)

// this is the routine called by the 2 previous cases

function engageTimetravelLinks() {

if(!tt_timetravel) tt_timetravel=queryString('timetravel');

appendCSS('a.timetravel { color:#00ff00 !important;} a.ttused {color:#ff0000 !important;}');

engageTT2 (document.getElementById('bodyContent') || document.getElementById('content') || document.body, "A");

engageTT2 (document.getElementById('p-cactions'), "B");

}

function engageTT2 (docobj, tag) {

if (!docobj) return;

var a = docobj.getElementsByTagName('a');

for(var i=0;i

if (tag=='B' && a[i].innerHTML==tt_history) {

a[i].href=a[i].href + '&offset=' + tt_timetravel.replace(/[^0-9]/g,"");

continue

}

// Exclude: catlinks, extiw/external/new/image, diff/oldid/action, special, http/uri, media?, anchors?, imagemap?

if(a[i].className.search(/(extiw|external|new|image)/ig) != -1) continue

if(a[i].href.search(/(\/wiki\/(Category\:|Special\:)|diff\=|oldid\=|action\=|Special\:Cite)/ig) != -1) continue

if(a[i].innerHTML==tt_currentrevision) continue;

var link = a[i].href;

link = link.replace(mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace(/\$1/,),);

if(link.indexOf('#') != -1) link = link.substr(0,link.indexOf('#'));

if(link.search(/(http|https|file|javascript)\:/ig) == 0) continue

a[i].onmouseover=timetravel;

// a[i].className += ' timetravel';

a[i].id = 'ttlink-' + tag + i;

}

}

//

// this code deals with the mouseOver an anchor

//

var tt_anchor, tt_id; // this may create a problem if several mouseover are fired before they can be fully handled

function timetravel(e) {

//first, let's find the anchor

var targ;

if (!e) var e = window.event;

if (e.target) targ = e.target;

else if (e.srcElement) targ = e.srcElement;

if (targ.nodeType == 3) // defeat Safari bug

targ = targ.parentNode;

var a = targ;

var link = a.href;

// no need to do anything else if it already has timetravel

if (link.indexOf('timetravel=') != -1) {

return

}

// block the href until updated

a.className += ' ttused';

if (link.indexOf('javascript:void("') !=-1) { // this happens when the call back does not happen! Remove it.

link=link.substr( ('javascript:void("').length, link.length- ('javascript:void("').length- ('");').length);

} else {

a.href = 'javascript:void("' + a.href + '");';

}

//set the global variables

link = link.replace(mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace(/\$1/,),);

link = link.replace (/_/g, ' ');

if(link.indexOf('#') != -1) {

tt_anchor=link.substr(link.indexOf('#'))

link = link.substr(0,link.indexOf('#'));

} else {tt_anchor=''};

tt_id=a.id;

//call the API

var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?maxage=300&smaxage=300&action=query&prop=revisions&&rvprop=ids&rvlimit=1&rvstart=' + tt_timetravel + '&format=json&callback=timetravelCB&titles=' + encodeURIComponent(decodeURIComponent(link));

url+= '&rnd=' + Math.random() // add a random element to make sure it is called

mw.loader.load(url);

}

function timetravelCB(obj) {

var a = document.getElementById(tt_id);

if(!obj['query'] || !obj['query']['pages']) return

var pages = obj['query']['pages'];

var rev;

var title = '';

for(var i in pages) {

rev = pages[i]['revisions'];

title = pages[i]['title'];

}

if(!rev) {

//unblock the link

url=a.href.substr( ('javascript:void("').length, a.href.length- ('javascript:void("').length- ('");').length);

a.href=url;

a.className ='';

// alert('No such page, or no revisions found that old.\n');

} else {

a.onmouseover=''; // no need to fire this anymore

var id = 0;

for(var i in rev) {

id = rev[i]['revid'];

}

if(id != 0) {

var url = mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=' + encodeURIComponent(title) + '&oldid=' + id + '&timetravel=' + tt_timetravel +tt_anchor ;

a.href = url;

a.className ='';

}

}

}

function queryString(p) {

var re = RegExp('[&?#]' + p + '=([^&#]*)');

var matches;

if (matches = re.exec(document.location)) {

try {

return decodeURI(matches[1]);

} catch (e) {

}

}

return null;

}

//

// Add links to timestamps in talk pages

//

if (mw.config.get('wgAction') == 'view') addOnloadHook(addDateLinks);

function addDateLinks() {

var newContent = document.getElementById('bodyContent');

if (! newContent || ! newContent.innerHTML || newContent.innerHTML=='') return;

newContent=newContent.innerHTML;

var tt_regDate= /(\d?\d):(\d\d), (\d?\d) (January|February|March|April|May|June|July|August|September|October|November|December|Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d\d\d\d) \(UTC\)/g;

var dates= newContent.match(tt_regDate);

if (!dates || ! dates.length) return;

for (var j=0;j

tt_regDate.lastIndex=0;

var a = tt_regDate.exec(dates[j]);

if (!a) continue;

var dateLink=a[5] +'-'+ tt_2(a[4]) +'-'+ tt_2(a[3]) +'T'+ tt_2(a[1]) +':'+ tt_2(a[2]) + ':59Z';

dateLink=""+ dates[j]+ "";

var r= dates[j].replace("(","\\(");

r = r.replace(")","\\)");

r = new RegExp(r, "g");

newContent=newContent.replace(r, dateLink);

}

document.getElementById('bodyContent').innerHTML=newContent

};

//

// this code deals with the mouseOver an anchor

//

var tt_tentativeDate;

function getURLofThisPageFor(aDate) {

//first, let's find the anchor

var a=document.getElementById(aDate);

if (!a) return;

// no need to do anything else if it already has timetravel

if (a.href.indexOf('timetravel=') != -1) return;

//set the global variables

tt_tentativeDate=aDate;

//call the API

var pageName= mw.config.get('wgPageName').replace (/()\/Archive_[\d]*/,'$1');

var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?maxage=300&smaxage=300&action=query&prop=revisions&&rvprop=ids&rvlimit=1&rvstart=' + aDate + '&format=json&callback=getURLofThisPageCB&titles=' + encodeURIComponent(decodeURIComponent(pageName));

url+= '&rnd=' + Math.random() // add a random element to make sure it is called

mw.loader.load(url);

};

function getURLofThisPageCB (obj) {

if (!tt_tentativeDate) return;

var a = document.getElementById(tt_tentativeDate);

if (!a) return;

if(!obj['query'] || !obj['query']['pages']) return

var pages = obj['query']['pages'];

var rev;

var title='';

for (var i in pages) {

rev = pages[i]['revisions'];

title = pages[i]['title'];

};

if(!rev) {

//unblock the link

url=a.href.substr( ('javascript:void("').length, a.href.length- ('javascript:void("').length- ('");').length);

a.href=url;

a.className ='';

// alert('No such page, or no revisions found that old.\n');

} else {

a.onmouseover=''; // no need to fire this anymore

var id = 0;

for (var i=0;i

id = rev[i]['revid'];

};

title=title.replace (/()\/Archive_[\d]*/,'$1');

if(id != 0) {

var url = mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=' + encodeURIComponent(title) + '&oldid=' + id + '&timetravel=' + tt_tentativeDate ;

a.href = url;

a.className ='';

}

}

};

function tt_2 (s) {

switch (s) {

case '1': return '01';

case '2': return '02';

case '3': return '03';

case '4': return '04';

case '5': return '05';

case '6': return '06';

case '7': return '07';

case '8': return '08';

case '9': return '09';

case 'January': return '01';

case 'February': return '02';

case 'March': return '03';

case 'April': return '04';

case 'May': return '05';

case 'June': return '06';

case 'July': return '07';

case 'August': return '08';

case 'September': return '09';

case 'October': return '10';

case 'November': return '11';

case 'December': return '12';

case 'Jan': return '01';

case 'Feb': return '02';

case 'Mar': return '03';

case 'Apr': return '04';

case 'May': return '05';

case 'Jun': return '06';

case 'Jul': return '07';

case 'Aug': return '08';

case 'Sep': return '09';

case 'Oct': return '10';

case 'Nov': return '11';

case 'Dec': return '12';

default: return s

}

}