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<a.length;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<dates.length;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="<a href=javascript:void('" + dateLink +"') id='" + dateLink +"' onmouseover='getURLofThisPageFor("+ '"'+dateLink+'"'+ ")'>"+ dates[j]+ "</a>";

       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<rev.length;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
 }
}

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.