MediaWiki:Gadget-levelThreeSidebar.js

// _______________________________________________________________________________________ // |                                                                                       | // |                    === WARNING: GLOBAL GADGET FILE ===                                | // |                 Changes to this page affect many users. | // |																					  | // |_______________________________________________________________________________________| // // Rolling Release 04.07.2021 var API = "https://www.portalsofphereon.com/w/api.php?"; // pageid: 1634 -> MediaWiki:Level3-Sidebar var request = {action: "parse", pageid: 1634, prop: "wikitext", format: "json"}; var delayPageReady = function (sidebarConf) { if (document.readyState!="loading") createLevelThreeSidebar(sidebarConf); // modern browsers else if (document.addEventListener) document.addEventListener("DOMContentLoaded", createLevelThreeSidebar(sidebarConf)); };

var parseSidebar = function (sidebarConf) { var createLevelOneObj = function(textStr) { return {name: mw.html.escape(textStr.trim), levelTwo: []}; };	var createLevelTwoObj = function(textStr) { var tempArr = textStr.split("|"); var tempObj = {link: "",name: "",tooltip: "",acc: "", levelThree: []}; if (tempArr.length >= 1) { tempObj.link = mw.html.escape(tempArr[0].trim); } if (tempArr.length >= 2) { tempObj.name = mw.html.escape(tempArr[1].trim); } if (tempArr.length >= 3) { tempObj.tooltip = mw.html.escape(tempArr[2].trim); } if (tempArr.length >= 4) { tempObj.acc = mw.html.escape(tempArr[3].trim); } return tempObj; };	var createLevelThreeObj = function(textStr) { var tempArr = textStr.split("|"); var tempObj = {link: "",name: "",tooltip: "",acc: ""}; if (tempArr.length >= 1) { tempObj.link = mw.html.escape(tempArr[0].trim); } if (tempArr.length >= 2) { tempObj.name = mw.html.escape(tempArr[1].trim); } if (tempArr.length >= 3) { tempObj.tooltip = mw.html.escape(tempArr[2].trim); } if (tempArr.length >= 4) { tempObj.acc = mw.html.escape(tempArr[3].trim); } return tempObj; };	var parsed = {levelOne: []}; var levelOne = ""; var levelTwo = ""; var text = sidebarConf.split("\n").reduce( function(result, entry) {		if (entry.trim !== "") {		   result.push(entry);		}		return result;	}, []); for (var i = 0; i < text.length; i++) { var level = text[i].lastIndexOf("*",3); switch (level) { case 0: levelOne = text[i].slice(level + 1).trim; parsed.levelOne.push(createLevelOneObj(levelOne)); levelTwo = ""; break; case 1: if (levelOne !== "") { levelTwo = text[i].slice(level + 1).trim; parsed.levelOne[parsed.levelOne.length - 1] .levelTwo.push(createLevelTwoObj(levelTwo)); }				break; case 2: if (levelOne !== "" && levelTwo !== "") { var levelThree = text[i].slice(level + 1).trim; parsed.levelOne[parsed.levelOne.length - 1] .levelTwo[parsed.levelOne[parsed.levelOne.length - 1].levelTwo.length - 1] .levelThree.push(createLevelThreeObj(levelThree)); }				break; }	}	return parsed; };

var removeSidebarOptions = function { document.getElementById("site-navigation").remove; var elem = document.getElementById("site-tools"); $(elem).off("click"); elem.onclick = closeOpenSidebar; elem = document.getElementById("page-tools"); $(elem).off("click"); elem.onclick = closeOpenSidebar; };

var closeOpenSidebar = function(e) { var $dropdowns = $('#personal, #p-variants-desktop, .sidebar-chunk'); var closeOpen = function { $dropdowns.removeClass('dropdown-active'); };	if ($(this).hasClass('dropdown-active')) { if ($(e.target).closest($('h2, #p-variants-desktop h3')).length > 0) { closeOpen; }   } else { closeOpen; e.stopPropagation; $(this).addClass('dropdown-active'); } };

var openSidebarMobile = function (e) { var toggleTime = 200; if ($(window).width < 851) { $('#site-navigation .sidebar-inner, #menus-cover').fadeToggle(toggleTime); } };

var openSidebar = function(e) { if (e.target.className.indexOf("pop-level-two-sidebar-label-open") !== -1) { e.target.classList.remove("pop-level-two-sidebar-label-open"); e.target.parentElement.nextSibling.classList.remove("pop-level-three-sidebar-container-open"); }	else { e.target.classList.add("pop-level-two-sidebar-label-open"); e.target.parentElement.nextSibling.classList.add("pop-level-three-sidebar-container-open"); } };

var uppercaseFirstLetter = function(str) { return str.charAt(0).toUpperCase + str.slice(1); };

var copyMobileLevel = function(origNode, copyNode) { var nodeClone = copyNode.cloneNode(true); nodeClone.classList.add('pop-desktop-hide'); var arrThird = nodeClone.getElementsByClassName('pop-level-two-sidebar-label'); for (var l = 0; l < arrThird.length; l++) { arrThird[l].onclick = openSidebar; }	origNode.appendChild( nodeClone ); }; //prevent page reflows for performance var fragment = document.createDocumentFragment;

