사용자:IRTC1015/IPLabeller.js
보이기
참고: 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다. 구글 크롬, 파이어폭스, 마이크로소프트 엣지, 사파리: ⇧ Shift 키를 누른 채 "새로 고침" 버튼을 클릭하십시오. 더 자세한 정보를 보려면 위키백과:캐시 무시하기 항목을 참고하십시오.
/***
* IPLabeller
*
* IP 사용자에 영구적인 레이블 및 배경색 부여
*
* 원본: [[:en:User:Cumbril/IPLabeller]]
*
* 설정용 변수:
* window.colorCodes: object, 기본값 대신 사용할 색상을 설정
***/
mw.loader.load('//ko.wikipedia.org/w/index.php?title=' +
'User:IRTC1015/IPLabeller.css&action=raw&ctype=text/css', 'text/css');
// allow user to override colorCodes in common.js, make sure property '4' stays empty
if (!window.colorCodes) {
var colorCodes = {
1:"#ffcccc", // red
2:"#ffee99", // yellow
3:"#ccff66", // green
4:"" // white (must be empty)
};
} else {
colorCodes['4'] = "";
}
var messages = {
errNoStorage: '저장소를 사용할 수 없습니다. 다음 사항을 확인 바랍니다.\n' +
'a) 브라우저에서 영구 저장소가 지원되지 않음\n' +
'b) 저장소가 비활성화됨\n' +
'c) 저장소가 가득 참',
formAddLabel: '+',
formAddTitle: '레이블 추가',
formChange : '변경',
formLabel : '레이블',
formColor : '색상',
errMissingIP: '오류: IP가 없습니다',
lblDeleted : '레이블 제거됨',
lblMissing : '레이블 없음',
lblChanged : '레이블 변경됨',
lblAdded : '레이블 추가됨',
errAction : '오류: 알 수 없는 동작'
};
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) {
$(".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 linkTitle = messages.formAddTitle;
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 = $('<span class="ip-label-container"></span>').html('<a href="#" class="ip-label-link" data-ip="' + ip + '" title="' + linkTitle + '">' + 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).data('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) {
fb_msg = messages.lblDeleted;
isOK = true;
} else {
fb_msg = messages.lblMissing;
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) {
fb_msg = messages.lblChanged;
isOK = true;
} else {
fb_msg = messages.lblAdded;
isOK = true;
}
showMessage (popUpDiv, fb_msg, isOK);
}
} else if ( formObj.action == "del" ) {
// delete was clicked, do delete
deleteData ( ip );
if (keyExists) {
fb_msg = messages.lblDeleted;
isOK = true;
} else {
fb_msg = messages.lblMissing;
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;
});
}