User:Quarl/rollback.js

// User:quarl/rollback.js - rollback button for non-admins

// requires util.js, md5.js, wikipage.js, wikiedit.js

// based on http://sam.zoy.org/wikipedia/godmode-light.js

// - more robust (works with Popups, etc)

// - factored code

//

// -----------------------------------------------------------------------------

// God-like Monobook skin

// (c) 2005 Sam Hocevar

// Forked from: Id: godmode-light.js 980 2005-11-12 01:51:51Z sam

// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------

// Language support, taken from phase3/languages/*

// -----------------------------------------------------------------------------

var rollbacklink = 'rollback';

var cantrollback = 'Cannot revert edit; last contributor is only author of this page.';

var alreadyrolled = 'Cannot rollback last edit of $1 by $2 (Talk); someone else has edited or rolled back the page already. Last edit was by $3 (Talk). ';

var revertpage = 'Reverted edits by $2 (t) (c) to last version by $1';

// -----------------------------------------------------------------------------

// Our nice Revert functions

// -----------------------------------------------------------------------------

var gml_vandal, gml_editor;

function rollback_Revert() {

if(typeof queryVars === 'undefined') return;

var token = queryVars['token'];

gml_vandal = queryVars['vandal'];

document.cont = document.getElementById('bodyContent');

document.cont.innerHTML = 'Please wait, reverting edits by ' + gml_vandal + '...';

// Avoid XSS kiddies by using a special token

if (!token || token != rollback_mkToken(wikiPage, gml_vandal)) {

document.cont.innerHTML += 'ERROR: Bad authentication token!';

return;

}

document.getElementById('bodyContent').innerHTML += '
Getting article history...';

asyncDownloadXML(wikiPage.qurl + '&action=history&limit=50', rollback_Revert2);

}

// Get the vandal and new editor names

function rollback_parseHistory(doc) {

var l = doc.getElementById('pagehistory').getElementsByTagName('li');

for (i = 0; i < l.length; i++) {

var name = l[i].getElementsByTagName('span')[0].getElementsByTagName('a')[0].innerHTML.replace(/_/g,' ');

if (!name) continue;

if (i == 0) {

if (name != gml_vandal) {

document.cont.innerHTML += '
Error: Last editor is ' + name + ', not ' + gml_vandal + '!';

return {};

}

} else {

if (name != gml_vandal) {

var oldid = l[i].getElementsByTagName('input')[0].value;

var editor = name;

return {'oldid':oldid, 'editor':editor};

}

}

}

return {};

}

function rollback_Revert2(xmlhttp) {

doc = xmlhttp.responseXML;

var r = rollback_parseHistory(doc);

var oldid = r.oldid;

gml_editor = r.editor;

if (!gml_editor) {

document.cont.innerHTML += '
Error: ' + gml_vandal + ' is the only editor!';

return;

}

var url = wikiPage.qurl + '&action=edit&oldid=' + oldid;

document.cont.innerHTML += '
Getting article edit form...';

asyncDownloadXML(url, rollback_Revert3);

}

function rollback_Revert3(xmlhttp) {

summary_text = revertpage.replace(/\$1/g, gml_editor).replace(/\$2/g, gml_vandal);

document.cont.innerHTML += '
Submitting form...';

var wd = new WikiDocument(xmlhttp.responseXML, wikiPage);

var editor = new WikiEditor(wd);

editor.wpSummary = summary_text;

editor.submit();

}

function rollback_mkToken(wp, vandal) {

return hex_md5(wp.page + '%' + vandal + '%' + document.cookie);

}

function rollback_mkUrl(wp, vandal) {

return url_getpath(wp.qurl + '&fakeaction=rollback&vandal=' +

escape(vandal) + '&token=' + escape(rollback_mkToken(wp, vandal)));

}

// -----------------------------------------------------------------------------

// Add revert buttons to the page

// -----------------------------------------------------------------------------

function rollback_AddButtonDiff() {

if (wikiDoc.editingP) return; // preview diff pages will also be edit pages and shouldn't have rollback buttons

var difftag = getElementsByClass('diff-ntitle',document.getElementById('bodyContent'),'td')[0];

if (!difftag) return;

// if toplink has an oldid then this is not a diff against current revision.

var toplink = difftag.getElementsByTagName('a')[0].href;

if (toplink.match(/oldid=/)) return;

var vandal = getUsernameFromLink(difftag.getElementsByTagName('a')[1]);

if (!vandal) { alert("Couldn't parse username in diff page!"); return; }

var url = rollback_mkUrl(wikiPage,vandal);

var newtext = '    [' + rollbacklink + '] ';

difftag.innerHTML = difftag.innerHTML.replace(/(<\/a>\))( *

}

function rollback_AddButtonContributions() {

if (wikiPage.page != 'Special:Contributions') return;

var vandal = relevantUser; // defined in wikipage.js

if (!vandal) return;

var l = document.getElementById('bodyContent').getElementsByTagName('li');

for (i = 0; i < l.length; i++) {

var t = l[i].innerHTML;

// If we are already a sysop on this wiki, abort

if (t.match(/>rollback<\/a>]/)) return;

if (t.match(/ \(/)) {

var wp = new WikiPage(l[i].getElementsByTagName('a')[0].href);

var url = rollback_mkUrl(wp,vandal);

l[i].innerHTML += ' [' + rollbacklink + ']';

}

}

}

function rollback_Load() {

if(typeof queryVars === 'undefined') return;

if (queryVars['fakeaction'] == 'rollback') {

rollback_Revert();

} else {

rollback_AddButtonDiff();

rollback_AddButtonContributions();

}

}

$(rollback_Load);

//