User:Useigor/Gadget-Ledokol.js

//en LEDOKOL: Little-Effort Dictionaries Overview by Known word for One Language //ru ЛЕДОКОЛ: ЛЕгкоДОступный Каталог Открытых Лексиконов

var langcodes;     // "name":"code" var langnames = {}; // "code":"name" (reversed langcodes)

// https://www.mediawiki.org/wiki/API:Get_the_contents_of_a_page // /w/api.php?action=parse&page=Module:languages/canonical names.json&prop=wikitext&formatversion=2 function updateStorageLangcodes( present ) { return new mw.Api.get({		"action": "parse",		"page": "Module:languages/canonical names.json",		"prop": "wikitext",		"formatversion": 2, // omitted? data.parse.wikitext["*"]		"format": "json"	}).done( function(data) {		localStorage["languages/canonical names/date"] = present || Math.floor( Date.now / 8.64e7 ); // avoid storing over-specific timestamp		localStorage["languages/canonical names/json"] = data.parse.wikitext.replaceAll(/\n */g,"").replaceAll(/" *: *"/g,'":"');	}); }

function displayHeaderLangcodes { langcodes = JSON.parse( localStorage["languages/canonical names/json"] || null ); if ( !langcodes ) { delete localStorage["languages/canonical names/date"]; console.warn('Local storage: "languages/canonical names/json" is absent'); return; }	Object.entries(langcodes).forEach( function(entry) {		langnames[ entry[1] ] = entry[0];	}); document.querySelectorAll(".mw-parser-output > h2 .mw-headline").forEach( function(hl) {		var name = hl.innerText;		var code = langcodes[name] || "--";		var a = document.createElement("a");		a.href = "/wiki/Category:"+ name + (name.includes("Language")? "" : "_language"); // Sign Language [language]		a.innerText = "("+ code +")";		hl.after( a );		a.before( document.createTextNode(" ") ); // a.style["margin-left"] = "1ch"	}); }

var ledokolRef = document.createElement("span"); // preserve em ledokolRef.style["position"] = "absolute"; ledokolRef.style["padding-top"] = "0.20em"; ledokolRef.style["margin-top"] = "1.20em";

var ledokolRef2 = ledokolRef.appendChild( document.createElement("code") ); // reset inconsistent properties ledokolRef2.style["font-size"] = "0.875rem"; ledokolRef2.style["font-family"] = "sans-serif"; ledokolRef2.style["font-style"] = "normal"; ledokolRef2.style["font-weight"] = "normal"; ledokolRef2.appendChild( document.createElement("a") ).target = "_blank"; ledokolRef2.append( document.createTextNode(" ") ); ledokolRef2.appendChild( document.createElement("a") ).target = "_blank"; ledokolRef2.children[0].innerText = "References"; ledokolRef2.children[1].innerText = "(Category)";

function toggleLedokolRef( ev ) { if ( !langcodes ) return;

if ( ev.type == "mouseenter" ) { var code = "0code"; var name = "0lang"; var word = "0word"; if ( this.nodeName == "A" ) { // a			code = this.parentNode["lang"]; if ( this.classList.contains("new") ) { word = this.search.replace(/.*title=([^&]*).*/g, "$1"); } else if ( this.pathname.search("^/wiki/") != -1 ) { word = this.pathname; if ( !langnames[code] ) name = this.hash.replace("#",""); }			name = langnames[code] || name; } else { // h2 .mw-headline word = location.pathname; name = this.innerText; code = langcodes && langcodes[name] || code; }			word = word.replace(/.*\//g, ""); var linkName = name.replaceAll(" ","_"); ledokolRef2.firstElementChild.href = "/wiki/Appendix:"+ name +"_bibliography#"+ word; ledokolRef2.lastElementChild.href = "/wiki/Category:"+ name +"_reference_templates"; ledokolRef.style["display"] = ""; this.before( ledokolRef ); } else if ( ev.type == "mouseleave" ) { // a.parentNode, h2		ledokolRef.style["display"] = "none"; } }

function ledokolEncode( input, href ) { if ( !input ) return;

if ( href.includes("FFFFFF") ) { return href.replace( "FFFFFF", input ); } else if ( href.includes("EEEEEE") ) { return href.replace( "EEEEEE", input.replaceAll(" ","+") ); } }

function loadLedokol { if ( mw.config.get("wgArticleId") == 0 ) // wgWMEPageLength, wgRevisionId return; var ns = mw.config.get("wgNamespaceNumber"); // wgNamespaceIds if ( ns == 100 && mw.config.get("wgTitle").search("bibliography$") != -1 ) { // 100:"appendix" var search = document.querySelector("#mw-content-text .mw-parser-output").insertAdjacentElement( "beforebegin", document.createElement("p") ); search.style["position"] = "fixed"; search.style["left"] = "0"; search.style["bottom"] = "0"; search.style["width"] = "100%"; search.style["text-align"] = "center"; var input = search.appendChild( document.createElement("input") ); input.placeholder = 'Change links with query="FFFFFF"'; input.title = "FFFFFF (space=space), EEEEEE (space=+)" var button = search.appendChild( document.createElement("button") ); button.innerText = "open"; if ( location.hash ) { input.value = decodeURI(location.hash).replace("#","").replaceAll("_"," "); }		var linkCount = 0; document.querySelectorAll("#mw-content-text a").forEach( function(a) {			if ( a.href.search("(FFFFFF|EEEEEE)") != -1 ) {				linkCount++;				a.dataset["href"] = a.href;				a.href = ledokolEncode( input.value, a.dataset["href"] );				a.style["background-color"] = "rgba(255,127,0,0.20)";			}		}); button.innerText += " "+ linkCount;

input.addEventListener("input", function {			location.hash = "#"+ input.value;			document.querySelectorAll("#mw-content-text a[data-href]").forEach( function(a) { ledokolEncode( input.value, a.dataset["href"] ); a.href = ledokolEncode( input.value, a.dataset["href"] ); });		});		button.addEventListener("click", function {			document.querySelectorAll("#mw-content-text a[data-href]").forEach( function(a) { open( a.href, "_blank" ); // _parent, _top });		});	} else if ( ns == 0 || ns == 118 ) { // 0:"" || 118:"reconstuction" var past = JSON.parse( localStorage["languages/canonical names/date"] || null ); var present = Math.floor( Date.now / 8.64e7 ); if ( !past || present-past > 7 ) { $.when( updateStorageLangcodes(present) ).done( function {				displayHeaderLangcodes;			}); } else { displayHeaderLangcodes; }		document.querySelectorAll("#mw-content-text a").forEach( function(a) {			if ( a.parentNode["lang"] && a.host == location.host && a.innerText ) { // lang-marked && internal && not empty				a.addEventListener("mouseenter", toggleLedokolRef);				a.parentNode.addEventListener("mouseleave", toggleLedokolRef);			}		}); document.querySelectorAll("#mw-content-text h2 .mw-headline").forEach( function(h) {			h.addEventListener("mouseenter", toggleLedokolRef);			h.parentNode.addEventListener("mouseleave", toggleLedokolRef);		}); } }

document.addEventListener("DOMContentLoaded", loadLedokol);