MediaWiki:Gadget-labelLister.js/beta.js

importScript( 'MediaWiki:Gadget-extJsNotif.js'); importStylesheet("MediaWiki:Gadget-extJsNotif.css"); importStylesheet("MediaWiki:Gadget-labelLister.css");

var labelLister = ( function (mw, $){	"use strict";

/**	 * Get the ID of the current entity. (if it's not an entity it terminate the script) */	var itemId = mw.config.get( 'wbEntityId' ); if ( !itemId ) { return; }

/**	 * Get the user's language */	var lang = mw.config.get( 'wgUserLanguage' );

/**	 * Write a line on the table */	function LlTable (elem){ this.tableElement = elem; this.authorizedLanguage = ["aa", "ab", "abs", "ace", "ady", "ady-cyrl", "aeb", "aeb-arab", "aeb-latn", "af", "ak", "aln", "als", "alt", "am", "ami", "an", "ang", "anp", "ar", "arc", "arn", "arq", "ary", "arz", "as", "ase", "ast", "atj", "av", "avk", "awa", "ay", "az", "azb", "ba", "ban", "bar", "bbc", "bbc-latn", "bcc", "bcl", "be", "be-tarask", "bg", "bgn", "bho", "bi", "bjn", "bm", "bn", "bo", "bpy", "bqi", "br", "brh", "bs", "btm", "bto", "bug", "bxr", "ca", "cbk-zam", "cdo", "ce", "ceb", "ch", "cho", "chr", "chy", "ckb", "co", "cps", "cr", "crh", "crh-cyrl", "crh-latn", "cs", "csb", "cu", "cv", "cy", "da", "dag", "de", "de-at", "de-ch", "de-formal", "din", "diq", "dsb", "dtp", "dty", "dua", "dv", "dz", "ee", "egl", "el", "eml", "en", "en-ca", "en-gb", "eo", "es", "es-419", "es-formal", "et", "eu", "ext", "fa", "ff", "fi", "fit", "fj", "fkv", "fo", "fr", "frc", "frp", "frr", "fur", "fy", "ga", "gag", "gan", "gan-hans", "gan-hant", "gcr", "gd", "gl", "glk", "gn", "gom", "gom-deva", "gom-latn", "gor", "got", "grc", "gsw", "gu", "guc", "gv", "ha", "hak", "haw", "he", "hi", "hif", "hif-latn", "hil", "ho", "hr", "hrx", "hsb", "ht", "hu", "hu-formal", "hy", "hyw", "hz", "ia", "id", "ie", "ig", "ii", "ik", "ike-cans", "ike-latn", "ilo", "inh", "io", "is", "it", "iu", "ja", "jam", "jbo", "jut", "jv", "ka", "kaa", "kab", "kbd", "kbd-cyrl", "kbp", "kcg", "kea", "kg", "khw", "ki", "kiu", "kj", "kjp", "kk", "kk-arab", "kk-cn", "kk-cyrl", "kk-kz", "kk-latn", "kk-tr", "kl", "km", "kn", "ko", "ko-kp", "koi", "kr", "krc", "kri", "krj", "krl", "ks", "ks-arab", "ks-deva", "ksh", "ku", "ku-arab", "ku-latn", "kum", "kv", "kw", "ky", "la", "lad", "lb", "lbe", "lez", "lfn", "lg", "li", "lij", "liv", "lki", "lld", "lmo", "ln", "lo", "loz", "lrc", "lt", "ltg", "lus", "luz", "lv", "lzh", "lzz", "mad", "mai", "map-bms", "mdf", "mg", "mh", "mhr", "mi", "min", "mk", "ml", "mn", "mni", "mnw", "mo", "mr", "mrh", "mrj", "ms", "ms-arab", "mt", "mus", "mwl", "my", "myv", "mzn", "na", "nah", "nan", "nap", "nb", "nds", "nds-nl", "ne", "new", "ng", "nia", "niu", "nl", "nl-informal", "nn", "nod", "nov", "nqo", "nrm", "nso", "nv", "ny", "nys", "oc", "olo", "om", "or", "os", "ota", "pa", "pag", "pam", "pap", "pcd", "pdc", "pdt", "pfl", "pi", "pih", "pl", "pms", "pnb", "pnt", "prg", "ps", "pt", "pt-br", "pwn", "qu", "qug", "rgn", "rif", "rm", "rmf", "rmy", "rn", "ro", "roa-tara", "ru", "rue", "rup", "ruq", "ruq-cyrl", "ruq-latn", "rw", "rwr", "ryu", "sa", "sah", "sat", "sc", "scn", "sco", "sd", "sdc", "sdh", "se", "sei", "ses", "sg", "sgs", "sh", "shi", "shi-latn", "shi-tfng", "shn", "shy", "shy-latn", "si", "simple", "sjd", "sje", "sju", "sk", "skr", "skr-arab", "sl", "sli", "sm", "sma", "smj", "smn", "sms", "sn", "so", "sq", "sr", "sr-ec", "sr-el", "srn", "srq", "ss", "st", "stq", "sty", "su", "sv", "sw", "szl", "szy", "ta", "tay", "tcy", "te", "tet", "tg", "tg-cyrl", "tg-latn", "th", "ti", "tk", "tl", "tly", "tly-cyrl", "tn", "to", "tpi", "tr", "tru", "trv", "ts", "tt", "tt-cyrl", "tt-latn", "tum", "tw", "ty", "tyv", "tzm", "udm", "ug", "ug-arab", "ug-latn", "uk", "ur", "uz", "uz-cyrl", "uz-latn", "ve", "vec", "vep", "vi", "vls", "vmf", "vo", "vot", "vro", "wa", "war", "wls", "wo", "wuu", "xal", "xh", "xmf", "xsy", "yi", "yo", "yue", "za", "zea", "zgh", "zh", "zh-cn", "zh-hans", "zh-hant", "zh-hk", "zh-mo", "zh-my", "zh-sg", "zh-tw", "zu"]; this.openedLanguage = []; this.diff = {}; }

LlTable.prototype = { addCol: function(lang, type, data, cols, rows){ //Condition if(typeof lang != "string"){ throw "You've sent the wrong type of data through lang param of LlTable.addCol"; }			if(typeof type != "string"){ throw "You've sent the wrong type of data through type param of LlTable.addCol"; }			if(typeof cols != "number"){ throw "You've sent the wrong type of data through cols param of LlTable.addCol"; }			if(typeof rows != "number"){ throw "You've sent the wrong type of data through rows param of LlTable.addCol"; }

var ret = '';

//console.log(data); if(typeof data == "object" && data instanceof Array){ ret += '';

for(var key in data){ if(!data.hasOwnProperty(key)){ continue; }

ret += '' + mw.html.escape( data[key] ) + ''; }

ret += '+';

ret += ''; }

if(typeof data == "string"){ ret += '' + mw.html.escape( data ) + ' ';

}

ret += " ";

return ret; },		addRow: function(lang, data){ if(typeof lang != "string"){ throw "You've sent the wrong type of data through lang param of LlTable.addRow"; }			if(typeof data != "object"){ throw "You've sent the wrong type of data through data param of LlTable.addRow"; }			if(this.authorizedLanguage.indexOf(lang) == -1){ throw "You've sent a lang param that isn't recognized by MediaWiki!"; }			if(this.openedLanguage.indexOf(lang) != -1){ throw "This language has already been added!"; }else{ this.openedLanguage.push(lang); }

//First line var ret = '';

ret += this.addCol(lang, "lang", (typeof mw.config.get( 'wgULSLanguages' )[lang] == "undefined")?lang:mw.config.get( 'wgULSLanguages' )[lang], 1, 2); ret += this.addCol(lang, "label", data.label, 1, 1); ret += this.addCol(lang, "description", data.description, 1, 1);

ret += ' ';

//Second line ret += '';

ret += this.addCol(lang, "aliases", data.aliases, 2, 1);

ret += ' ';

$(this.tableElement).append(ret);

return ret; },		addRows: function(data){ if(typeof data != "object"){ throw "You've sent the wrong type of data through data param of LlTable.addRows"; }

//Reset (no opened language, empty table, close edition) this.unEditCols; $(this.tableElement).empty; this.openedLanguage = [];

//fetch each line for(var key in data){ if(!data.hasOwnProperty(key)){ continue; }

try{ this.addRow(key, data[key]); }catch (e){ notice.addError("Error", "Couldn't resolve language abreviation (" + key + ") sent by the database", false, true); }			}

this.setEvent;

},		editCol: function(e){ if(!$(e).hasClass("ll-lang") && !$(e).hasClass("ll-pending-edition")){ table.unEditCols; $(e).removeClass("ll-deleted"); $(e).removeClass("ll-edited"); $(e).addClass("ll-pending-edition");

var inner = e.textContent; if(typeof $(e).prop("old") == "undefined"){ $(e).prop('old', inner); }				var old = $(e).prop("old");

$(e).html('');

$('#lli').focus; }		},		unEditCols: function{ $(".ll-pending-edition").each(function {				$(this).removeClass("ll-pending-edition");

//Easter egg (whoops!!) var rE = new RegExp("whoops!!"); if(rE.test($(this).children('input').val)){ $(this).children('input').val($(this).prop("old")); }

var inner = $(this).children('input').val; var old = $(this).prop("old");

if(!$(this).hasClass("ll-list")) { $(this).removeClass("ll-deleted"); $(this).removeClass("ll-edited"); if (inner === "" && old !== "") { $(this).addClass("ll-deleted"); } else if (inner != old) { $(this).addClass("ll-edited"); }				}else{ $(this).addClass("ll-list-added"); }

$(this).text(inner);

//prevent empty list if(inner === "" && $(this).hasClass("ll-list")){ table.deleteList(this); }			});		},		addList: function(e){			table.unEditCols;			var appendice = ' ';			$(e).before(appendice);		},		deleteList: function(e){			table.unEditCols;			$(e).remove;		},		removeList: function(e){			table.unEditCols;			if(!$(e).hasClass("ll-list-removed")) {				$(e).addClass("ll-list-removed");			}else{				$(e).removeClass("ll-list-removed");			}		},		setEvent: function {			//add new language			$(".ll-add-lang").each(function { if(!$(this).hasClass("ll-event")) { $(this).addClass("ll-event"); $(this).click(function {						if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) {							var lang = prompt("Which language to add? Enter its language code here:");							if (lang === null) {								notice.addError("Error", "Cannot get information from the prompt", true, false);								return;							}							try {								table.addRow(lang, {label: "", description: "", aliases: []});							} catch (e) {								notice.addWarning("Attention", e, true, false);							}

//update all event table.setEvent; }					});				}			});

//add event on data $(".ll-single").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) { table.editCol(this);

//update all event table.setEvent; }					});				}			});

//add event on add list button $(".ll-list-add").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) { table.addList(this);

//update all event table.setEvent; }					});				}			});

//add event on add list button $(".ll-list-added").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) { table.deleteList(this);

//update all event table.setEvent; }					});				}			});

//add event on add list button $(".ll-list").each(function {				if(!$(this).hasClass("ll-event") && !$(this).hasClass("ll-list-added") && !$(this).hasClass("ll-list-add") && !$(this).hasClass("ll-pending-edition")) {					$(this).addClass("ll-event");					$(this).click(function  { if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) { table.removeList(this);

//update all event table.setEvent; }					});				}			});

//close edition on return $(".ll-pending-edition input") .blur(function {					table.unEditCols;

//update all event table.setEvent; })				.keyup(function (e) { if(e.which == 13) { table.unEditCols;

//update all event table.setEvent; }				});

//Search $(".ll-search-lang-input").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).keyup(function  { if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) { table.unEditCols;

var search = $(this).parent.children("input").val; if(search == ""){ $(".ll-search-lang-clear").animate({opacity:0},200); }else{ $(".ll-search-lang-clear").animate({opacity: 1}, 400); }							table.search(search);

//update all event table.setEvent; }					});				}			});			//Clear search $(".ll-search-lang-clear").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) { table.unEditCols;

$(this).parent.children("input").val(""); $(".ll-search-lang-clear").animate({opacity:0},200); table.search("");

//update all event table.setEvent; }					});				}			});

//Accept changes $(".ll-preview-send").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { if($(table.tableElement).parent("table").hasClass("ll-table-blocked")) { var resume = $(".ll-preview-resume").val;

if(model.sendDatas(table.diff, resume)){ table.addRows(model.receiveDatas); table.unlock; }

//update all event table.setEvent; }					});				}			});

//Cancel changes $(".ll-preview-return").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { if($(table.tableElement).parent("table").hasClass("ll-table-blocked")) {

table.addRows(model.receiveDatas); table.setDiff(table.diff); table.unlock;

//update all event table.setEvent; }					});				}			});

//Cancel changes $(".ll-preview-cancel").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { if($(table.tableElement).parent("table").hasClass("ll-table-blocked")) {

table.addRows(model.receiveDatas); table.unlock;

//update all event table.setEvent; }					});				}			});

//Display information $(".ll-info").each(function {				if(!$(this).hasClass("ll-event")) {					$(this).addClass("ll-event");					$(this).click(function  { alert("\n== Label & Description ==\n" +							" * To edit label and description just click on it.\n" +							" * Blue and red ones are those which are changed from the original.\n" +							" * Type \"whoops!!\" without quote anywhere in a field to return to the original value.\n" +							"\n== Aliases ==\n" +							" * To delete an alias from the original click on it, it becomes red. To undo a deletion re-click on it.\n" +							" * To create an alias click on the (+), it creates a new blue one. To cancel a creation from the original just re-click, it will disappear.\n" +							" * To edit an alias. Delete it from the original then create a new one.\n" +							" * Blue ones are those which will be created and red ones are those which woill be deleted from the original.\n" +							"\n== Language ==\n" +							" * If a language doesn't appear in the table, click on (add new language) to add a new one.\n" + " * You can search for a language in the field (search a language).\n" + "\n== Other ==\n" + " * Click on (reload) the re-download data from the server\n" + " * Click on preview to see your change. You need to preview before saving.\n" + "\n== Preview ==\n" + " * Set a summary to explain your change. A summary of what you've changed is automatically added after your summary.");

//update all event table.setEvent; });				}			});		},		getDiffSingle: function (type) { if(typeof type != "string"){ throw "You've sent a wrong type of data through type param of LlTable.getDataSingle"; }

var ret = {};

$(".ll-" + type + ".ll-edited, .ll-" + type + ".ll-deleted").each( function{				ret[$(this).prop("lang")] = {};				ret[$(this).prop("lang")].new = $(this).text;				ret[$(this).prop("lang")].old = $(this).prop("old");			});

this.diff = ret;

return ret; },		getDiffLists: function (type) { if(typeof type != "string"){ throw "You've sent a wrong type of data through type param of LlTable.getDataSingle"; }

var ret = {};

$(".ll-lists.ll-aliases .ll-list.ll-list-removed, .ll-lists.ll-aliases .ll-list.ll-list-added").each( function{				if(typeof ret[$(this).prop("lang")] == "undefined"){					ret[$(this).prop("lang")] = {};				}				if($(this).hasClass("ll-list-removed")){					if(typeof ret[$(this).prop("lang")].del == "undefined"){						ret[$(this).prop("lang")].del = [];					}					ret[$(this).prop("lang")].del.push($(this).text);				}else if($(this).hasClass("ll-list-added")){					if(typeof ret[$(this).prop("lang")].add == "undefined"){						ret[$(this).prop("lang")].add = [];					}					ret[$(this).prop("lang")].add.push($(this).text);				}			});

return ret; },		getDiff: function { var ret = {};

ret.label = this.getDiffSingle("label"); ret.description = this.getDiffSingle("description"); ret.aliases = this.getDiffLists("aliases");

table.diff = ret;

return ret; },		setDiff: function (data) { for(var type in data){ if(!data.hasOwnProperty(type)){ continue; }

for(var lang in data[type]){ if(!data[type].hasOwnProperty(lang)){ continue; }

if($('.ll-row[lang="' + lang + '"]').length == 0){ this.addRow(lang, {label: "", description:"", aliases:[]}); }

if(data[type][lang].hasOwnProperty("new") && data[type][lang].hasOwnProperty("old")){

$('.ll-single.ll-' + type + '[lang="' + lang + '"]') .prop("old", data[type][lang].old) .text(data[type][lang].new) .addClass((data[type][lang].new == "")?"ll-deleted":"ll-edited");

}else if(data[type][lang].hasOwnProperty("add") || data[type][lang].hasOwnProperty("del")) {

if (data[type][lang].hasOwnProperty("del")) { $('.ll-lists.ll-' + type + '[lang="' + lang + '"] .ll-list').each(function {								for (var alias in data[type][lang].del) {									if($(this).text == data[type][lang].del[alias]){										$(this).addClass("ll-list-removed");									}								}							}) }

if (data[type][lang].hasOwnProperty("add")) { for (var alias in data[type][lang].add) { $('.ll-lists.ll-' + type + '[lang="' + lang + '"] .ll-list-add').before('' + data[type][lang].add[alias] + '') }						}

}				}			}		},		showDiffs: function { var data = this.getDiff; this.tableElement.empty;

var ret = "";

for(var type in data){ if(!data.hasOwnProperty(type)){ continue; }

if(data[type].length <= 0){ ret += " "; ret += '' + type + ' '; ret += ' '; ret += ' '; }else{ var nb = 0; for(var lang in data[type]){ if(!data[type].hasOwnProperty(lang)){ continue; }

nb++; ret += " "; if(nb == 1){ ret += '<td class="ll-preview-type" rowspan="' + Object.keys(data[type]).length + '">' + type + ' '; }						ret += '<td class="ll-preview-lang" lang="' + lang + '">' + ((typeof mw.config.get( 'wgULSLanguages' )[lang] == "undefined")?lang:mw.config.get( 'wgULSLanguages' )[lang]) + ' ';

ret += '<td class="ll-preview-' + type + '">'; if(data[type][lang].hasOwnProperty("new") && data[type][lang].hasOwnProperty("old")){ ret += '<div class="ll-preview-old ' + ((data[type][lang].old == "")?"ll-preview-empty":"") + '">' + data[type][lang].old + ' '; ret += '<div class="ll-preview-new ' + ((data[type][lang].new == "")?"ll-preview-empty":"") + '">' + data[type][lang].new + ' '; }else if(data[type][lang].hasOwnProperty("add") || data[type][lang].hasOwnProperty("del")){ ret += ''; if(data[type][lang].hasOwnProperty("del")){ for(var key in data[type][lang].del){ if(!data[type][lang].del.hasOwnProperty(key)){ continue; }

ret += '' + data[type][lang].del[key] + '</li>'; }							}							if(data[type][lang].hasOwnProperty("add")){ for(var key in data[type][lang].add){ if(!data[type][lang].add.hasOwnProperty(key)){ continue; }

ret += '' + data[type][lang].add[key] + '</li>'; }							}							ret += '</ul>'; }						ret += ' ';

ret += ' '; }				}			}

this.tableElement.html(ret); this.initResumeInput;

return ret; },		lock: function { this.unEditCols; $(table.tableElement).parent("table").addClass("ll-table-blocked"); },		unlock: function { this.unEditCols; $(table.tableElement).parent("table").removeClass("ll-table-blocked"); },		head: function ( number ) { var allHead = [1, 2];

if(allHead.indexOf(number) == -1){ throw "Wrong head number"; }

for(var i in allHead){ if(!allHead.hasOwnProperty(i)){ continue; }

$(table.tableElement).parent("table").removeClass("ll-head" + allHead[i] ); $("#ll-form").removeClass("ll-form" + allHead[i] ); }

$("#ll-form").addClass("ll-form" + number );

$(table.tableElement).parent("table").addClass("ll-head" + number ); },		search: function (name) { if(typeof name == "undefined" || name == ""){ this.unEditCols; $(this.tableElement).children("tr").css("display", "table-row"); }else{ this.unEditCols; $(this.tableElement).children("tr").each(function {					var lang = $(this).prop("lang");					var language = (typeof mw.config.get( 'wgULSLanguages' )[lang] == "undefined")?lang:mw.config.get( 'wgULSLanguages' )[lang];					var rE = new RegExp(name);					if(rE.test(lang) || rE.test(language)){						$(this).css("display", "table-row");					}else{						$(this).css("display", "none");					}				}); }		},		initResumeInput: function { $(".ll-preview-resume").prop("placeholder", model.generateSummary(this.diff)) }	};

/**	 * Write a line on the table */	function LlModel (Qid){ this.item = Qid; this.lastrevid = 0; }

LlModel.prototype = { api: function (req, data) { return $.ajax({				type: req,				url: mw.util.wikiScript('api'),				async: false,				data: data			}); },		diff2json: function (data) { var ret = {labels:{},descriptions:{},aliases:{}};

for(var key in data.label){ if(!data.label.hasOwnProperty(key)){ continue; }

ret.labels[key] = {}; ret.labels[key].language = key; ret.labels[key].value = data.label[key].new; }

for(var key in data.description){ if(!data.description.hasOwnProperty(key)){ continue; }

ret.descriptions[key] = {}; ret.descriptions[key].language = key; ret.descriptions[key].value = data.description[key].new; }

for(var key in data.aliases){ if(!data.aliases.hasOwnProperty(key)){ continue; }

ret.aliases[key] = []; for(var state in data.aliases[key]){ if(!data.aliases[key].hasOwnProperty(state)){ continue; }

for(var it in data.aliases[key][state]){ if(!data.aliases[key][state].hasOwnProperty(it)){ continue; }

var obj = {}; obj.language = key; obj.value = data.aliases[key][state][it]; if(state == "add"){ obj.add = ''; }else if(state == "del"){ obj.remove = ''; }

ret.aliases[key].push(obj); }				}			}

return ret; },		json2view: function (data) { var ret = {};

if(!data.hasOwnProperty("entities")){ return; }			if(!data.entities.hasOwnProperty(this.item)){ return; }			data = data.entities[this.item];

//labels for( var key in data.labels){ if(!data.labels.hasOwnProperty(key)){ continue; }

if(typeof ret[key] == "undefined"){ ret[key] = {label: "", description:"", aliases: []}; }				ret[key].label = data.labels[key].value; }

//descriptions for( var key in data.descriptions){ if(!data.descriptions.hasOwnProperty(key)){ continue; }

if(typeof ret[key] == "undefined"){ ret[key] = {label: "", description:"", aliases: []}; }				ret[key].description = data.descriptions[key].value; }

//aliases for( var key in data.aliases){ if(!data.aliases.hasOwnProperty(key)){ continue; }

if(typeof ret[key] == "undefined"){ ret[key] = {label: "", description:"", aliases: []}; }				ret[key].aliases = []; for(var it in data.aliases[key]){ if(!data.aliases[key].hasOwnProperty(it)){ continue; }

ret[key].aliases.push(data.aliases[key][it].value); }			}

return ret; },		sendDatas: function ( data, resume ) {

var json = this.diff2json(data);

if(this.lastrevid == 0){ notice.addError("Error 418", "I’m a teapot !", false, true); //You're not supposed being there without receiving datas return false; }

var success = false;

this.api("POST", {				action: "wbeditentity",				format: "json",				id: model.item,				summary: "LabelLister V3 (beta) - " + resume + " : " + model.generateSummary(table.diff),				data: JSON.stringify(json),				token: mw.user.tokens.get( 'csrfToken' ),				baserevid: this.lastrevid			}).done(function (data) {				if(data.hasOwnProperty("error")){					notice.addError("Error", "(" + data.error.code + ") " + data.error.info, true, false);				}else if(data.hasOwnProperty("success")){					notice.addSuccess("Success", "This edit has been correctly sent to the database", false, true);					success = true;				}			}).fail(function {				notice.addError("Error", "The request to the API failed.", true, false);			});

return success;

},		receiveDatas: function { var ret = {};

table.head(1); this.api("GET", {				action: "wbgetentities",				format: "json",				ids: this.item			}).done(function (data) {				if(data.hasOwnProperty("error")){					notice.addError("Error", "(" + data.error.code + ") " + data.error.info, true, false);					return {};				}else if(data.entities[model.item].hasOwnProperty("missing")){					notice.addWarning("Attention", "The entity you want to edit doesn't exist or has been deleted. You need to create it first.", false, true);					return {};				}				model.lastrevid = data.entities[model.item].lastrevid;				ret = model.json2view(data);

}).fail(function {

notice.addError("Error", "The request to the API failed.", true, false);

});

return ret; },		generateSummary: function (data) { var ret = {label:{new:[], del:[], edit:{}}, desc:{new:[], del:[], edit:{}}, alias:{}};

//labels for(var lang in data.label){ if(!data.label.hasOwnProperty(lang)) { continue; }

var o = 0; if(data.label[lang].hasOwnProperty("old")) { o = data.label[lang].old.length; }

var n = 0; if(data.label[lang].hasOwnProperty("new")) { n = data.label[lang].new.length; }

var d = n - o;				if(o == 0){ ret.label.new.push(lang); }else if(n == 0){ ret.label.del.push(lang); }else{ ret.label.edit[lang] = d;				} }

//descriptions for(var lang in data.description){ if(!data.description.hasOwnProperty(lang)) { continue; }

var o = 0; if(data.description[lang].hasOwnProperty("old")) { o = data.description[lang].old.length; }

var n = 0; if(data.description[lang].hasOwnProperty("old")) { n = data.description[lang].new.length; }

var d = n - o;

if(o == 0){ ret.desc.new.push(lang); }else if(n == 0){ ret.desc.del.push(lang); }else{ ret.desc.edit[lang] = d;				} }