var createLevelOne = function(levelName, lvlNumber) { var divnode1 = document.createElement( 'div' ); divnode1.id = 'site-' + levelName.replace(/ /g,"_").toLowerCase; divnode1.className = 'sidebar-chunk'; divnode1.onclick = closeOpenSidebar; var h2node= document.createElement( 'h2' ); h2node.onclick = openSidebarMobile; if (lvlNumber !== 0) { h2node.className = 'pop-mobile-hide'; } 	var spannode= document.createElement( 'span' ); spannode.appendChild( document.createTextNode(uppercaseFirstLetter(levelName)) ); h2node.appendChild( spannode ); divnode1.appendChild( h2node ); var divnode2 = document.createElement( 'div' ); divnode2.className = 'sidebar-inner'; var divnode3 = document.createElement( 'div' ); divnode3.setAttribute( 'role', 'navigation' ); divnode3.setAttribute( 'aria-labelledby', 'p-' + levelName.replace(/ /g,"_") + '-label' ); divnode3.className = 'mw-portlet'; divnode3.id = 'p-' + levelName.replace(/ /g,"_"); var hnode = document.createElement( 'h3' ); hnode.setAttribute( 'lang', 'en' ); hnode.setAttribute( 'dir', 'ltr' ); hnode.id = 'p-' + levelName.replace(/ /g,"_") + '-label'; hnode.appendChild( document.createTextNode(uppercaseFirstLetter(levelName)) ); divnode3.appendChild(hnode); var divnode4 = document.createElement( 'div' ); divnode4.className = 'mw-portlet-body'; divnode4.appendChild( document.createElement( 'ul' ) ); divnode3.appendChild(divnode4); divnode2.appendChild( divnode3 ); divnode1.appendChild( divnode2 ); fragment.appendChild( divnode1 ); return {lvl: divnode4.getElementsByTagName( 'ul' )[0], dup: divnode3, orig: divnode2}; };

var createLevelTwo = function(prevLevel, levelName, levelLink, levelTool, accKey, hasNextLevel) { var linode = document.createElement( 'li' ); linode.id = 'n-' + levelName.replace(/ /g,"_"); linode.className = 'pop-level-two-sidebar'; var anode = document.createElement( 'a' ); if (levelLink.length >= 1 && levelLink[0] !== "#") { var link = ""; if (levelLink[0] === "/") { link = "/wiki" + levelLink; } else { link = "/wiki/" + levelLink; }		anode.setAttribute( 'href', link ); if (accKey.length === 1) { anode.setAttribute( 'accesskey', accKey ); }	} else { anode.className = 'pop-level-default-cursor'; }	if (levelTool.length >= 1) { anode.setAttribute( 'title', levelTool); }	var spannode = document.createElement( 'span' ); spannode.appendChild( document.createTextNode(uppercaseFirstLetter(levelName)) ); anode.appendChild( spannode ); linode.appendChild( anode ); if (hasNextLevel) { labelnode = document.createElement( 'label' ); labelnode.className = 'pop-level-two-sidebar-label'; labelnode.onclick = openSidebar; linode.className = linode.className + ' pop-level-two-sidebar-menu'; linode.appendChild( labelnode ); divnode = document.createElement( 'div' ); divnode.className = 'pop-level-three-sidebar-container'; prevLevel.appendChild( linode ); prevLevel.appendChild( divnode ); } else { prevLevel.appendChild( linode ); }	return hasNextLevel ? divnode : prevLevel; };

