User:Hoo man/smartUndo.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/*
* [[m:user:Hoo man]]; Version 1.2.0; 2012-06-10;
* Provides smart undo (automatic undo of many changes)
* Requires rollback permissions (the script needs it to find pages which have undoable edits)
* Tested in IE and FF with vector and monobook, uses my (Hoo man) wiki tools (functions.js)
*
* DO NOT COPY AND PASTE, instead use:
//Smart undo, by [[m:user:Hoo man]]
mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:Hoo_man/smartUndo.js&action=raw&ctype=text/javascript');
*/
if(typeof(hoo) === 'undefined') {
hoo = {};
}
/*global hoo, mw, smartUndoConfig, disable_smart_undo */
/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, loopfunc:true, bitwise:true, undef:true, browser:true, jquery:true, indent:4, maxerr:50, white:false */
hoo.smartUndo = function() {
this.init = function() {
//edit summaries
if(typeof(smartUndoConfig) === 'undefined' || typeof(smartUndoConfig.editSummaries) === 'undefined') {
//smartUndoConfig.editSummaries isn't set, so we take the default out of the lang file
this.config.editSummaries = mw.messages.get('hoo-smartUndo-editSummaries');
}else{
this.config.editSummaries = smartUndoConfig.editSummaries;
}
hoo.addToolLink(mw.message('hoo-smartUndo-toolbarText').escaped(), (function (self) { return function() { self.openWindow(); }; })(this), '', this.config.toolLinkMethod);
};
this.openWindow = function() {
if(!this.window) {
this.window = new hoo.popup('smartUndoWindow', 460, 155, mw.message('hoo-smartUndo-windowTitle').escaped());
this.window.addButton(mw.message('hoo-smartUndo-windowMassButton').escaped(), (function (self) { return function() { self.performAction(); }; })(this));
}else{
this.window.reOpen();
}
var tmp = '<form name="smartUndoForm">';
tmp += mw.message('hoo-smartUndo-editSummary').escaped() + '<br /><select name="editSummarySelect" style="width: 97%;">';
tmp += '<option value="useDefault">' + mw.message('hoo-smartUndo-useDefault').escaped() + '</option>';
for(var i in this.config.editSummaries) {
if(typeof(this.config.editSummaries[i]) === 'string' && i !== 'other' && i !== 'useDefault') { //to filter out stupid prototype functions and deprecated strings
tmp += '<option value="' + this.config.editSummaries[i] + '">' + this.config.editSummaries[i] + '</option>';
}
}
tmp += '<option value="otherSummary" id="smartUndoUseCustomEditSummary">' + mw.message('hoo-smartUndo-other').escaped() + '</option>';
tmp += '</select><br />';
tmp += '<small>' + mw.message('hoo-smartUndo-editSummaryInfo').escaped() + '</small><br /><br />';
tmp += mw.message('hoo-smartUndo-customEditSummary').escaped() + '<br /><input name="editSummaryOther" id="smartUndoEditSummaryOther" type="text" style="width: 97%;" onClick="document.getElementById(\'smartUndoUseCustomEditSummary\').selected = \'true\'"><br /><br />';
if(this.config.enableBotEdits !== false && (hoo.isInGlobalGroup('Global_bot') || hoo.isInGroup('bot') || hoo.isInGroup('flood') || this.config.enableBotEdits === true)) {
tmp += mw.message('hoo-smartUndo-markbotedits').escaped() + '<br /><label for="hoo-smartUndo-yes">' + mw.message('hoo-smartUndo-yes').escaped() + ':</label><input type="radio" name="bot" value="true" id="hoo-smartUndo-yes">';
tmp += '<label for="hoo-smartUndo-yes">' + mw.message('hoo-smartUndo-no').escaped() + ':</label><input type="radio" name="bot" value="false" id="hoo-smartUndo-no" checked>';
}
tmp += '</form>';
this.window.containerHTML(tmp);
};
this.performAction = function() {
var titles, lastRev, params, i, y, tmp, temp, page;
this.window.close();
hoo.showProcess();
//new edit summary
var summary = document.smartUndoForm.editSummarySelect.value;
if(summary === 'otherSummary') {
summary = document.smartUndoForm.editSummaryOther.value;
}
if(summary === 'useDefault') {
summary = hoo.api.sync.getPage({title : 'MediaWiki:Undo-summary', usemsgcache : true});
}
//mark as bot edits?
var bot = 'false';
if(document.smartUndoForm.bot) {
for(i=0; i<document.smartUndoForm.bot.length; i++) {
if(document.smartUndoForm.bot[i].checked) {
bot = document.smartUndoForm.bot[i].value;
}
}
}
//get all rollback links on page
var links = document.getElementsByTagName('a');
var pageList = {};
for(i = 0; i<links.length; i++) {
if(links[i].parentNode.className === 'mw-rollback-link') {
//it is a rollback link, so we auto undo
tmp = mw.util.getParamValue('title', links[i].href).replace(/_/g, ' ');
pageList[ tmp ] = {};
pageList[ tmp ].from = mw.util.getParamValue('from', links[i].href);
}
}
y = i = 0;
titles = [];
for(page in pageList) {
if(typeof(page) === 'string') {
if(i === 0) {
titles[y] = page;
}else if(i < 500) {
titles[y] += '|' + page;
}else{
//500 filed, starting next list
y++;
i = -1;
}
i++;
}
}
for(i = 0; i<titles.length; i++) {
tmp = hoo.api.sync.getToken('edit', titles[i], true);
for(y = 0; y<tmp.pageids.length; y++) {
temp = pageList[ tmp.pages[ tmp.pageids[y] ].title ].from;
pageList[ tmp.pages[ tmp.pageids[y] ].title ] = tmp.pages[ tmp.pageids[y] ];
pageList[ tmp.pages[ tmp.pageids[y] ].title ].from = temp;
}
}
for(page in pageList) {
if(typeof(page) === 'string') {
try {
lastRev = pageList[page].revisions[0];
if(lastRev.user !== pageList[page].from) {
continue;
}
params = {'summary' : summary.replace(/\$1/g, lastRev.revid).replace(/\$2/g, lastRev.user), 'minor' : true, 'basetimestamp' : lastRev.timestamp, 'undo' : lastRev.revid};
if(bot !== 'false') {
params.bot = true;
}
hoo.api.sync.edit(page, params);
}catch(e) {
// mhm :/
}
}
}
window.location.reload();
};
var lang;
if(typeof(disable_smart_undo) !== 'undefined' && disable_smart_undo) {
return false;
}
if(typeof(smartUndoConfig) === 'undefined') {
this.config = hoo.objectDiff(hoo.smartUndoDefaultConfig, null);
}else{
this.config = hoo.objectDiff(smartUndoConfig, hoo.smartUndoDefaultConfig);
}
if(typeof(this.config.toolLinkMethod) === 'undefined') {
this.config.toolLinkMethod = hoo.config.toolLinkMethod;
}
//is there at least one rollback link on the page, so that there is smth. to undo?
var spans = mw.util.$content[0].getElementsByTagName('span');
for(var i = 0; i<spans.length; i++) {
if(spans[i].className === 'mw-rollback-link') {
//localization
if(this.config.lang) {
lang = this.config.lang;
}else{
lang = hoo.config.lang;
}
hoo.loadLocalization(lang, '//meta.wikimedia.org/w/index.php?title=User:Hoo_man/lang/$1/smartUndo.js&action=raw&ctype=text/javascript', (function (self) { return function() { self.init(); }; })(this), this.config.availableLangs, 'en');
break;
}
}
};
//default config
if(typeof(hoo.smartUndoDefaultConfig) === 'undefined') hoo.smartUndoDefaultConfig = {};
//to change anything just add one of the following lines to your own .js and replace 'hoo.smartUndoDefaultConfig' with 'smartUndoConfig'
hoo.smartUndoDefaultConfig.lang = null;
hoo.smartUndoDefaultConfig.enableBotEdits = null;
hoo.smartUndoDefaultConfig.availableLangs = ['en'];
//(default) lang
mw.messages.set({
'hoo-smartUndo-toolbarText' : 'Smart undo',
'hoo-smartUndo-windowTitle' : 'Smart undo',
'hoo-smartUndo-windowMassButton' : 'Undo everything',
'hoo-smartUndo-editSummary' : 'Edit summary:',
'hoo-smartUndo-editSummaryInfo' : '($1 will be replaced with the revision id and $2 with the user)',
'hoo-smartUndo-customEditSummary' : 'Custom edit summary:',
'hoo-smartUndo-useDefault' : 'Use the default edit summary',
'hoo-smartUndo-markbotedits' : 'Mark edits as bot edits:',
'hoo-smartUndo-yes' : 'Yes',
'hoo-smartUndo-no' : 'No',
'hoo-smartUndo-other' : 'Other ->',
'hoo-smartUndo-editSummaries' : [
'Undo revision $1',
'Undo revision $1, vandalism'
]
});
if(typeof(hoo) === 'undefined' || typeof(hoo.objectDiff) === 'undefined') {
if(typeof(hoo_callbacks) === 'undefined') {
var hoo_callbacks = [ function() { hoo.instances.smartUndo = new hoo.smartUndo(); } ];
mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:Hoo_man/functions2.js&action=raw&ctype=text/javascript');
}else{
hoo_callbacks = hoo_callbacks.concat([ function() { hoo.instances.smartUndo = new hoo.smartUndo(); } ]);
}
}else{
hoo.instances.smartUndo = new hoo.smartUndo();
}