User:Future Perfect at Sunrise/rangeblock.js

// =============================================== // User script to add a dropdown box to the admin // block form, offering CDIR range block codes // when blocking IPs // ===============================================

var patternIP = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;

function isIP(txt) { var found = patternIP.exec(txt); if (found) { for (var i = 0; i < 4; i++) { if (found[i] > 255) return false; }     return true; } else return false; }

// ============================================= // create the dropdown box if not done already, // and (re-)populate it with CDIR ranges based // on the one currently in the user input box // ============================================= function makeOptions { var frm = getBlockForm; if (frm) { var userBox = document.getElementsByName('wpTarget')[0]; if (userBox) { var user = userBox.value;

// check if our added div already exists var div = document.getElementById('rangeBlockSelectionDiv');

// only proceed if the current user is an IP        if (isIP(user)) { var select = document.getElementById('rangeBlockSelector'); if (div) { // if div has already been created: reset the // dropdown box before repopulating it              select.innerHTML = ""; }           else { // create the selection dropdown, inside a new // div div = document.createElement('div'); div.id = "rangeBlockSelectionDiv"; div.appendChild(document.createTextNode("Range block? ")); select = document.createElement('select'); // install onchange event handler on dropdown box: select.onchange = resetUser; select.id = "rangeBlockSelector"; div.appendChild(select); var parent = frm.parentNode; var sibling = frm.nextSibling; if (sibling) { parent.insertBefore(div, sibling) }              else { parent.appendChild(div); }           }            // default value in dropdown box is single IP            var opt = document.createElement('option'); opt.value = user; opt.innerHTML = "single IP (" + user + ")"; select.appendChild(opt); // offer range blocks from /26 to /16 var maxMask = 26; var minMask = 16; for (var i = maxMask; i >= minMask; i--) { opt = makeOption(user, i); select.appendChild(opt); }           // make div visible div.style.display = null; }        else { // make div invisible if it exists if (div) div.style.display = "none"; }     }   } }

function makeOption(ip, mask) { var parts = patternIP.exec(ip); // turn IP string into a single 32-bit integer: var ipVal = (parts[1] * 0x1000000) | (parts[2] * 0x10000)  | (parts[3] * 0x100)    | parts[4]; // get the binary mask var maskVal = Math.pow(2, (32-mask)) - 1; var rgVal = ipVal & maskVal; // make sure the result is treated as an unsigned integer: if (rgVal < 0) rgVal += 0x100000000; rgVal = (ipVal - rgVal); // translate back into four-byte representation: parts = [0,0,0,0]; for (i = 3; i>=0; i--) { parts[i] = rgVal % 0x100; rgVal -= parts[i]; rgVal = rgVal >>> 8; }  var cdir = parts[0] + "." +              parts[1] + "." +              parts[2] + "." +              parts[3] + "/" + mask; var size = Math.pow(2, (32-mask)); var desc = cdir + " (" + size + " IPs )"; var opt = document.createElement('option'); opt.value = cdir; opt.innerHTML = desc; return opt; }

function getBlockForm { // the standard block form has no id, so we need to identify it  // by its action attribute for (var i = document.forms.length - 1; i >= 0; i--) { var frm = document.forms[i]; if (frm.action.search(/\bSpecial:Block\b/) >= 0) { if (! frm.id) frm.id = "_myBlockForm"; document.forms._myBlockForm = frm; return frm; }  }   return null; }

function resetUser { // Onchange event handler of the dropdown box. // Copy selected value back into user input field. var val = this.value; var userBox = document.getElementsByName('wpTarget')[0]; userBox.value = val; var act = document.forms._myBlockForm.action; act = act.replace(/Special:Block\/.+/, "Special:Block/" + val); document.forms._myBlockForm.action = act; }

// install this script as an onload hook $(function {   // only proceed if we are on the Special:Block page   if (document.title.match(/^Block user - Wikipedia, the free encyclopedia$/)) {      var userBox = document.getElementsByName('wpTarget')[0];      if (userBox) {         // call the update function both now, and         // on later onchange events         makeOptions;         userBox.onchange = makeOptions;        }   } });