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);
//