User:Kaniivel/IPLabeller.js

///////////////////////////////////////////////////////////////////////////////////////// // 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 = $(" ").html(""+ linkText + "");		$(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(" " + messages.formLabel + ":  " + messages.formColor + ":       "); // 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 = $(" ").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 = $(" ").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 = $("  " + fb_msg + "  "); $(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{       $(' ')[0].src = this;    }); }