Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/* Timetravel, version [0.1.0]
Originally from: http://en.wikipedia.org/wiki/User:Splarka/timetravel.js

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

if(queryString('oldid') && !queryString('timetravel') && !queryString('diff') && 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=addTimetravelButtonCB&revids=' + queryString('oldid');
  mw.loader.load(url);
}

function addTimetravelButtonCB(obj) {
  if(!obj['query'] || !obj['query']['pages'] || !obj['query']['pages'][wgArticleId]) return
  var rev = obj['query']['pages'][wgArticleId]['revisions'];
  if(rev.length == 0) return
  if(rev[0]['revid'] =! queryString('oldid')) return
  var ts = rev[0]['timestamp'];
  mw.util.addPortletLink('p-cactions', mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&oldid=' + queryString('oldid') + '&timetravel=' + ts, 'Time travel');
}

if(queryString('timetravel') && wgAction == 'view') addOnloadHook(engageTimetravelLinks)
function engageTimetravelLinks() {
  appendCSS('a.timetravel { color:#00ff00 !important;} a.ttused {color:#ff0000 !important;} b.timetravel {color:#008800;background-color:#ffff00;border:1px dashed #008800}');
  var note = document.getElementById('contentSub') || document.getElementById('topbar')
  if(note) { 
    var txt = document.createTextNode('Currently time travelling, appropriate time travel links in green.');
    var b = document.createElement('b');
    b.className = 'timetravel';
    b.appendChild(txt);
    note.appendChild(b);
  }
  var docobj = document.body;
  var a = docobj.getElementsByTagName('a');
  for(var i=0;i<a.length;i++) {
    // 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

    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].href = 'javascript:(timetravel("' + queryString('timetravel') + '","' + encodeURIComponent(link) + '",' + i + '))';
    a[i].className += ' timetravel';
    a[i].id = 'ttlink-' + i;
  }
}

function timetravel(date,page,id) {
  var a = document.getElementById('ttlink-' + id);
  a.className += ' ttused';
  a.href = 'javascript:void(0);';
  var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?maxage=300&smaxage=300&action=query&prop=revisions&indexpageids&rvprop=ids&rvlimit=1&rvstart=' + date + '&format=json&callback=timetravelCB&titles=' + page;
  mw.loader.load(url);
}

function timetravelCB(obj) {
  if(!obj['query'] || !obj['query']['pages'] || !obj['query']['pageids']) return
  var pages = obj['query']['pages'];
  var ids = obj['query']['pageids'];
  if(ids.length == 0) return
  var title = '';
  var rev = pages[ids[0]]['revisions'];
  title = pages[ids[0]]['title'];

  if(!rev) {
    //change to redlink later, lazy now
    alert('No such page, or no revisions found that old.\n');
    return;
  }
  if(rev.length == 0) return
  var id = rev[0]['revid'];
  if(id != 0) {
    var url = mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=' + encodeURIComponent(title) + '&oldid=' + id + '&timetravel=' + queryString('timetravel') ;
    window.location.href = url;
  }
}

function queryString(p) {
  var re = RegExp('[&?#]' + p + '=([^&#]*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try { 
      return decodeURI(matches[1]);
    } catch (e) {
    }
  }
  return null;
}