//aliases for(var lang in data.aliases){ if(!data.aliases.hasOwnProperty(lang)) { continue; }

var a = 0; if(data.aliases[lang].hasOwnProperty("add")) { a = data.aliases[lang].add.length; }

var d = 0; if(data.aliases[lang].hasOwnProperty("del")) { d = -data.aliases[lang].del.length; }

ret.alias[lang] = [a, d]; }

console.log(JSON.stringify(ret));

//sorting edit property

//Generate Text from JSON var text = "";

var first1 = true;

/*			 * Objects iteration (label, desc, alias) */			for(var obj in ret){ if(!ret.hasOwnProperty(obj)){ continue; }

//See if there's modifiction inside var nb = 0; if(ret[obj].hasOwnProperty("new") && ret[obj].hasOwnProperty("del") && ret[obj].hasOwnProperty("edit")){ nb = ret[obj].new.length + ret[obj].del.length + objectSize(ret[obj].edit); }else{ nb = objectSize(ret[obj]); }				if(nb == 0){ continue; }

if(!first1){ text += ", "; }else{ first1 = false; }

text += obj + "(";

var first2 = true; /*				 * State iteration (new, del, edit, etc...) */				for(var state in ret[obj]){ if(!ret[obj].hasOwnProperty(state)){ continue; }

if(ret[obj][state].length == 0 || objectSize(ret[obj][state]) == 0){ continue; }

if(!first2){ text += ", " }else{ first2 = false; }

switch (state){ case "new": case "del": text += state + "[";

var first3 = true; /*							 * Element iteration */							for(var lang in ret[obj][state]){ if(!ret[obj][state].hasOwnProperty(lang)){ continue; }

if(!first3){ text += ", "; }else{ first3 = false; }

text += ret[obj][state][lang]; }

text += "]"; break; case "edit": text += state + "[";

var first3 = true; /*							 * Element iteration */							for(var lang in ret[obj][state]){ if(!ret[obj][state].hasOwnProperty(lang)){ continue; }

if(!first3){ text += ", "; }else{ first3 = false; }

text += lang + "(" + ((ret[obj][state][lang] > 0)?'+':'') + ret[obj][state][lang] + ")"; }

text += "]"; break; default : text += state + "[";

var first3 = true; /*							 * Element iteration */							for(var diff in ret[obj][state]){ if(!ret[obj][state].hasOwnProperty(diff)){ continue; }

if(ret[obj][state][diff] == 0){ continue; }

if(!first3){ text += "/"; }else{ first3 = false; }

text += ((ret[obj][state][diff] > 0)?'+':'') + ret[obj][state][diff]; }

text += "]"; break; }				}

text += ")";			}

