<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-zhDialMap.js</id>
	<title>MediaWiki:Gadget-zhDialMap.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-zhDialMap.js"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-zhDialMap.js&amp;action=history"/>
	<updated>2026-04-09T01:27:22Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-zhDialMap.js&amp;diff=475121&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-zhDialMap.js&amp;diff=475121&amp;oldid=prev"/>
		<updated>2025-11-04T17:54:06Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:54, 4 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-zhDialMap.js&amp;diff=475120&amp;oldid=prev</id>
		<title>wikt&gt;Justinrleung at 22:33, 4 June 2024</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-zhDialMap.js&amp;diff=475120&amp;oldid=prev"/>
		<updated>2024-06-04T22:33:03Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// Chinese dialectal maps, part of gadget zhDialMap&lt;br /&gt;
// designed by [[User:Suzukaze-c]], originally posted at User:Suzukaze-c/zhDialMap.js&lt;br /&gt;
// discussion: [[Module talk:User:Suzukaze-c/zh-dial-map]]&lt;br /&gt;
&lt;br /&gt;
// ideas:&lt;br /&gt;
// * group locations in the popup by lect&lt;br /&gt;
&lt;br /&gt;
&amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
mw.loader.load(&amp;#039;oojs-ui-core&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
var classes = {&lt;br /&gt;
	dotHover: &amp;#039;zh-dial-map__dot--hover&amp;#039;,&lt;br /&gt;
	dotSuperHover: &amp;#039;zh-dial-map__dot--superHover&amp;#039;,&lt;br /&gt;
	legendRowHover: &amp;#039;zh-dial-map__legend-row--hover&amp;#039;,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
var groupZH = {&lt;br /&gt;
	&amp;#039;Mandarin&amp;#039;: &amp;#039;官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Northeastern Mandarin&amp;#039;: &amp;#039;東北官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Jilu Mandarin&amp;#039;: &amp;#039;冀魯官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Jiaoliao Mandarin&amp;#039;: &amp;#039;膠遼官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Central Plains Mandarin&amp;#039;: &amp;#039;中原官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Lanyin Mandarin&amp;#039;: &amp;#039;蘭銀官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Southwestern Mandarin&amp;#039;: &amp;#039;西南官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Jianghuai Mandarin&amp;#039;: &amp;#039;江淮官話&amp;#039;,&lt;br /&gt;
	&amp;#039;Cantonese&amp;#039;: &amp;#039;粵語&amp;#039;,&lt;br /&gt;
	&amp;#039;Hakka&amp;#039;: &amp;#039;客家話&amp;#039;,&lt;br /&gt;
	&amp;#039;Huizhou&amp;#039;: &amp;#039;徽語&amp;#039;,&lt;br /&gt;
	&amp;#039;Gan&amp;#039;: &amp;#039;贛語&amp;#039;,&lt;br /&gt;
	&amp;#039;Jin&amp;#039;: &amp;#039;晉語&amp;#039;,&lt;br /&gt;
	&amp;#039;Jiuxing Yumin&amp;#039;: &amp;#039;九姓漁民方言&amp;#039;,&lt;br /&gt;
	&amp;#039;Northern Min&amp;#039;: &amp;#039;閩北語&amp;#039;,&lt;br /&gt;
	&amp;#039;Eastern Min&amp;#039;: &amp;#039;閩東語&amp;#039;,&lt;br /&gt;
	&amp;#039;Southern Min&amp;#039;: &amp;#039;閩南語&amp;#039;,&lt;br /&gt;
	&amp;#039;Puxian Min&amp;#039;: &amp;#039;莆仙閩語&amp;#039;,&lt;br /&gt;
	&amp;#039;Zhongshan Min&amp;#039;: &amp;#039;中山閩語&amp;#039;,&lt;br /&gt;
	&amp;#039;Central Min&amp;#039;: &amp;#039;閩中語&amp;#039;,&lt;br /&gt;
	&amp;#039;Shaojiang Min&amp;#039;: &amp;#039;邵將閩語&amp;#039;,&lt;br /&gt;
	&amp;#039;Southern Pinghua&amp;#039;: &amp;#039;桂南平話&amp;#039;,&lt;br /&gt;
	&amp;#039;Northern Pinghua&amp;#039;: &amp;#039;桂北平話&amp;#039;,&lt;br /&gt;
	&amp;#039;Shehua&amp;#039;: &amp;#039;畬話&amp;#039;,&lt;br /&gt;
	&amp;#039;Waxiang&amp;#039;: &amp;#039;瓦鄉話&amp;#039;,&lt;br /&gt;
	&amp;#039;Wu&amp;#039;: &amp;#039;吳語&amp;#039;,&lt;br /&gt;
	&amp;#039;Xiang&amp;#039;: &amp;#039;湘語&amp;#039;,&lt;br /&gt;
	&amp;#039;Xiangnan Tuhua&amp;#039;: &amp;#039;湘南土話&amp;#039;,&lt;br /&gt;
	&amp;#039;Yuebei Tuhua&amp;#039;: &amp;#039;粵北土話&amp;#039;,&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
function zh(data) {&lt;br /&gt;
	var element;&lt;br /&gt;
	if (data.type == &amp;#039;lang&amp;#039;) {&lt;br /&gt;
		element = $(&amp;#039;&amp;lt;span&amp;gt;&amp;#039;);&lt;br /&gt;
	} else if (data.type == &amp;#039;link&amp;#039;) {&lt;br /&gt;
		element = $(&amp;#039;&amp;lt;a&amp;gt;&amp;#039;).attr(&amp;#039;href&amp;#039;, &amp;#039;/wiki/&amp;#039; + data.word + &amp;#039;#Chinese&amp;#039;);&lt;br /&gt;
	}&lt;br /&gt;
	element.addClass(&amp;#039;Hani&amp;#039;).attr(&amp;#039;lang&amp;#039;, &amp;#039;zh&amp;#039;).text(data.alt ? data.alt : data.word);&lt;br /&gt;
	if (data.red) element.addClass(&amp;#039;new&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	return element;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function updateGroupSelection() {&lt;br /&gt;
	var groupSelectionStyle = $(&amp;quot;style.zh-dial-map__groupSelectionStyle&amp;quot;);&lt;br /&gt;
	var groupInputChecked = $(&amp;quot;input.zh-dial-map__groupItem:checked&amp;quot;);&lt;br /&gt;
	var checkedGroups = [];&lt;br /&gt;
&lt;br /&gt;
	for (var i = 0; i &amp;lt; groupInputChecked.length; i++) {&lt;br /&gt;
		checkedGroups.push($(groupInputChecked[i]).attr(&amp;#039;data-group&amp;#039;));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (checkedGroups.length === 0) {&lt;br /&gt;
		groupSelectionStyle.text(&amp;#039;&amp;#039;);&lt;br /&gt;
	} else {&lt;br /&gt;
		var checkedGroupsNotSelector = &amp;#039;&amp;#039;;&lt;br /&gt;
		for (var i = 0; i &amp;lt; checkedGroups.length; i++) {&lt;br /&gt;
			checkedGroupsNotSelector += &amp;#039;:not([data-group=&amp;quot;&amp;#039; + checkedGroups[i] + &amp;#039;&amp;quot;])&amp;#039;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		groupSelectionStyle.text(&amp;#039;.zh-dial-map__dot&amp;#039; + checkedGroupsNotSelector + &amp;#039; { display: none; }&amp;#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function main() {&lt;br /&gt;
	var dots;&lt;br /&gt;
	var redLinks = {}; // Record which pages don&amp;#039;t exist (for the &amp;quot;other terms&amp;quot; popup links)&lt;br /&gt;
	var wordLocations = {}; // Initialize object that will contain locations for each dialectal word. Cache instead of regenerating all the time&lt;br /&gt;
	var otherTerms = [];&lt;br /&gt;
	var activePopup;&lt;br /&gt;
	var popups = [];&lt;br /&gt;
&lt;br /&gt;
	var mapImg = $(&amp;#039;.zh-dial-map__map img&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
	// take original pixel dimensions from the image&lt;br /&gt;
	// and give them to the image and the container holding the image&lt;br /&gt;
	$(&amp;#039;.zh-dial-map__map, .zh-dial-map__map img&amp;#039;)&lt;br /&gt;
		.css(&amp;#039;width&amp;#039;, mapImg.attr(&amp;#039;width&amp;#039;) + &amp;#039;em&amp;#039;)&lt;br /&gt;
		.css(&amp;#039;height&amp;#039;, mapImg.attr(&amp;#039;height&amp;#039;) + &amp;#039;em&amp;#039;)&lt;br /&gt;
	;&lt;br /&gt;
&lt;br /&gt;
	// &amp;lt;s&amp;gt;change image source to svg&amp;lt;/s&amp;gt;&lt;br /&gt;
	// and remove dimension attributes&lt;br /&gt;
	mapImg&lt;br /&gt;
		.removeAttr(&amp;#039;width&amp;#039;)&lt;br /&gt;
		.removeAttr(&amp;#039;height&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
		.attr(&amp;#039;src&amp;#039;, function(index, attr) {&lt;br /&gt;
			return attr.replace(&amp;#039;1200px&amp;#039;, &amp;#039;2400px&amp;#039;);&lt;br /&gt;
		})&lt;br /&gt;
		.removeAttr(&amp;#039;srcset&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
		/*&lt;br /&gt;
		.attr(&amp;#039;src&amp;#039;, function(index, attr) {&lt;br /&gt;
			return attr.replace(&amp;#039;thumb/&amp;#039;, &amp;#039;&amp;#039;).replace(/(svg).+/, &amp;#039;$1&amp;#039;)&lt;br /&gt;
		})&lt;br /&gt;
		.removeAttr(&amp;#039;srcset&amp;#039;)&lt;br /&gt;
		*/&lt;br /&gt;
	;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	var inputContainer = $(&amp;#039;&amp;lt;span&amp;gt;&amp;#039;);&lt;br /&gt;
	inputContainer&lt;br /&gt;
		.addClass(&amp;#039;zh-dial-map__inputContainer&amp;#039;)&lt;br /&gt;
		.prependTo(&amp;#039;.zh-dial-map__container&amp;#039;)&lt;br /&gt;
	;&lt;br /&gt;
&lt;br /&gt;
	var zoomContainer = $(&amp;#039;&amp;lt;span&amp;gt;&amp;#039;);&lt;br /&gt;
	var zoomController = $(&amp;#039;&amp;lt;input&amp;gt;&amp;#039;);&lt;br /&gt;
	zoomContainer&lt;br /&gt;
		.addClass(&amp;#039;zh-dial-map__zoomContainer&amp;#039;)&lt;br /&gt;
		.appendTo(&amp;#039;.zh-dial-map__inputContainer&amp;#039;)&lt;br /&gt;
	;&lt;br /&gt;
	zoomController&lt;br /&gt;
		.addClass(&amp;#039;zh-dial-map__zoomController&amp;#039;)&lt;br /&gt;
		.attr(&amp;#039;type&amp;#039;, &amp;#039;range&amp;#039;)&lt;br /&gt;
		.attr(&amp;#039;min&amp;#039;, 0.1)&lt;br /&gt;
		.attr(&amp;#039;max&amp;#039;, 4)&lt;br /&gt;
		.attr(&amp;#039;step&amp;#039;, 0.1)&lt;br /&gt;
		.val(1) // default zoom at 100%&lt;br /&gt;
		.on(&amp;quot;change&amp;quot;, function() {&lt;br /&gt;
			//console.log($(this).val());&lt;br /&gt;
			$(&amp;#039;.zh-dial-map__map&amp;#039;).css(&amp;quot;font-size&amp;quot;, $(this).val() + &amp;quot;px&amp;quot;);&lt;br /&gt;
		})&lt;br /&gt;
		.appendTo(&amp;#039;.zh-dial-map__zoomContainer&amp;#039;)&lt;br /&gt;
	;&lt;br /&gt;
&lt;br /&gt;
	var groupSelectionContainer = $(&amp;#039;&amp;lt;span&amp;gt;&amp;#039;);&lt;br /&gt;
	var groupSelectionStyle = $(&amp;quot;&amp;lt;style&amp;gt;&amp;quot;);&lt;br /&gt;
	groupSelectionContainer&lt;br /&gt;
		.addClass(&amp;#039;zh-dial-map__groupSelectionContainer&amp;#039;)&lt;br /&gt;
		.appendTo(&amp;#039;.zh-dial-map__inputContainer&amp;#039;)&lt;br /&gt;
	;&lt;br /&gt;
	groupSelectionStyle&lt;br /&gt;
		.addClass(&amp;#039;zh-dial-map__groupSelectionStyle&amp;#039;)&lt;br /&gt;
		.appendTo(&amp;#039;head&amp;#039;)&lt;br /&gt;
	;&lt;br /&gt;
	for (var group in groupZH) {&lt;br /&gt;
		var groupItem = $(&amp;#039;&amp;lt;input&amp;gt;&amp;#039;);&lt;br /&gt;
		var groupLabel = $(&amp;#039;&amp;lt;label&amp;gt;&amp;#039;);&lt;br /&gt;
		var id = &amp;#039;zh-dial-map__groupItem--&amp;#039; + group.replace(&amp;#039; &amp;#039;, &amp;#039;-&amp;#039;);&lt;br /&gt;
		groupItem&lt;br /&gt;
			.attr(&amp;#039;type&amp;#039;, &amp;#039;checkbox&amp;#039;)&lt;br /&gt;
			.addClass(&amp;#039;zh-dial-map__groupItem&amp;#039;)&lt;br /&gt;
			.attr(&amp;#039;id&amp;#039;, id)&lt;br /&gt;
			.attr(&amp;#039;name&amp;#039;, &amp;#039;zh-dial-map__groupItem&amp;#039;)&lt;br /&gt;
			.attr(&amp;#039;data-group&amp;#039;, group)&lt;br /&gt;
			.on(&amp;quot;change&amp;quot;, updateGroupSelection)&lt;br /&gt;
			.appendTo(&amp;#039;.zh-dial-map__groupSelectionContainer&amp;#039;)&lt;br /&gt;
		;&lt;br /&gt;
		groupLabel&lt;br /&gt;
			.attr(&amp;#039;for&amp;#039;, id)&lt;br /&gt;
			.text(group)&lt;br /&gt;
			.appendTo(&amp;#039;.zh-dial-map__groupSelectionContainer&amp;#039;)&lt;br /&gt;
		;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	$(&amp;#039;.zh-dial-map__legend-row&amp;#039;).on(&amp;quot;touchstart mouseenter&amp;quot;,&lt;br /&gt;
		function() {&lt;br /&gt;
			var word = $(this).data(&amp;#039;word&amp;#039;); // Get the dialectal word for the active legend row&lt;br /&gt;
			var isOther = (word == &amp;#039;other&amp;#039;); // Is our row the &amp;quot;other terms&amp;quot; row?&lt;br /&gt;
&lt;br /&gt;
			if (isOther) {&lt;br /&gt;
				dots = $(&amp;#039;.zh-dial-map__dot-other&amp;#039;); // Get all grey dots&lt;br /&gt;
			} else {&lt;br /&gt;
				dots = $(&amp;#039;.zh-dial-map__dot[data-word=&amp;#039; + word + &amp;#039;]&amp;#039;); // Get every dot corresponding to our word&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			$(this).addClass(classes.legendRowHover); // Add hovered class to the legend row&lt;br /&gt;
			dots.addClass(classes.dotHover); // Add hovered class to every corresponding dot&lt;br /&gt;
&lt;br /&gt;
			if (! wordLocations[word]) {&lt;br /&gt;
				wordLocations[word] = [];&lt;br /&gt;
&lt;br /&gt;
				dots.each(&lt;br /&gt;
					function(index) {&lt;br /&gt;
						var location = [$(this).data(&amp;#039;location-en&amp;#039;), $(this).data(&amp;#039;location-zh&amp;#039;), $(this).data(&amp;#039;group&amp;#039;)]; // Get location of dot&lt;br /&gt;
						wordLocations[word].push(location);&lt;br /&gt;
&lt;br /&gt;
						if (isOther) {&lt;br /&gt;
							var otherWord = $(this).data(&amp;#039;word&amp;#039;); // For &amp;quot;other terms&amp;quot;, collect the terms too&lt;br /&gt;
							otherTerms.push(otherWord);&lt;br /&gt;
&lt;br /&gt;
							if (! redLinks[otherWord]) redLinks[otherWord] = $(this).parent().hasClass(&amp;#039;new&amp;#039;);&lt;br /&gt;
							//console.log(otherWord, redLinks[otherWord]);&lt;br /&gt;
						}&lt;br /&gt;
					}&lt;br /&gt;
				);&lt;br /&gt;
				//console.log(word, wordLocations[word]);&lt;br /&gt;
				//if (isOther) { console.log(otherTerms) };&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			if (! popups[word]) {&lt;br /&gt;
				var locationsList = $(&amp;#039;&amp;lt;ul&amp;gt;&amp;#039;).addClass(&amp;#039;zh-dial-map__legend-row-locations&amp;#039;); // Popup contents&lt;br /&gt;
&lt;br /&gt;
				$.each(wordLocations[word], function(index, value) { // Do stuff related to each location recorded for this word&lt;br /&gt;
					if (isOther) word = otherTerms[index];&lt;br /&gt;
&lt;br /&gt;
					var locationEn = value[0], locationZh = value[1], group = value[2];&lt;br /&gt;
					var listItem = $(&amp;#039;&amp;lt;li&amp;gt;&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
					listItem.append(zh({type: &amp;#039;lang&amp;#039;, word: locationZh + groupZH[group]})).append(&amp;#039; (&amp;#039; + locationEn + &amp;#039; &amp;#039; + group + &amp;#039;)&amp;#039;); // FIXME: this feels really hacky&lt;br /&gt;
					if (isOther) listItem.append(&amp;#039;: &amp;#039;).append(zh({type: &amp;#039;link&amp;#039;, word: otherTerms[index], red: redLinks[word]})); // FIXME: this too&lt;br /&gt;
&lt;br /&gt;
					var locationDot = $(&amp;#039;[data-location-zh=&amp;#039; + locationZh + &amp;#039;][data-word=&amp;#039; + word + &amp;#039;]&amp;#039;); // Find the dot for this word at this location&lt;br /&gt;
					//console.log(&amp;#039;[data-location-zh=&amp;#039; + locationZh + &amp;#039;][data-word=&amp;#039; + word + &amp;#039;]&amp;#039;, locationDot);&lt;br /&gt;
					listItem.hover(&lt;br /&gt;
						function() {&lt;br /&gt;
							locationDot.addClass(classes.dotSuperHover);&lt;br /&gt;
						},&lt;br /&gt;
						function() {&lt;br /&gt;
							locationDot.removeClass(classes.dotSuperHover);&lt;br /&gt;
						}&lt;br /&gt;
					);&lt;br /&gt;
&lt;br /&gt;
					listItem.appendTo(locationsList);&lt;br /&gt;
				});&lt;br /&gt;
&lt;br /&gt;
				popups[word] = new OO.ui.PopupWidget({&lt;br /&gt;
					$content: locationsList,&lt;br /&gt;
					$container: $(&amp;#039;.zh-dial-map__container&amp;#039;),&lt;br /&gt;
				});&lt;br /&gt;
&lt;br /&gt;
				$(this).append(popups[word].$element); // Add cool popup to DOM&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			popups[word].toggle(true); // Make the popup visible&lt;br /&gt;
			activePopup = popups[word];&lt;br /&gt;
		}&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$(&amp;#039;.zh-dial-map__legend-row&amp;#039;).on(&amp;quot;touchend mouseleave&amp;quot;,&lt;br /&gt;
		function() {&lt;br /&gt;
			$(this).removeClass(classes.legendRowHover); // Remove hovered class from legend row&lt;br /&gt;
			dots.removeClass(classes.dotHover); // Remove hovered class from every dot that corresponds to that word&lt;br /&gt;
			activePopup.toggle(false); // Hide popup&lt;br /&gt;
		}&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if ($(&amp;#039;.zh-dial-map__map&amp;#039;).length) {&lt;br /&gt;
	main();&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>wikt&gt;Justinrleung</name></author>
	</entry>
</feed>