User:Jarandhel/common.js: Difference between revisions
m (Protected "User:Jarandhel/common.js": I hope I don't need to protect this, but just in case. ([edit=sysop] (indefinite) [move=sysop] (indefinite))) |
|||
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
/* Ajax mass user-rollback, version [0.0.1b] |
|||
Originally from: http://en.wikipedia.org/wiki/User:Splarka/ajaxmassrollback.js |
|||
Notes: |
|||
* Oh god this is ugly code. Haha. |
|||
* This does not revert moves but thinks it does. Not sure how to skip them either. BE AWARE. |
|||
* This only goes back 7 (configurable) days by default, but should work with any number of contribs in that timeframe. |
|||
Operation: |
|||
* Gets user's contribs (query-continues until reaching the time limit). |
|||
** For each contrib that is (top) and not (new) it leaves a checkbox (and info/links). |
|||
* After selecting which to rollback via checkboxes, it iterates over these checkboxes. |
|||
** For each revid, it gets the rollback token, title, and user. |
|||
*** Upon getting the token, it attempts rollback. |
|||
**** If successful, checkbox is unchecked and next is selected (after 1 second delay). |
|||
To do: |
|||
* Delete link for pages created by user? Maybe. |
|||
* Rewrite for efficiency when generator=usercontribs becomes implemented! Oh yah. |
|||
* Markbot optional? |
|||
* Reason field? |
|||
*/ |
|||
var amrNumContribs; |
|||
if(!window.amrNumDays) var amrNumDays = 7 |
|||
var amrWorking = false; |
|||
if((wgNamespaceNumber == 2 || wgNamespaceNumber == 3) && wgTitle.indexOf('/') == -1 && (wgAction != 'edit' || wgAction != 'submit') && wgEnableAPI) addOnloadHook(function() { |
|||
addPortletLink('p-cactions','/wiki/Special:BlankPage?blankspecial=ajaxmr&user=' + encodeURIComponent(wgTitle),'Mass Rollback','p-mr'); |
|||
}); |
|||
if(wgCanonicalSpecialPageName && wgCanonicalSpecialPageName == 'Contributions' && wgEnableAPI) addOnloadHook(function() { |
|||
var ucfrm = document.getElementsByTagName('form')[0]; |
|||
var targ = ''; |
|||
if(ucfrm.target && ucfrm.target.value != '') { |
|||
targ = '&user=' + encodeURIComponent(ucfrm.target.value); |
|||
} |
|||
addPortletLink('p-cactions','/wiki/Special:BlankPage?blankspecial=ajaxmr' + targ,'Mass Rollback','p-mr'); |
|||
}); |
|||
if(wgCanonicalSpecialPageName && wgCanonicalSpecialPageName.toLowerCase() == 'blankpage' && queryString('blankspecial') == 'ajaxmr') { |
|||
document.title = 'Ajax Mass Rollback'; |
|||
addOnloadHook(amrForm); |
|||
appendCSS('#amr-contriblist {border:2px solid black;margin:.7em .1em;padding:.5em;height:20em;overflow:auto;}' |
|||
+ '\n#amr-contriblist li {white-space:nowrap;} .amr-step1 {background-color:#ffff99;} .amr-step2 {background-color:#9999ff;} .amr-step3 {background-color:#99ff99;}'); |
|||
} |
|||
function amrForm() { |
|||
//subvert this Special: page to our own needs. |
|||
var con = document.getElementById('content') || document.getElementById('mw_content'); |
|||
var bcon = document.getElementById('bodyContent') || document.getElementById('mw_contentholder'); |
|||
var fh = getElementsByClassName(con,'h1','firstHeading')[0]; |
|||
while(fh.firstChild) fh.removeChild(fh.firstChild) |
|||
fh.appendChild(document.createTextNode('Ajax Mass Rollback')); |
|||
for(var i=0;i<bcon.childNodes.length;i++) { |
|||
bcur = bcon.childNodes[i]; |
|||
if(bcur.id != 'siteSub' && bcur.id != 'contentSub' && bcur.className != 'visualClear') { |
|||
while(bcur.firstChild) bcur.removeChild(bcur.firstChild) |
|||
if(bcur.nodeType == 3) bcur.nodeValue = ''; |
|||
} |
|||
} |
|||
var form = document.createElement('form'); |
|||
form.setAttribute('action','javascript:void(0)'); |
|||
var lab1 = document.createElement('label'); |
|||
lab1.setAttribute('for','amr-user') |
|||
lab1.appendChild(document.createTextNode('User (vandal): ')); |
|||
form.appendChild(lab1); |
|||
var inp1 = document.createElement('input'); |
|||
inp1.style.width = '20em'; |
|||
inp1.setAttribute('type','text'); |
|||
if(queryString('user')) inp1.setAttribute('value',queryString('user')); |
|||
inp1.setAttribute('id','amr-user'); |
|||
form.appendChild(inp1); |
|||
var sub1 = document.createElement('input'); |
|||
sub1.setAttribute('type','button'); |
|||
sub1.setAttribute('id','amr-getcontribs'); |
|||
sub1.setAttribute('value','start'); |
|||
sub1.setAttribute('onclick','amrGetContribs()'); |
|||
form.appendChild(sub1); |
|||
var ul = document.createElement('ul'); |
|||
ul.setAttribute('id','amr-contriblist'); |
|||
form.appendChild(ul); |
|||
bcon.appendChild(form); |
|||
var pre = document.createElement('pre'); |
|||
pre.setAttribute('id','amr-output'); |
|||
bcon.appendChild(pre); |
|||
} |
|||
function amrGetContribs(tsoffset) { |
|||
var start = ''; |
|||
if(tsoffset) { |
|||
start = '&ucstart=' + tsoffset; |
|||
} else { |
|||
if(amrWorking) return |
|||
amrWorking = true; |
|||
document.getElementById('amr-user').setAttribute('disabled','disabled'); |
|||
injectSpinner(document.getElementById('amr-getcontribs'),'getcontribs-spin'); |
|||
var ul = document.getElementById('amr-contriblist'); |
|||
while(ul.firstChild) ul.removeChild(ul.firstChild) |
|||
amrNumContribs = 0; |
|||
} |
|||
var user = document.getElementById('amr-user').value; |
|||
var now = new Date(); |
|||
var stop = parseInt(now.getTime() / 1000) - 86400 * amrNumDays; |
|||
var url = wgScriptPath + '/api.php?action=query&format=json&list=usercontribs&ucprop=flags|title|ids|comment|timestamp&uclimit=50' + start + '&ucend=' + stop + '&ucuser=' + encodeURIComponent(user); |
|||
var req = sajax_init_object(); |
|||
req.open('GET', url, true); |
|||
req.onreadystatechange = function() { |
|||
if(req.readyState == 4 && req.status == 200) { |
|||
eval("amrPopulatContribs(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "')"); |
|||
} |
|||
} |
|||
req.send(null); |
|||
} |
|||
function amrPopulatContribs(obj,txt) { |
|||
var ul = document.getElementById('amr-contriblist'); |
|||
if(obj['error']) { |
|||
ul.parentNode.appendChild(document.createTextNode('Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n')); |
|||
return; |
|||
} |
|||
if(!obj['query'] || !obj['query']['usercontribs']) { |
|||
ul.parentNode.appendChild(document.createTextNode('Unexpected response: ' + txt + '\n')); |
|||
return; |
|||
} |
|||
var uc = obj['query']['usercontribs']; |
|||
for(var i=0;i<uc.length;i++) { |
|||
if(uc[i]['new'] == '') { |
|||
// delete link? |
|||
} else if(uc[i]['top'] == '') { |
|||
var li = document.createElement('li'); |
|||
var inp = document.createElement('input'); |
|||
inp.setAttribute('type','checkbox'); |
|||
inp.setAttribute('checked','checked'); |
|||
inp.setAttribute('class','amr-cl'); |
|||
inp.setAttribute('title',uc[i].title); |
|||
inp.setAttribute('id','amr-cl-' + uc[i].revid); |
|||
li.appendChild(inp); |
|||
var lab = document.createElement('label'); |
|||
lab.setAttribute('for','amr-cl-' + uc[i].revid); |
|||
lab.appendChild(document.createTextNode(uc[i].timestamp.replace(/[TZ]/g,' '))); |
|||
li.appendChild(lab); |
|||
li.appendChild(document.createTextNode('(')); |
|||
addlinkchild(li, wgScript + '?curid=' + uc[i].pageid + '&diff=prev&oldid=' + uc[i].revid,'diff'); |
|||
li.appendChild(document.createTextNode(') (')); |
|||
addlinkchild(li, wgScript + '?curid=' + uc[i].pageid + '&action=history','hist'); |
|||
li.appendChild(document.createTextNode(') . . ')); |
|||
addlinkchild(li, wgScript + '?curid=' + uc[i].pageid,uc[i].title); |
|||
if(uc[i].comment) li.appendChild(document.createTextNode(' (' + uc[i].comment + ')')) |
|||
ul.appendChild(li); |
|||
amrNumContribs++; |
|||
} |
|||
} |
|||
if(obj['query-continue'] && obj['query-continue']['usercontribs'] && obj['query-continue']['usercontribs']['ucstart']) { |
|||
amrGetContribs(obj['query-continue']['usercontribs']['ucstart']); |
|||
} else { |
|||
amrWorking = false; |
|||
document.getElementById('amr-user').removeAttribute('disabled'); |
|||
removeSpinner('getcontribs-spin'); |
|||
var li = document.createElement('li'); |
|||
li.appendChild(document.createTextNode(amrNumContribs + ' top contributions found for user (over last ' + amrNumDays + ' days). ')); |
|||
var sub = document.createElement('input'); |
|||
sub.setAttribute('type','button'); |
|||
sub.setAttribute('id','amr-startrollbacks'); |
|||
sub.setAttribute('value','rollback selected'); |
|||
sub.setAttribute('onclick','amrRollbackContribs()'); |
|||
li.appendChild(sub); |
|||
ul.insertBefore(li,ul.firstChild); |
|||
} |
|||
} |
|||
function amrRollbackContribs(automated) { |
|||
var out = document.getElementById('amr-output'); |
|||
if(!automated) { |
|||
if(amrWorking) return |
|||
amrWorking = true; |
|||
injectSpinner(document.getElementById('amr-startrollbacks'),'startrollbacks-spin'); |
|||
} |
|||
var ul = document.getElementById('amr-contriblist'); |
|||
var ucs = getElementsByClassName(ul,'input','amr-cl'); |
|||
var uc = false; |
|||
for(var i=0;i<ucs.length;i++) { |
|||
if(ucs[i].checked && ucs[i].parentNode.className == '') { |
|||
uc = ucs[i]; |
|||
break; |
|||
} |
|||
} |
|||
if(!uc) { |
|||
out.appendChild(document.createTextNode('* Done!')); |
|||
amrWorking = false; |
|||
} else { |
|||
var id = uc.id.replace(/amr\-cl\-/,''); |
|||
uc.parentNode.className = 'amr-step1'; |
|||
uc.removeAttribute('checked'); |
|||
var page = uc.title; |
|||
out.appendChild(document.createTextNode('> Attempting to rollback [[' + page + ']]\n')); |
|||
amrGetToken(id,page); |
|||
} |
|||
} |
|||
function amrGetToken(id,page) { |
|||
var out = document.getElementById('amr-output'); |
|||
out.appendChild(document.createTextNode(' > Fetching rollback token for [[' + page + ']]\n')); |
|||
var url = wgScriptPath + '/api.php?action=query&format=json&prop=revisions&indexpageids&rvprop=user|ids&rvtoken=rollback&revids=' + id; |
|||
var req = sajax_init_object(); |
|||
req.open('GET', url, true); |
|||
req.onreadystatechange = function() { |
|||
if(req.readyState == 4 && req.status == 200) { |
|||
eval("amrRollback(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "')"); |
|||
} |
|||
} |
|||
req.send(null); |
|||
} |
|||
function amrRollback(obj,txt) { |
|||
var out = document.getElementById('amr-output'); |
|||
if(obj['error']) { |
|||
out.appendChild(document.createTextNode(' ! Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n')); |
|||
return; |
|||
} |
|||
if(!obj['query'] || !obj['query']['pageids'] || !obj['query']['pages'][obj['query']['pageids'][0]]) { |
|||
out.appendChild(document.createTextNode(' ? Unexpected response: ' + txt + '\n')); |
|||
return; |
|||
} |
|||
var pid = obj['query']['pages'][obj['query']['pageids'][0]]; |
|||
if(!pid['title'] || !pid['revisions'] || !pid['revisions'][0] || !pid['revisions'][0]['user'] || !pid['revisions'][0]['revid'] || !pid['revisions'][0]['rollbacktoken']) { |
|||
out.appendChild(document.createTextNode(' ?? Unexpected response: ' + txt + '\n')); |
|||
return; |
|||
} |
|||
var id = pid['revisions'][0]['revid']; |
|||
var uc = document.getElementById('amr-cl-' + id); |
|||
if(uc) uc.parentNode.className = 'amr-step2' |
|||
var user = pid['revisions'][0]['user']; |
|||
var token = pid['revisions'][0]['rollbacktoken']; |
|||
var title = pid['title']; |
|||
out.appendChild(document.createTextNode(' > Token found, attempting rollback\n')); |
|||
var params = 'action=rollback&format=json&markbot=1&token=' + encodeURIComponent(token) + '&title=' + encodeURIComponent(title) + '&user=' + encodeURIComponent(user); |
|||
var url = wgScriptPath + '/api.php'; |
|||
var req = sajax_init_object(); |
|||
req.open('POST', url, true); |
|||
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); |
|||
req.setRequestHeader('Content-length', params.length); |
|||
req.setRequestHeader('Connection', 'close'); |
|||
req.onreadystatechange = function() { |
|||
if(req.readyState == 4 && req.status == 200) { |
|||
eval("amrRollbackAftermath(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "')"); |
|||
} |
|||
} |
|||
req.send(params); |
|||
} |
|||
function amrRollbackAftermath(obj,txt) { |
|||
var out = document.getElementById('amr-output'); |
|||
if(obj['error']) { |
|||
out.appendChild(document.createTextNode(' ! Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n')); |
|||
} else if(obj['rollback'] && obj['rollback']['title']) { |
|||
var rb = obj['rollback']; |
|||
out.appendChild(document.createTextNode(' > Page [[' + rb['title'] + ']] rollbacked (')); |
|||
addlinkchild(out, wgScript + '?curid=' + rb['pageid'] + '&diff=next&oldid=' + rb['old_revid'],'diff'); |
|||
out.appendChild(document.createTextNode(').\n')); |
|||
if(obj['rollback']['old_revid']) { |
|||
var uc = document.getElementById('amr-cl-' + obj['rollback']['old_revid']); |
|||
uc.setAttribute('disabled','disabled'); |
|||
if(uc) uc.parentNode.className = 'amr-step3' |
|||
} |
|||
} else { |
|||
out.appendChild(document.createTextNode(' ? Unexpected response: ' + txt + '\n')); |
|||
return; |
|||
} |
|||
setTimeout('amrRollbackContribs(true)',1000); |
|||
} |
|||
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 queryString(p) { |
|||
var re = RegExp('[&?#]' + p + '=([^&#]*)'); |
|||
var matches; |
|||
if (matches = re.exec(document.location)) { |
|||
try { |
|||
return decodeURI(matches[1]); |
|||
} catch (e) { |
|||
} |
|||
} |
|||
return null; |
|||
} |