//  _________________________________________________________________________________________
// |                                                                                         |
// |                    === WARNING: GLOBAL GADGET FILE ===                                  |
// |                  Changes to this page affect many users.                                |
// | Please discuss changes on the talk page or on ] before editing. |
// |_________________________________________________________________________________________|
//
// Imported from version 312947638 as of September 10, 2009 from ]
// See notes below

/* Special:Contributions Wildcard/CIDR lookup, version 
Originally from: http://en.wikipedia.orghttps://wiki95.com/de/User:Splarka/contribsrange.js

Notes:
* Uses the API which is faster than most CIDR contrib tools.
** Needs 1.14 r42198+ for advanced continue.
* Currently uses a GET json via <script src=""> to avoid ajax problems.
* Only currently works if submitted (or called by URL parameter, eg Special:Contributions/User).
** Checks namespace and date options in form.
** Also utilizes &ucstart and &ucend date parameters if supplied manually (not supported in the UI atm).
*** These parameter soverride the form date options.
* Uses: Submit any IP CIDR range /16 or from /24 to /32. Submit any string (at least 3 characters) with a suffixed asterisk.
** eg:  or  or .
* Now keeps searching until it finds crMax (or forever with crshowall=true URI parameter).
** Puts them in a nice collapsed div stack, like enhanced recent changes.
* /25 and /26 ranges now disabled, since they are inaccurate (50 parameter limit), please use /24 (ucuserprefix) or /27 (32 parameters)

To do:
* use ajax (let sysops/bots = 5000)?
*/

if( mw.config.get( 'wgCanonicalSpecialPageName' ) == 'Contributions' ) {
  $(mw.loader.using(, prefixContribsInit));
  var crContURI = ''; //query URI for continuing later
  var crLimit = 500; //limit for each query
  var crMax = 10000; //bypass with &crshowall=true URI parameter
  var crImgHid = '//upload.wikimedia.org/wikipedia/commons/a/ad/Arr_r.png';
  var crImgSho = '//upload.wikimedia.org/wikipedia/commons/f/f0/Arr_d.png';
  mw.util.addCSS('.cr-list {padding-left:5px;}\n.cr-toggle-hidden {padding-left:16px;background: transparent no-repeat center left url("' + crImgHid + '")}'
  + '\n.cr-toggle-shown {padding-left:16px;background: transparent no-repeat center left url("' + crImgSho + '")}\n.mw-mightexist {font-style:italic;}'
  + '\n#results-from-CIDR {border:1px solid black;padding:.5em}\n#prefixcontribs-tog {float:right;border:1px solid black;text-decoration:none;color:black;padding:0 5px;}');
}

