Jump to content

User:Ponor/really-quick-block.js

From Meta, a Wikimedia project coordination wiki

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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* 
really quick block —  adds configurable buttons to block IP users from 
Recent Changes and Page History. 
Each button takes 4 seconds to 'load', to prevent accidental blocks, 
and is available for another 6 seconds to 'shoot'. 
Re-blocks are disabled, and a warning will be issued. 
Use responsibly!
*/
$(document).ready(function() {
  
if (
  !(mw.config.get("wgUserGroups").includes("sysop") 
    && (mw.config.get("wgCanonicalSpecialPageName")==="Recentchanges" || mw.config.get("wgCanonicalSpecialPageName")==="Watchlist" ||mw.config.get("wgAction") === "history")
    )
   ) {return;} //you don't belong here


//available block options: anononly, autoblock, nocreate, allowusertalk
//see mediawiki.org/wiki/API:Block
if (!window.rqb_buttons) {
  window.rqb_buttons = {
    V4:  {reason:"vandalism", expiry:"4 hours", options:["anononly"]},
    P6:  {reason:"profanity", expiry:"6 hours", options:["anononly"]},
    A24: {reason:"attacks", expiry:"24 hours"},
  };
}

mw.util.addCSS(
`.rqb-button {font-size:90%; border:2px dotted #f66; border-radius:6px; padding:0 2px; margin-right:4px;}
.rqb-button-disabled {background-color:transparent; color:gray; border-color:gray;}`
);

//triggered by Recent Changes autoupdate
mw.hook("wikipage.content").add(function(el) {
  if (el.hasClass('mw-changeslist')) {
    initialize();
  }
});

initialize();


//------------------------------------------------------- hoisted functions
function initialize() {
  let elements = $('li[data-mw-revid] a.mw-anonuserlink');
  elements.each(function() {
    let sp = $("<span/>");
    for (const b in window.rqb_buttons) {
      let button = $(`<a>${b}</a>`);
      button.addClass("rqb-button")
            .attr("data-ip", $(this).text())
            //.data("expiry", window.rqb_buttons[b].expiry)
            .attr("title", window.rqb_buttons[b].reason + ': ' + window.rqb_buttons[b].expiry)
            .on('click', on_click);
      sp.append(button);
    }

    $( ".mw-usertoollinks", $(this).parent() ).append(sp);
  });
} //on_load


//first click: 4 seconds to "load",the button remains inactive; 4+2 seconds to "shoot" or go back to inactive again
function on_click() {
  if ($(this).data("status")===undefined || $(this).data("status")==="WAITING") {
    $(this).data("status","LOADING");
    $(this).animate({"background-color":"#f66"}, 4000,  ()=>{$(this).data("status", "CHARGED")})
           .delay(4000)
           .animate({"background-color":"transparent"}, 2000,  ()=>{$(this).data("status", "WAITING")});
  }
  else if ($(this).data("status")==="CHARGED") { //ready to block
    //console.log("BLOCKED")
    let ip = $(this).attr("data-ip");
    if ( (ip+'.').match(/^(?:\d{1,3}\.){4}$/) || ip.match(/^(?:[0-9a-f]{0,4}:){2}[:0-9a-f]*$/) ) (
      api_block(ip, window.rqb_buttons[$(this).text()].expiry, window.rqb_buttons[$(this).text()].reason, window.rqb_buttons[$(this).text()].options)
    );
  }
}


function api_block(user, expiry='1 minute', reason='block test', options=["anononly","autoblock","nocreate","allowusertalk"]) {
  if (!user) {return;}
  
  //if not already blocked, block
  let api = new mw.Api();
  var blocksPromise = api.get({
      "action": "query",
      "format": "json",
      "list": "blocks",
      "bkusers": user,
      "bkprop": "id|by"
    });

  blocksPromise.done(function(jsondata) {
    if (jsondata.query.blocks.length===0) {
        var params = {
          action: 'block',
          format: 'json',
          //anononly: "", //yes
          //nocreate: "", //yes
          //autoblock: "", //yes
          //allowusertalk: "", //yes
          user: user,
          expiry: expiry,
          reason: reason,
        };
        for (const i of options.keys()) {
          params[options[i]] = ""; //means yes
        }

        api.postWithToken( 'csrf', params )
          .done( function() {
             $("a.rqb-button[data-ip='"+user+"']").addClass("rqb-button-disabled").data("status", "BLOCKED").off();
             mw.notify("⛔ " + user, {'type':'success'}) ;
           })
          .fail( function() {
             mw.notify("⚡⚡⚡ " + user, {'type':'error'});
           });	
    }
    else {
      mw.notify("2× ⛔ " + user, {'type':'warn'});
      $("a.rqb-button[data-ip='"+user+"']").addClass("rqb-button-disabled").data("status","DISABLED").off();
    }
  }); //blocksPromise.done

} //api_block

});