User:Splarka/contribsmulti.js

From Wikipedia, the free encyclopedia
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.
/* Special:Contributions Multi-user lookup, version [0.0.2a]
Originally from: http://en.wikipedia.org/wiki/User:Splarka/contribsmulti.js

Notes:
* Experimental per: https://bugzilla.wikimedia.org/show_bug.cgi?id=16402
** brion: please make this core, kthx!
* cmLimit is also the default display limit, this is to prevent incorrect/lost data
** Logic goes: if you fetch X contribs for each user, mix and sort by date, and show X total, you don't lose any

*/

if(wgCanonicalSpecialPageName == 'Contributions' && true) { 
  addOnloadHook(multiContribsInit);
  var cmLimit = 500; //max uclimit (500 default) and max display limit;
  var cmMaxU = 5;   //max number of parameters
  var cmTotal;
  var cmList = [];
  var cmIndex = [];
  appendCSS('#results-from-multicontribs {border:1px solid black;padding:.5em}\n.mw-mightexist {font-style:italic;}');
}

function multiContribsInit() {
  var ucfrm = document.getElementsByTagName('form')[0];
  if(!ucfrm.target) return
  var users = ucfrm.target.value.split('|');
  if(users.length < 2) return

  //general optionlets independent of type of search.
  var opt_ns = (parseInt(ucfrm.namespace[ucfrm.namespace.selectedIndex].value) > -1) ? '&ucnamespace=' + ucfrm.namespace[ucfrm.namespace.selectedIndex].value : '';
  var opt_ts = '';
  var m = '' + ucfrm.month.selectedIndex; 
  var y = ucfrm.year.value;
  if(m.length == 1) m = '0' + m
  if(y > 2000 && y < 2100) opt_ts = '&ucstart=' + y + '-' + m + '-01T00:00:00Z'
  var options = opt_ns + opt_ts;

  cmTotal = 0;
  multiContribsStartbox(ucfrm.parentNode);
  for(var i=0;i<users.length;i++) {
    if(i >= parseInt(cmMaxU)) break
    var user = users[i].replace(/(^\W*|\W*$)/g,'');
    if(user == '') continue
    var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?action=query&format=json&callback=multiContribs&list=usercontribs' + options + '&uclimit=' + parseInt(cmLimit) + '&ucuser=' + encodeURIComponent(user) + '&requestid=' + i;
    mw.loader.load(url);
    cmTotal++;
  }
}

function multiContribs(obj) {
  if(!obj['requestid']) return
  var ri = obj['requestid'];
  cmTotal--;
  if(cmTotal == 0) removeSpinner('multicontribs-spin')

  if(!obj['query'] || !obj['query']['usercontribs']) return
  var contribs = obj['query']['usercontribs'];
  for(var i=0;i<contribs.length;i++) {
    //fill global object with all arrays, indexed by timestamp + contrib# + user#
    var index = contribs[i]['timestamp'] + '_' + i + '_' + ri;  
    cmList[index] = contribs[i];
    cmIndex.push(index);
  }
  if(cmTotal == 0) multiContribsShowResults()
}

function multiContribsShowResults() {
  var res = document.getElementById('results-from-multicontribs');
  //sort by date by creating plain index of associative array's index which is made of timestamps (dirty)
  cmIndex.sort(sortReverse);

  if(cmIndex.length == 0) {
    res.appendChild(document.createTextNode('No results found.'));
  }

  //limit display, if you show too many you might miss some
  var length = (cmIndex.length > cmLimit) ? cmLimit : cmIndex.length
  var ul = document.createElement('ul');
  for(var i=0;i<length;i++) {
    var li = document.createElement('li');
     li.appendChild(document.createTextNode(cmList[cmIndex[i]].timestamp.replace(/[TZ]/g,' ') + ''));
     addlinkchild(li, wgScript + '?title=Special:Contributions/' + cmList[cmIndex[i]].user, cmList[cmIndex[i]].user);
     li.appendChild(document.createTextNode(' ('));
     addlinkchild(li, wgScript + '?title=User_talk:' + cmList[cmIndex[i]].user, 'talk','','mw-mightexist');
     li.appendChild(document.createTextNode(') edited ('));
     addlinkchild(li, wgScript + '?title=-&curid=' + cmList[cmIndex[i]].pageid + '&diff=' + cmList[cmIndex[i]].revid , 'diff');
     li.appendChild(document.createTextNode(') '));
     addlinkchild(li, wgScript + '?title=-&curid=' + cmList[cmIndex[i]].pageid, cmList[cmIndex[i]].title);
     if(cmList[cmIndex[i]].comment) li.appendChild(document.createTextNode(' (' + cmList[cmIndex[i]].comment + ')'))
    ul.appendChild(li);
  }
  res.appendChild(ul);
}

function sortReverse(a,b) {
 return ((b < a) ? -1 : ((b > a) ? 1 : 0));
}

function multiContribsStartbox(parent) {
  var res = document.createElement('div');
  res.setAttribute('id','results-from-multicontribs');
  var spin = document.createElement('span');
   spin.setAttribute('id','multicontribs-prog')
   //spin.appendChild(document.createTextNode('Searching.'));
  res.appendChild(spin);
  injectSpinner(spin,'multicontribs-spin');
  parent.appendChild(res);
}

function addlinkchild(obj,href,text,id,classes) {
  if(!obj || !href || !text) return false;
  var a = document.createElement('a');
  a.setAttribute('href',href);
  a.appendChild(document.createTextNode(text));
  if(id) a.setAttribute('id',id);
  if(classes) a.setAttribute('class',classes);
  obj.appendChild(a);
  return a;
}