return text; }	};

/**	 * Object size */	function objectSize( obj ) { var size = 0; for(var key in obj){ if(!obj.hasOwnProperty(key)){ continue; }			size++ }		return size; };

/**	 * Init instances of Class */	var notice, table, model;

/**	 * Init portlet and modal on the view */	function initCurrentPage { //Modal Content var modalContent = ' ' +			'<form id="ll-form" onsubmit="return false;">' + '<ul id="ll-notice"></ul>' + ' [+] Add new language ' + ' ' +			' &times; ' + '<input placeholder="Search a language" class="ll-search-lang-input"/>' + ' ' +			' ' +			' ' +			' <label for="ll-summary">Summary : ' + '<input type="text" id="ll-summary" class="ll-preview-resume"/>' + '<button class="ll-preview-send">Accept changes ' + '<button class="ll-preview-return">Return to edits ' + '<button class="ll-preview-cancel">Cancel ' + ' ' +			' ' +			' ';

//Modal location var modalExec; if ( document.getElementById( 'content' ) ) { modalExec = $( modalContent ).appendTo( '#content' ); } else { modalExec = $( modalContent ).appendTo( '#mw_content' ); }

//Modal Function mw.loader.using( ['jquery.ui'], function {			modalExec.dialog( { title: '<img id="labelLister-logo" src="//upload.wikimedia.org/wikipedia/commons/d/db/Symbol_list_class.svg" style="width:20px"> List of all labels in different languages', autoOpen: false, modal: true, width: 900, height: 650, show: 'blind', hide: 'blind', buttons: [ { text: "Preview", id: 'll-preview', click: function { if(!$(table.tableElement).parent("table").hasClass("ll-table-blocked")) { table.unEditCols; table.lock; table.head(2); table.showDiffs; //console.log(JSON.stringify(model.diff2json(table.getDiff))); }					}				},{					text: "Reload", id: 'll-reload', click: function { table.lock; $(".ll-search-lang-input").val(""); table.addRows(model.receiveDatas); table.unlock; }				}, {					text: "Close", click: function { $( this ).dialog( 'close' ); }				} ]			} );		});

//Portlet Link options var portletLinkNextNode = $.uls.data.isRtl( lang ) ? '#ca-view' : '#ca-history'; var portletId = ( mw.config.get( 'skin' ) === 'vector' ) ? 'p-views' : 'p-cactions'; var portletLink = mw.util.addPortletLink( portletId, '#', "List of headers (BETA)", 't-labelLister', "List of labels", 'e', portletLinkNextNode );

//Portlet Link Action $( portletLink ).click( function {			$( 'div#labelListerv3' ).dialog( 'open' );

//On opening table.addRows(model.receiveDatas); table.unlock;

return false; } );

//Init notice Class notice = new JsNotice($("#ll-notice"));

//Init model Class model = new LlModel (itemId);

//Init table Class table = new LlTable ($("#ll-table tbody"));

//Require once notice.addInfo("BETA version", "This is a beta version, please check your contributions. (<a href=\"\" onclick=\"mw.cookie.set('llBETA', 'false');\">go back to released version</a>)", false, true); notice.addInfo("Tips and tricks", "Just click to edit. You need to preview changes before saving. Click <a href=\"#\" class=\"ll-info\">here</a> to get more information.", false, true);

}	/**	 * LOADER COMPONENT */	function preventLoader{ var semaphore = false; var interval = setInterval(function{			if(typeof JsNotice != "undefined" && !semaphore){				semaphore = true;				initCurrentPage;				window.clearInterval(interval);			}		},100); }

$( preventLoader );

var ret = new Object; ret.notice = notice; ret.table = table; ret.model = model; return new LlTable;

} ( mediaWiki, jQuery ) );