function prefixContribsInit() {
  mw.util.addSubtitle(' \u2022 Du kannst ein Sternchen (wie 123.45.67.*) als Platzhalter verwenden.');
  var ucparent = $( '.mw-body-content form' ).first().parent();
  var uctarget = $( '#mw-target-user-or-ip input' ).attr( 'value' );
  if(!uctarget) return;

  //general optionlets independent of type of search.
  var ucns = $( '#namespace select' ).val();
  var opt_ns = (parseInt(ucns) > -1) ? '&ucnamespace=' + ucns : '';
  var opts_ts = '';
  var dateStart = $( '#mw-date-start input' ).val();
  var dateEnd = $( '#mw-date-end input' ).val();
  if( dateStart ) {
    opts_ts += '&ucstart=' + dateStart + 'T23:59:59Z';
  }
  if( dateEnd ) {
    opts_ts += '&ucend=' + dateEnd + 'T23:59:59Z';
  }
  var opts_se = '';
  if(queryString('ucstart')) opts_se += '&ucstart=' + encodeURIComponent(queryString('ucstart'));
  if(queryString('ucend')) opts_se += '&ucend=' + encodeURIComponent(queryString('ucend'));
  if(opts_se == '') {
    var options = opt_ns + opts_ts + '&ucdir=newer';
  } else {
    var options = opt_ns + opts_se + '&ucdir=newer';
  }

  var patternCIDR = /(25|2|??)\.(25|2|??)\.(25|2|??)\.(25|2|??)\/(2|3|24|16)/i ;
  var patternWild = /^.{3,}\*$/i ;
  var url = mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php?action=query&format=json&rawcontinue=&callback=prefixContribs&list=usercontribs&ucprop=ids|title|timestamp|comment|size|sizediff' + options + '&uclimit=' + parseInt(crLimit);
  if(false && uctarget.search(patternCIDR) == 0) {
    prefixContribsStartbox(ucparent);
    var cidr = uctarget.match(patternCIDR);
    var range = cidr.match(/\d{1,2}$/i);
    if(range == 24 || range == 16) {
      //prefixable CIDR, lets do-er
      if(range == 24) {
        cidr = cidr.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\./);
      } else {
        cidr = cidr.match(/\d{1,3}\.\d{1,3}\./);
      }
      url += '&ucuserprefix=' + cidr;
    } else {
      //complex CIDR, lets figure it out
      var oct3 = cidr.match(/\.\d{1,3}\//i).replace(/(\.|\/)/g,'');
      cidr = cidr.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\./);
      var num = Math.pow(2,32 - range);
      var start = oct3 - oct3 % num;
      url += '&ucuser=';
      for(var i=start;i<=start + num;i++) {
        url += '' + cidr + i;
        if(i != start + num) url += '|';
      }
    }
  } else if(uctarget.search(patternWild) == 0) {
    //very simple wildcard, lets do-er
    prefixContribsStartbox(ucparent);
    var prefix = uctarget.replace(/\*$/,'');
    prefix = prefix.substr(0,1).toUpperCase() + prefix.substr(1);
    url += '&ucuserprefix=' + prefix;
  } else {
    //no user or no userprefix, nothing to do
    return;
  }
  mw.loader.load(url);
  crContURI = url;
}

function prefixContribsStartbox(parent) {
  var res = document.createElement('div');
  res.setAttribute('id','results-from-CIDR');
  addlinkchild(res,'javascript:window.prefixContribsToggleAll();','alle auf/zu','prefixcontribs-tog');
  var spin = document.createElement('span');
  spin.setAttribute('id','prefixcontribs-prog');
  spin.appendChild(document.createTextNode('Suche …'));
  res.appendChild(spin);
  $(spin).injectSpinner('prefixcontribs-spin');
  parent.append(res);
}

