MediaWiki:Gadget-taginfo.js: Difference between revisions

From OpenStreetMap Wiki
Jump to navigation Jump to search
(Fixed error when value is set to a number)
(Avoid evaluating keys and values as Booleans when testing whether they are specified)
Line 1: Line 1:
$(function() {
$(function() {
$('.taginfo-ajax').each(function() {
$('.taginfo-ajax').each(function() {
if($(this).data('taginfo-value')) {
if (typeof $(this).data('taginfo-value') !== 'undefined') {
taginfoLoad($(this));
taginfoLoad($(this));
} else if($(this).data('taginfo-key')) {
} else if (typeof $(this).data('taginfo-key') !== 'undefined') {
keyinfoLoad($(this));
keyinfoLoad($(this));
} else if($(this).data('taginfo-rtype')) {
} else if (typeof $(this).data('taginfo-rtype') !== 'undefined') {
relationLoad($(this));
relationLoad($(this));
}
}

Revision as of 19:17, 27 May 2022

$(function() {
	$('.taginfo-ajax').each(function() {
		if (typeof $(this).data('taginfo-value') !== 'undefined') {
			taginfoLoad($(this));
		} else if (typeof $(this).data('taginfo-key') !== 'undefined') {
			keyinfoLoad($(this));
		} else if (typeof $(this).data('taginfo-rtype') !== 'undefined') {
			relationLoad($(this));
		}
	});
});

function decodeHtmlEntities(encoded) {
	return ('' + encoded)
		.replace(/&lt;/g, '<')
		.replace(/&gt;/g, '>')
		.replace(/&amp;/g, '&')
		.replace(/&quot;/g, '"')
		.replace(/&nbsp;/g, '\u00a0');
}

function taginfoLoad(box) {
	var urlBase = box.data("taginfo-url");
	var key = decodeHtmlEntities(box.data('taginfo-key'));
	var value = decodeHtmlEntities(box.data('taginfo-value'));

	$.when(
		$.ajax(urlBase + "/api/4/tag/stats", {
			data: {
				key: key,
				value: value
			}
		}),
		$.ajax(urlBase + "/api/4/key/stats", {
			data: {
				key: key
			}
		})
	).then(function(tagData, keyData) {
		var taginfoData = statsMap(tagData[0].data);

		if(isTagEmpty(taginfoData)) {
        	box.find(".ti_content").hide();
        	box.find(".ti_empty").html(box.data("taginfo-no-such-tag"));
        	box.find(".ti_empty").show();
        	box.find(".ti_empty").show();
        	box.css("display", "block");
        	return;
        }

		var taginfoKeyData = statsMap(keyData[0].data);

		setPercent(box, ".all-pct", taginfoData.all, taginfoKeyData.all);
		setPercent(box, ".node-pct", taginfoData.nodes, taginfoKeyData.nodes);
		setPercent(box, ".way-pct", taginfoData.ways, taginfoKeyData.ways);
		setPercent(box, ".rel-pct", taginfoData.relations, taginfoKeyData.relations);

		populateCountsAndShow(box,taginfoData);
	},
	function(err) { displayError(box) });
}

function keyinfoLoad(box) {
	var urlBase = box.data("taginfo-url");
	var key = decodeHtmlEntities(box.data('taginfo-key'));

	$.when(
		$.ajax(urlBase + "/api/4/key/stats", {
			data: {
				key: key
			}
		})
	).then(function(keyData) {
		var taginfoKeyData = statsMap(keyData.data);

		if(isTagEmpty(taginfoKeyData)) {
        	box.find(".ti_content").hide();
        	box.find(".ti_empty").html(box.data("taginfo-no-such-tag"));
        	box.find(".ti_empty").show();
        	box.css("display", "block");
        	return;
        }
		
		populateCountsAndShow(box,taginfoKeyData);
	},
	function(err) { displayError(box) });
}

function relationLoad(box) {
	var urlBase = box.data("taginfo-url");
	var rtype = decodeHtmlEntities(box.data('taginfo-rtype'));

	$.when(
		$.ajax(urlBase + "/api/4/tag/stats", {
			data: {
				key: 'type',
				value: rtype
			}
		}),
		$.ajax(urlBase + "/api/4/relation/stats", {
			data: {
				rtype: rtype
			}
		}),
		$.ajax(urlBase + "/api/4/relation/roles", {
			data: {
				page: 1,
				rp: 10,
				sortname: 'count_all_members',
				sortorder: 'desc',
				rtype: rtype
			}
		})
	).then(function(keyData, relData, relStats) {
		var taginfoKeyData = statsMap(keyData[0].data);
		var taginfoRelData = statsMap(relData[0].data);
        var roleData = relStats[0].data;

		var roles = [];

		for (i = 0; i < roleData.length; i++) {
			if(roleData[i].count_all_members_fraction > 0.01) {
				var role = roleData[i].role;
				if(role) {
					roles.push(roleData[i].role);
				} else {
					roles.push(box.data("taginfo-empty-role"));
				}
			}
		}

		box.find(".rel-count").html(mw.language.convertNumber(taginfoKeyData.relations.count));
		box.find(".member-count").html(mw.language.convertNumber(taginfoRelData.all.count));
		box.find(".prevalent-roles").html(mw.language.listToText(roles));

		box.css("display", "block");
	},
	function(err) { displayError(box) });
}

function setPercent(box, classSelector, numKey, denomKey) {
	var num = numKey.count;
	var denom = denomKey.count;

	if(denom === 0) {
		box.find(classSelector).html('—');
	}

	var basePercent = box.find(classSelector).html();
	
	if (typeof basePercent !== 'undefined') {
		basePercent = basePercent.replace(/\$1/g, mw.language.convertNumber(Math.round((num/denom) * 10000) / 100));
		box.find(classSelector).html(basePercent);
	}
}

function statsMap(data) {
	var taginfoData = new Map();

	for (i = 0; i < data.length; i++) {
		taginfoData[data[i].type] = data[i];
	}
	
	return taginfoData;
}

function isTagEmpty(tags) {
	return (tags.nodes.count + tags.ways.count + tags.relations.count) === 0;
}

function displayError(box){
   	box.find(".ti_content").hide();
    box.html(box.data("taginfo-taginfo-error"));
   	box.find(".ti_error").show();
	box.css("display", "block");
}

function populateCountsAndShow(box, taginfoKeyData) {
	$(".taginfo-fallback-link").hide();
	box.find(".all-count").html(mw.language.convertNumber(taginfoKeyData.all.count));
	box.find(".node-count").html(mw.language.convertNumber(taginfoKeyData.nodes.count));
	box.find(".way-count").html(mw.language.convertNumber(taginfoKeyData.ways.count));
	box.find(".rel-count").html(mw.language.convertNumber(taginfoKeyData.relations.count));
	box.css("display", "block");
}