var createLevelThree = function(prevLevel, levelName, levelLink, levelTool, accKey) { var linode = document.createElement( 'li' ); linode.id = 'n-' + levelName.replace(/ /g,"_"); linode.className = 'pop-level-three-sidebar'; var anode = document.createElement( 'a' ); // This should not happen but we add it for consistency if (levelLink.length >= 1 && levelLink[0] !== "#") { var link = ""; if (levelLink[0] === "/") { link = "/wiki" + levelLink; } else { link = "/wiki/" + levelLink; }		anode.setAttribute( 'href', link ); anode.setAttribute( 'href', levelLink ); if (accKey.length === 1) { anode.setAttribute( 'accesskey', accKey ); }	} else { anode.className = 'pop-level-default-cursor'; }	if (levelTool.length >= 1) { anode.setAttribute( 'title', levelTool); }	var spannode = document.createElement( 'span' ); spannode.appendChild( document.createTextNode(uppercaseFirstLetter(levelName)) ); anode.appendChild( spannode ); linode.appendChild( anode ); prevLevel.appendChild( linode ); };

//in case other events get attached after constructing the menu var resetJQueryEvents = function (e) { var list = document.getElementsByClassName("sidebar-chunk"); for (var i=0; i < list.length; i++) { $(list[i]).off("click"); }	var listNav = document.getElementById("site-navigation").children; for (var i=0; i < listNav.length; i++) { if (listNav[i].tagName === "H2") { $(listNav[i]).off("click"); break; }	} }

var showSidebar = function(e) { e.target.classList.add("pop-level-two-sidebar-nav-open"); e.target.lastChild.classList.remove("pop-level-three-sidebar-nav-container-closed"); };

var hideSidebar = function(e) { if (e.target.className.indexOf("pop-level-two-sidebar-nav-open") !== -1) { e.target.classList.remove("pop-level-two-sidebar-nav-open"); e.target.lastChild.classList.add("pop-level-three-sidebar-nav-container-closed"); } };

var createLevelThreeSidebar = function (sidebarConf) { var sidebarLevels = parseSidebar(sidebarConf.parse.wikitext["*"]); var firstLevel = null; for (var i = 0; i < sidebarLevels.levelOne.length; i++) { var levelOne = createLevelOne(sidebarLevels.levelOne[i].name, i); if (i === 0) { firstLevel = levelOne.orig; }   	for (var j = 0; j < sidebarLevels.levelOne[i].levelTwo.length; j++) { var levelTwo = createLevelTwo(levelOne.lvl, sidebarLevels.levelOne[i].levelTwo[j].name,    								 sidebarLevels.levelOne[i].levelTwo[j].link,    								 sidebarLevels.levelOne[i].levelTwo[j].tooltip,    								 sidebarLevels.levelOne[i].levelTwo[j].acc,    								 sidebarLevels.levelOne[i].levelTwo[j].levelThree.length > 0); for (var k = 0; k < sidebarLevels.levelOne[i].levelTwo[j].levelThree.length; k++) { createLevelThree(levelTwo, sidebarLevels.levelOne[i].levelTwo[j].levelThree[k].name,    									   sidebarLevels.levelOne[i].levelTwo[j].levelThree[k].link,    									   sidebarLevels.levelOne[i].levelTwo[j].levelThree[k].tooltip,    									   sidebarLevels.levelOne[i].levelTwo[j].levelThree[k].acc); }   	}    	if (i !== 0) { copyMobileLevel(firstLevel, levelOne.dup); }	}	// Gadget-enableTopNavBar compatibility fix if (mw.user.options.get('gadget-enableTopNavBar',"") === "1") { var menu = fragment.querySelectorAll(".sidebar-chunk"); for (var i = 0; i < menu.length; i++) { var list = menu[i].getElementsByClassName("pop-level-two-sidebar-menu"); var j = 1; while(list.length > 0){ list[0].onclick = null; list[0].onmouseenter = showSidebar; list[0].onmouseleave = hideSidebar; list[0].getElementsByTagName("a")[0].classList.add("pop-level-two-sidebar-nav-a"); list[0].getElementsByTagName("span")[0].classList.add("pop-level-two-sidebar-nav-span"); list[0].getElementsByTagName("label")[0].classList.add("pop-level-two-sidebar-nav-label"); list[0].getElementsByTagName("label")[0].onclick = null; list[0].appendChild(list[0].nextSibling); var threeElem = list[0].getElementsByClassName("pop-level-three-sidebar"); if (j < threeElem.length) { list[0].classList.add("pop-level-two-sidebar-nav-no-stick"); list[0].getElementsByClassName("pop-level-three-sidebar-container")[0] .classList.add("pop-level-three-sidebar-nav-stick-container"); }				list[0].classList.add("pop-level-two-sidebar-nav-li"); list[0].classList.remove("pop-level-two-sidebar-menu"); j++; }			list = menu[i].getElementsByClassName("pop-level-three-sidebar"); while(list.length > 0){ list[0].classList.add("pop-level-three-sidebar-elem"); list[0].classList.remove("pop-level-three-sidebar"); }			list = menu[i].getElementsByClassName("pop-level-three-sidebar-container"); for (var j = 0; j < list.length; j++) { list[j].classList.add("pop-level-three-sidebar-nav-container-closed"); list[j].classList.add("sidebar-inner"); list[j].classList.add("pop-level-three-sidebar-nav-container"); }			/*list = menu[i].getElementsByClassName("pop-level-two-sidebar-nav-li"); for (var j = 0; j < list.length; j++) { if (list[j].offsetHeight > 24) { var threeElem = list[j].getElementsByClassName("pop-level-three-sidebar-elem"); var elem = null; if ((j + 1) < threeElem.length) { elem = threeElem[j]; } else { elem = threeElem[threeElem.length - 1]; }					if (elem.offsetHeight < list[j].offsetHeight) { elem.setAttribute( 'style', 'height: ' + elem.offsetHeight + ';' ); elem.getElementsByTagName("span")[0].setAttribute( 'style', 'line-height: ' + (elem.offsetHeight - 8) + ';' ); }				}			}*/		}	}	var list = document.getElementById("mw-site-navigation"); //remove old removeSidebarOptions; //append new list.insertBefore( fragment, list.lastElementChild ); window.onload = resetJQueryEvents; };

$.getJSON(API, request).done(delayPageReady);