window.prefixContribs = function(obj) {
  if(!obj || !obj) return;
  cidr = obj;
  var res = document.getElementById('results-from-CIDR');
  if(cidr.length == 0) {
    res.appendChild(document.createTextNode(' Für diesen Netzbereich wurden keine Änderungen gefunden.'));
    $.removeSpinner('prefixcontribs-spin');
    return;
  }
  for(var i=0;i<cidr.length;i++) {
    var id = 'cr-' + escapeID(cidr.user);
    var etitle = encodeURIComponent(cidr.title.replace(/ /g,'_')).replace('%2F','/').replace('%3A',':');
    var euser = encodeURIComponent(cidr.user.replace(/ /g,'_')).replace('%2F','/').replace('%3A',':');
    // group each result set based on the user name, create new div for new names
    if(!document.getElementById(id)) {
      var hdiv = document.createElement('div');
      hdiv.setAttribute('id','d-' + id);
      addlinkchild(hdiv,'javascript:window.prefixContribsToggleDiv("' + id +'")',cidr.user,'m-' + id,'cr-toggle-hidden');
      res.appendChild(hdiv);
      res.appendChild(document.createTextNode('\n'));
      var rul = document.createElement('ul');
       rul.setAttribute('id',id);
       rul.setAttribute('class','cr-list');
       rul.style.display = 'none';
      res.appendChild(rul);
      res.appendChild(document.createTextNode('\n'));
    }
    var ul = document.getElementById(id);
    ul.appendChild(document.createTextNode('\n'));
    var li = document.createElement('li');
    var script = mw.config.get( 'wgScript' );
     li.appendChild(document.createTextNode(cidr.timestamp.replace(//g,' ')));
     addlinkchild(li, script + '?title=Special:Contributions/' + euser, cidr.user);
     li.appendChild(document.createTextNode(' ('));
     addlinkchild(li, script + '?title=User_talk:' + euser, 'Diskussion','','mw-mightexist');
     li.appendChild(document.createTextNode(') bearbeitete ('));
     addlinkchild(li, script + '?title=' + etitle + '&curid=' + cidr.pageid + '&diff=prev&oldid=' + cidr.revid , 'diff');
     li.appendChild(document.createTextNode(') '));
     addlinkchild(li, script + '?title=' + etitle + '&curid=' + cidr.pageid, cidr.title);
     if(cidr.comment) li.appendChild(document.createTextNode(' (' + cidr.comment + ')'));
     if(cidr.sizediff) li.appendChild(document.createTextNode(' .sizediff.toString().replace(/^(\d)/i,'+$1') + ']'));
    ul.appendChild(li);
  }

  //continue?
  crMax = crMax - cidr.length;
  var prog = document.getElementById('prefixcontribs-prog');
  if(!obj || !obj || !obj) {
    $.removeSpinner('prefixcontribs-spin');
    prog.parentNode.removeChild(prog);
    prefixContribsNumerate();
    return;
  }
  var url = crContURI + '&uccontinue='+ obj;
  if(crMax <= 0 && queryString('crshowall') != 'true') {
    prog.appendChild(document.createTextNode(' Es wurden viele Ergebnisse gefunden. Um sie alle zu sehen klicke '));
    var ga = document.createElement('a');
     var gaurl = document.location.href;
     if(gaurl.indexOf('#') != -1) gaurl = gaurl.substr(0,gaurl.indexOf('#'));
     if(gaurl.indexOf('?') == -1) gaurl += '?';
     gaurl += '&crshowall=true';
     ga.setAttribute('href',gaurl);
     ga.appendChild(document.createTextNode('hier'));
    prog.appendChild(ga);
    prog.appendChild(document.createTextNode('. Achtung: Könnte den Browser lahmlegen!'));
    $.removeSpinner('prefixcontribs-spin');
    prefixContribsNumerate();
  } else {
    prog.appendChild(document.createTextNode('.'));
    mw.loader.load(url);
  }
}

function prefixContribsNumerate() {
  var lsts = $('ul.cr-list');
  lsts.each( function() {
    var dv = document.getElementById('d-' + this.getAttribute('id'));
    dv.appendChild(document.createTextNode(' ' + this.getElementsByTagName('li').length + ' gefunden'));
  });
  if(lsts.length == 1) window.prefixContribsToggleDiv(lsts.eq(0).attr('id'));
}

window.prefixContribsToggleAll = function() {
  var lsts = $('ul.cr-list');
  if(lsts.length == 0) return;
  var togglefrom = lsts.first().css('display');
  lsts.each( function() {
    if(this.style.display == togglefrom) window.prefixContribsToggleDiv(this.id);
  });
}

window.prefixContribsToggleDiv = function(id) {
  var i = document.getElementById(id);
  var m = document.getElementById('m-' + id);
  if(!i || !m) return;
  if(i.style.display == 'none') {
    i.style.display = 'block';
    m.className = 'cr-toggle-shown';
  } else {
    i.style.display = 'none';
    m.className = 'cr-toggle-hidden';
  }
}

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;
}

function escapeID(txt) {
  var id = txt;
  id = id.replace(/ /g,'_');
  id = encodeURIComponent(id);
  id = id.replace(/\%3A/g,':');
  id = id.replace(/\%/g,'.');
  return id;
}

function queryString(p) {
  var re = RegExp('' + p + '=(*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try {
      return decodeURI(matches);
    } catch (e) {
    }
  }
  return null;
}