User:Erutuon/scripts/Marshallese.js

$( => {	// C: non-glide consonant	// G: glide	// V: vowel	// #: word boundary	// None of these occur in any of the rows.	const specialNotation = {		'C': '[pmtnrlkŋ][ʲˠʷ]?',		'G': '[jɰw]',		'V': '[æɛei]',		'#': '(?:^|\s|$)',	};	const hasSpecialNotation = str => {		return new RegExp('[' + Object.keys(specialNotation).join('') + ']')			.test(str);	};	// Add search box above table of Marshallese transcriptions	// in Module:mh-pronunc.	// The box will accept the symbols C, G, V, #,	// which match a non-glide consonant, glide, vowel, and word boundary.	// If any of the symbols are included,	// the box searches the phonemic IPA transcription.	$('.mh-transcription-list').get.forEach(t => { const getRows = t => { return $(t).find('tr').filter((_, e) => {				return $(e).find('th').length === 0;			}); };		const name1 = 'mh-transcription-list-search'; const $searchLabel = $(' ') .attr('for', name1) .text('Filter table rows:'); const $searchBox = $(' ') .attr({ 'type': 'search', 'id': name1 }) .on('input', function {				const $rows = getRows(t);				const input = $(this).val;				let filterer;				if (hasSpecialNotation(input)) {					const regex = new RegExp( input.replace(/./g, char => specialNotation[char]							? specialNotation[char] + "\\.?"							: char), 'g'					);					filterer = ($row, templateInput, phonemic) => {						return phonemic && regex.test(phonemic);					};				} else {					const lowercaseInput = input.toLowerCase;					filterer = ($row, templateInput) => {						return $row.text.toLowerCase.includes(input)						|| templateInput && templateInput.toLowerCase.includes(input);					};				}				$rows.each((_, row) => { const $row = $(row); $row.css(						'display',						filterer($row, $row.data('templateInput'), $row.data('phonemic')) ? '' : 'none'); });			});		const name2 = 'show-only-differences'; const $checkBoxLabel = $(' ') .attr('for', name2) .text('Show only rows with a difference'); const $checkBox = $(' ') .attr({ 'type': 'checkbox', 'id': name2 }) .on('change', function {				const $rows = getRows(t);				$rows.each((_, row) => { const $row = $(row); $row.css(						'display',						!this.checked || Boolean($row.data('hasDifference')) ? '' : 'none'); });			});		$(t).before($(' ').append($searchLabel, $searchBox), $(' ').append($checkBoxLabel, $checkBox)); });	const forEachTextNode = (func) => {		const key = Symbol;		const apply = node => {			if (!(node instanceof Node)) {				throw new TypeError("Expected Node");			}			for (const child of node.childNodes) {				if (child[key])					continue;				switch (child.nodeType) {					case Node.ELEMENT_NODE: apply(child); break;					case Node.TEXT_NODE: func(child);				}				child[key] = true;			}		};		return apply;	};	const addZwnjBeforeCedilla = forEachTextNode(textNode => { textNode.nodeValue = textNode.nodeValue .normalize('NFD') .replace(/\u200C*\u0327/g, '\u200C\u0327') .normalize('NFC'); });	$(":lang(mh)").get.forEach(addZwnjBeforeCedilla); });