User:Kaniivel/IPLabeller.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
This user script seems to have a documentation page at User:Kaniivel/IPLabeller and an accompanying .css page at User:Kaniivel/IPLabeller.css. |
/////////////////////////////////////////////////////////////////////////////////////////
// Enables user to set permanent labels and color backgrounds to anonymous IP accounts //
/////////////////////////////////////////////////////////////////////////////////////////
importStylesheet('User:Kaniivel/IPLabeller.css');
// allow user to override colorCodes in common.js, make sure property '4' stays empty
if (!window.colorCodes) {
var colorCodes = {
1:"#FC8888", // red
2:"#ffe299", // yellow
3:"#99FF33", // green
4:"" // white (must be empty)
};
} else {
colorCodes['4'] = "";
}
var messages = {
errNoStorage: 'No storage available. Seems that either:\n \
a) your browser does not support local storage,\n \
b) local storage is turned off, or\n \
c) is full.',
formAddLabel: 'add label',
formChange : 'change',
formLabel : 'Label',
formColor : 'Color',
errMissingIP: 'Error: missing IP address!',
lblDeleted : 'Label removed!',
lblMissing : 'Missing label!',
lblChanged : 'Label changed!',
lblAdded : 'Label added!',
errAction : 'Error: unrecognized action!'
}
preload([
'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/240px-Yes_check.svg.png',
'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/210px-X_mark.svg.png',
'https://upload.wikimedia.org/wikipedia/et/4/42/Ip_label_form_delete.png',
'https://upload.wikimedia.org/wikipedia/et/3/38/Ip_label_form_submit.png'
]);
$(document).ready(function(){
if( typeof(Storage) === "undefined" ) {
// if there is no local storage available, display message and do nothing
throw new Error( messages.errNoStorage );
} else {
// define two custom methods for storing objects
Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
};
Storage.prototype.getObject = function(key) {
var value = this.getItem(key);
return value && JSON.parse(value);
};
createLinks (false);
createEvents ();
}
});
$(document).mouseup(function (e) {
var container = $("div.ip-label-popup");
var link = $("a.mw-anonuserlink");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.hide();
$(link).css({"font-weight": "normal"});
}
var fbcontainer = $("div.ip-label-feedback");
if (!fbcontainer.is(e.target)
&& fbcontainer.has(e.target).length === 0)
{
fbcontainer.hide();
}
});
function createLinks( refresh ) {
var spacer = " ";
if (refresh) {
$("div.ip-label-container").remove();
$("a.mw-anonuserlink").css("background-color","");
}
$("a.mw-anonuserlink").each(function() {
// create link after every IP; add the IP into the link html code
var ip = $(this).text();
var linkText = messages.formAddLabel;
var dataResult = getData( ip );
var keyExists = dataResult.keyExists;
var dataObj = dataResult.dataObj;
if ( keyExists ) {
if (dataObj.label) {
linkText = dataObj.label;
} else if (dataObj.color) {
linkText = messages.formChange;
}
if (dataObj.color) {
$(this).css("background-color", colorCodes[ dataObj.color ])
}
}
var link = $("<div class='ip-label-container'></div>").html("<a href='#' class='ip-label-link' _ip='" + ip + "'>"+ linkText + "</a>");
$(this).after(spacer, link);
});
}
function createEvents () {
$("a.ip-label-link").click(function(event) {
// if the link was clicked ...
event.preventDefault();
var ip = $(this).attr("_ip");
var dataResult = getData( ip );
var keyExists = dataResult.keyExists;
var dataObj = dataResult.dataObj;
// ... make the IP address go bold ...
var iplink = $(this).parent().prev();
iplink.css({"font-weight": "bold"});
// ... create div with input form ...
$(this).after("<div class='ip-label-popup'>" + messages.formLabel + ": <form action='' class='ip-label-popup-form'><input type='hidden' name='ip_address' value='" + ip + "'><input type='text' name='label' autocomplete='off' size='60' value='"+ ( (keyExists && dataObj.label) ? dataObj.label : "") + "' maxlength='60' class='ip-label-popup-input'><div class='ip-label-popup-bottom'>" + messages.formColor + ":<input type='radio' name='color' value=1" + (keyExists && dataObj.color == 1 ? " checked" : "") + "><div class='ip-label-popup-bottom-red'></div><input type='radio' name='color' value=2" + (keyExists && dataObj.color == 2 ? " checked" : "") + "><div class='ip-label-popup-bottom-yellow'></div><input type='radio' name='color' value=3" + (keyExists && dataObj.color == 3 ? " checked" : "") + "><div class='ip-label-popup-bottom-green'></div><input type='radio' name='color' value=4" + (keyExists && dataObj.color == 4 ? " checked" : "") + "><div class='ip-label-popup-bottom-white'></div><div class='ip-label-submit-buttons'><div class='ip-label-form-delete'></div> <div class='ip-label-form-submit'></div></div></div></form></div>");
// this is the div created in the previous statement
var popUpDiv = $(this).next();
// set focus on input field
$(popUpDiv).find("input.ip-label-popup-input").focus();
// set up submit event for the form (we can have more than one way to submit the form)
$(popUpDiv).find("form.ip-label-popup-form").submit(function(event) {
event.preventDefault();
var data = $(this).serializeArray();
var formObj = {};
$.each(data, function(i, val) {
formObj[val.name] = val.value;
});
// pass container div along with the object holding form data to the processor function
processForm(popUpDiv, formObj);
});
// set up click event for the form + button
$(popUpDiv).find(".ip-label-form-submit").on("click", function(){
var form = $(this).closest("form.ip-label-popup-form");
var input = $("<input>").attr("type", "hidden").attr("name", "action").val("add");
$(form).append($(input));
$(form).submit();
iplink.css({"font-weight": "normal"});
});
// set up click event for the form - button
$(popUpDiv).find(".ip-label-form-delete").on("click", function(){
var form = $(this).closest("form.ip-label-popup-form");
var input = $("<input>").attr("type", "hidden").attr("name", "action").val("del");
$(form).append($(input));
$(form).submit();
iplink.css({"font-weight": "normal"});
});
});
}
function processForm (popUpDiv, formObj) {
var fb_msg, isOK;
if ( !formObj.ip_address ) {
// if somehow there is no IP address, call showError function
showError( popUpDiv, messages.errMissingIP );
}
// the key for storage is IP address
var ip = formObj.ip_address;
// check if the key already exists in storage to set up flag for later use
var dataResult = getData( ip );
var keyExists = dataResult.keyExists;
if ( formObj.action == "add" ) {
if ( isBlank(formObj.label) && ( isEmpty(formObj.color) || formObj.color == 4 ) ) {
// if ip label is empty or whitespace and color is undefined or white then delete the entry
deleteData( ip );
if (keyExists) {
var fb_msg = messages.lblDeleted;
var isOK = true;
} else {
var fb_msg = messages.lblMissing;
var isOK = false;
}
showMessage (popUpDiv, fb_msg, isOK);
} else {
// the form has data to save
if ( isEmpty (formObj.color) )
{
formObj.color = 4;
}
var newLabel = {
label:$.trim(formObj.label),
color:formObj.color
};
setData( ip, newLabel );
if (keyExists) {
var fb_msg = messages.lblChanged;
var isOK = true;
} else {
var fb_msg = messages.lblAdded;
var isOK = true;
}
showMessage (popUpDiv, fb_msg, isOK);
}
} else if ( formObj.action == "del" ) {
// delete was clicked, do delete
deleteData ( ip );
if (keyExists) {
var fb_msg = messages.lblDeleted;
var isOK = true;
} else {
var fb_msg = messages.lblMissing;
var isOK = false;
}
showMessage (popUpDiv, fb_msg, isOK);
} else {
showError( popUpDiv, messages.errAction );
}
popUpDiv.remove();
}
function showError (div, errormsg) {
// show error message, destroy popup div and exit
throw new Error( errormsg );
$(div).remove();
}
function showMessage (div, fb_msg, isOK) {
// show feedback message and hide/destroy popup divs
// call refresh list function afterwards
$(div).hide();
var img_Y = 'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/240px-Yes_check.svg.png';
var img_X = 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/210px-X_mark.svg.png';
// create div box for the message
var msg_div = $("<div class='ip-label-feedback'><div class='ip-label-feedback-inner'><img src='" + (isOK ? img_Y : img_X) + "'><div class='ip-label-feedback-inner-message'>" + fb_msg + "</div></div></div>");
$(div).after(msg_div);
msg_div.delay( 1100 ).fadeOut( 1000, function(){
msg_div.remove();
$(div).remove();
createLinks (true);
createEvents ();
});
}
function getData ( key ) {
key = "lbl_" + key;
var labelObj = localStorage.getObject( key );
var keyExists = ( (typeof labelObj === undefined || labelObj === null) ? false : true );
var dataObj;
if (keyExists) {
var dataObj = {
label:labelObj.l,
color:labelObj.c
};
}
return {
keyExists: keyExists,
dataObj: dataObj
};
}
function deleteData ( key ) {
key = "lbl_" + key;
localStorage.removeItem( key );
}
function setData( key, dataObj ) {
key = "lbl_" + key;
var labelObject = { l: dataObj.label, c: dataObj.color };
localStorage.setObject(key, labelObject);
}
function isBlank (str) {
return (!str || /^\s*$/.test(str));
}
function isEmpty(str) {
return (!str || 0 === str.length);
}
function preload( arrayOfImages ) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
});
}