User:Erutuon/scripts/defaultVisibilityToggles.js

Hello, you have come here looking for the meaning of the word User:Erutuon/scripts/defaultVisibilityToggles.js. In DICTIOUS you will not only get to know all the dictionary meanings for the word User:Erutuon/scripts/defaultVisibilityToggles.js, but we will also tell you about its etymology, its characteristics and you will know how to say User:Erutuon/scripts/defaultVisibilityToggles.js in singular and plural. Everything you need to know about the word User:Erutuon/scripts/defaultVisibilityToggles.js you have here. The definition of the word User:Erutuon/scripts/defaultVisibilityToggles.js will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofUser:Erutuon/scripts/defaultVisibilityToggles.js, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.
/* jshint undef: true, esversion: 5 */
/* globals $, jQuery, mw, window, getComputedStyle */

(function defaultVisibilityTogglesIIFE() {
	"use strict";
	
	if (window.noDefaultVisibilityToggles) return;
	
	/* == NavBars == */
	var NavigationBarHide = "hide ▲";
	var NavigationBarShow = "show ▼";
	
	// Check if an element has been activated with a toggle.
	// For convenience, this has the side effect of marking the element as having
	// a toggle, if it is not already marked.
	// Allows the functions to avoid toggleifying elements more than once, which
	// can lead to multiple "show" buttons, for instance.
	// The argument must be an Element, not a jQuery object.
	function checkAndSetToggleified(element) {
		if (element.isToggleified) {
			return true;
		}
		element.isToggleified = true;
	}
	
	function getToggleCategory(element, defaultCategory) {
		if ($(element).find("table").first().is(".translations"))
			return "translations";
		
		var heading = element;
		while ((heading = heading.previousElementSibling)) {
			// tagName is always uppercase:
			// https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName
			var num = heading.tagName.match(/H(\d)/);
			if (num)
				num = Number(num);
			else
				continue;
			if (4 <= num && num <= 6) {
				if (heading.getElementsByTagName("span"))
					heading = heading.getElementsByTagName("span");
				var text = jQuery(heading).text()
					.toLowerCase()
					// jQuery's .text() is inconsistent about whitespace:
					.replace(/^\s+|\s+$/g, "").replace(/\s+/g, " ")
					// remove numbers added by the "Auto-number headings" pref:
					.replace(/^+ ?/, "");
				// Toggle category must be convertible to a valid CSS identifier so
				// that it can be used in an id selector in jQuery in
				// ToggleCategory.prototype.newSidebarToggle
				// in ].
				// Spaces must later be converted to hyphens or underscores.
				// Reference: https://drafts.csswg.org/selectors-4/#id-selectors
				if (/^+$/.test(text))
					return text;
				else
					break;
			} else if (num)
				break;
		}
		
		return defaultCategory;
	}
	
	function createNavToggle(navFrame) {
		if (checkAndSetToggleified(navFrame)) {
			return;
		}
		
		var navHead, navContent;
		for (var i = 0, children = navFrame.childNodes; i < children.length; ++i) {
			var child = children;
			if (child.nodeName === "DIV") {
				var classList = child.classList;
				if (classList.contains("NavHead"))
					navHead = child;
				if (classList.contains("NavContent"))
					navContent = child;
			}
		}
		if (!(navHead && navContent))
			return;
		
		// Step 1, don't react when a subitem is clicked.
		$(navHead).find("a").on("click", function (e) {
			e.stopPropagation();
			e.stopImmediatePropagation();
		});
				
		// Step 2, toggle visibility when bar is clicked.
		// NOTE This function was chosen due to some funny behaviour in Safari.
		var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");
		
		$("<span>").addClass("NavToggle").attr("data-nosnippet", "")
			.append($navToggle)
			.prependTo(navHead);
		
		navHead.style.cursor = "pointer";
		var toggleCategory = $(navFrame).data("toggle-category")
			|| getToggleCategory(navFrame, "other boxes");
		navHead.onclick = window.VisibilityToggles.register(toggleCategory,
			function show() {
				$navToggle.html(NavigationBarHide);
				if (navContent)
					navContent.style.display = "block";
			},
			function hide() {
				$navToggle.html(NavigationBarShow);
				if (navContent)
					navContent.style.display = "none";
			});
	}
	
	function createNavToggleForInflectionTable(it) {
		if (checkAndSetToggleified(it)) {
			return;
		}
		
		// The table caption is the clickable element
		var itCaption = $(it).find("caption").get(0);
		
		// Step 1, don't react when a subitem is clicked.
		$(itCaption).find("a").on("click", function (e) {
			e.stopPropagation();
			e.stopImmediatePropagation();
		});
				
		// Step 2, toggle visibility when bar is clicked.
		// NOTE This function was chosen due to some funny behaviour in Safari.
		var $navToggle = $("<a>").attr("role", "button").attr("tabindex", "0");
		
		$("<span>").addClass("NavToggle").attr("data-nosnippet", "")
			.append($navToggle)
			.prependTo(itCaption);
		
		itCaption.style.cursor = "pointer";
		var toggleCategory = $(it).data("toggle-category")
			|| getToggleCategory(it, "other boxes");
		itCaption.onclick = window.VisibilityToggles.register(toggleCategory,
			function show() {
				$navToggle.html(NavigationBarHide);
				if (it) {
					it.classList.remove("inflection-table-collapsed");
				}
			},
			function hide() {
				$navToggle.html(NavigationBarShow);
				if (it) {
					it.classList.add("inflection-table-collapsed");
				}
			});
			
		// Check to see if we are on a browser that is known to support
		// visibility: collapse, which permits inflection table headings to wrap.
		// WebKit needs to be special-cased, as technically it does support
		// visibility: collapse, but it just implements it as a synonym for
		// visibility: hidden, which is useless. (as of November 2024)
		// Yes, I know User-Agent sniffing is so 2004... but WebKit is the new IE
		if (
			CSS && CSS.supports && CSS.supports("visibility:collapse") &&
			// exclude WebKit/Safari, excepting Blink engines which have a frozen WebKit version number
			(navigator.userAgent.indexOf("AppleWebKit/") === -1 || navigator.userAgent.indexOf("AppleWebKit/537.36") > -1)
		) {
			it.classList.remove("no-vc");
		} else {
			// Strange behaviour occurs when you set the table caption to nowrap
			// The  toggle crashes into the caption text
			// This spacer element prevents that
			$("<span>").addClass("no-vc-spacer").appendTo(itCaption);
		}
	}
	
	/* ==Hidden Quotes== */
	function setupHiddenQuotes(li) {
		if (checkAndSetToggleified(li)) {
			return;
		}
		
		var HQToggle, liComp, dl;
		var HQShow = "quotations ▼";
		var HQHide = "quotations ▲";
		function show() {
			HQToggle.html(HQHide);
			$(li).children("ul").show();
		}
		function hide() {
			HQToggle.html(HQShow);
			$(li).children("ul").hide();
		}
		
		for (var k = 0; k < li.childNodes.length; k++) {
			// Look at each component of the definition.
			liComp = li.childNodes;
			if (liComp.nodeName.toLowerCase() === "dl" && !dl) {
				dl = liComp;
			}
			// If we find a ul or dl, we have quotes or example sentences, and thus need a button.
			if (/^(ul|UL)$/.test(liComp.nodeName)) {
				HQToggle = $("<a>").attr("role", "button").attr("tabindex", "0");
				$(dl || liComp).before($("<span>").addClass("HQToggle").attr("data-nosnippet", "").append(HQToggle).css("margin-left", "5px"));
				HQToggle.on("click", window.VisibilityToggles.register("quotations", show, hide));
				break;
			}
		}
	}
	
	/* == View Switching == */
	
	function viewSwitching(rootElement) {
		if (checkAndSetToggleified(rootElement)) {
			return;
		}
		
		var $rootElement = $(rootElement);
		var showButtonText = $rootElement.data("vs-showtext") || "more ▼";
		var hideButtonText = $rootElement.data("vs-hidetext") || "less ▲";
		
		var toSkip = $rootElement.find(".vsSwitcher").find("*");
		var elemsToHide = $rootElement.find(".vsHide").not(toSkip);
		var elemsToShow = $rootElement.find(".vsShow").not(toSkip);
		
		// Find the element to place the toggle button in.
		var toggleElement = $rootElement.find(".vsToggleElement").not(toSkip).first();
		
		// The toggleElement becomes clickable in its entirety, but
		// we need to prevent this if a contained link is clicked instead.
		toggleElement.find("a").on("click", function (e) {
			e.stopPropagation();
			e.stopImmediatePropagation();
		});
		
		// Add the toggle button.
		var toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
		
		$("<span>").addClass("NavToggle").attr("data-nosnippet", "").append(toggleButton).prependTo(toggleElement);
		
		// Determine the visibility toggle category (for the links in the bar on the left).
		var toggleCategory = $rootElement.data("toggle-category");
		if (!toggleCategory) {
			var classNames = $rootElement.attr("class").split(/\s+/);
			
			for (var i = 0; i < classNames.length; ++i) {
				var className = classNames.split("-");
				
				if (className == "vsToggleCategory") {
					toggleCategory = className;
				}
			}
		}
		
		if (!toggleCategory)
			toggleCategory = "others";
		
		// Register the visibility toggle.
		toggleElement.css("cursor", "pointer");
		toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
			function show() {
				toggleButton.html(hideButtonText);
				elemsToShow.hide();
				elemsToHide.show();
			},
			function hide() {
				toggleButton.html(showButtonText);
				elemsToShow.show();
				elemsToHide.hide();
			}));
	}
	
	/* ==List switching== */
	function enableListSwitchGeneric(rootElement) {
		if (checkAndSetToggleified(rootElement)) {
			return;
		}
		
		var $rootElement = $(rootElement);
		
		// Create a toggle button.
		var $toggleElement = $("<div>").addClass("list-switcher-element");
		var $navToggle = $("<span>").addClass("NavToggle").attr("data-nosnippet", "");
		var $toggleButton = $("<a>").attr("role", "button").attr("tabindex", "0");
		
		// Add the toggle button to the DOM tree.
		$navToggle.append($toggleButton).prependTo($toggleElement);
		$toggleElement.insertAfter($rootElement);
		$toggleElement.show();
		
		// Determine the visibility toggle category (for the links in the bar on the
		// left). It will either be the value of the "data-toggle-category"
		// attribute or will be based on the text of the closest preceding
		// fourth-to-sixth-level header.
		var toggleCategory = $rootElement.data("toggle-category")
			|| getToggleCategory($rootElement, "other lists");
		
		// Determine the text for the $toggleButton.
		var showButtonText = "show more ▼";
		var hideButtonText = "show less ▲";
		
		// Register the visibility toggle.
		$toggleElement.on("click", window.VisibilityToggles.register(toggleCategory,
			function show() {
				$toggleButton.html(hideButtonText);
				if (rootElement) {
					rootElement.classList.remove("list-switcher-collapsed");
				}
			},
			function hide() {
				$toggleButton.html(showButtonText);
				if (rootElement) {
					rootElement.classList.add("list-switcher-collapsed");
				}
			}));
			
		// Register a resize observer to see if we need to keep the
		// show/hide toggle visible
		var termList = rootElement.querySelector(':scope > .term-list');
		if (termList && window.ResizeObserver) {
			var resizeObserver = new ResizeObserver(function(entries) {
				if (entries && entries.contentBoxSize) {
					// Work out what the max-height would be, in pixels
					// As a hack, this value is stored in the CSS `bottom`
					// property, as `max-height` is only in place when
					// the list is collapsed, but we need to do this check
					// even when the list is not collapsed
					var maxHeightPx = parseFloat(getComputedStyle(rootElement).bottom);
					
					// If box height is less than its max height + 20 px, suppress
					// collapsibility. The 20 px buffer prevents the situation where
					// clicking "show more" expands the box by just a few pixels
					if (entries.contentBoxSize.blockSize <= maxHeightPx + 20) {
						$toggleElement.hide();
						if (rootElement.classList.contains("list-switcher-collapsed")) {
							rootElement.classList.remove("list-switcher-collapsed");
							rootElement.classList.add("list-switcher-collapsibility-suppressed");
						}
					} else {
						$toggleElement.show();
						if (rootElement.classList.contains("list-switcher-collapsibility-suppressed")) {
							rootElement.classList.remove("list-switcher-collapsibility-suppressed");
							rootElement.classList.add("list-switcher-collapsed");
						}
					}
				}
			});
			
			resizeObserver.observe(termList);
		}
	}
	
	// based on ], ],
	// ]
	function setupNyms(index, dlTag) {
		// ]
		var relationClasses = [ "synonym", "antonym", "hypernym", "hyponym", "meronym",
								"holonym", "troponym", "comeronym", "coordinate-term",
								"near-synonym", "imperfective", "perfective", "alternative-form" ];
		
		var relations = $(dlTag).find("dd > .nyms").get().filter(
			function(element) {
				return Array.prototype.some.call(element.classList, function (className) {
					if (relationClasses.indexOf(className) !== -1) {
						element.dataset.relationClass = className;
						return true;
					}
				});
			});
		
		function setupToggle(elements, category, visibleByDefault) {
			if (elements.length === 0) return null;
			var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");
			var text = elements.map(function (e) {
				var linkCount = e.querySelectorAll("span").length;
				return e.dataset.relationClass.replace("-", " ") +
						(linkCount > 1 ? "s" : "");
			}).join(", ");
			
			function show() {
				toggler.html(text + "&nbsp;▲");
				$(dlTag).show();
				$(elements).show();
			}
			function hide() {
				toggler.html(text + "&nbsp;▼");
				if ($(dlTag).children().length === elements.length) {
					$(dlTag).hide();
				} else {
					$(elements).hide();
				}
			}
		
			$(dlTag).before($("<span>")
				.addClass("nyms-toggle")
				.attr("data-nosnippet", "")
				.append(toggler)
				.css("margin-left", "5px"));
				
			toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
		}
		
		var synonyms = relations.filter(function (e) {
			return .indexOf(e.dataset.relationClass) !== -1;
		});
		var other = relations.filter(function (e) { return synonyms.indexOf(e) === -1; });
		
		setupToggle(synonyms, "synonyms", true /* show by default  */);
		setupToggle(other, "semantic relations");
	}
	
	
	function setupUsageExampleCollapses(index, dlTag) {
		var usexTags = $(dlTag).find("dd > .h-usage-example").get();
		
		function setupToggle(elements, category, visibleByDefault) {
			if (elements.length === 0) return null;
			var toggler = $("<a>").attr("role", "button").attr("tabindex", "0");
			
			function show() {
				toggler.html(category + "&nbsp;▲");
				$(dlTag).show();
				$(elements).show();
			}
			function hide() {
				toggler.html(category + "&nbsp;▼");
				if ($(dlTag).children().length === elements.length) {
					$(dlTag).hide();
				} else {
					$(elements).hide();
				}
			}
		
			$(dlTag).before($("<span>")
				.addClass("nyms-toggle")
				.append(toggler)
				.css("margin-left", "5px"));
				
			toggler.click(window.VisibilityToggles.register(category, show, hide, visibleByDefault));
		}
		
		var collocations = usexTags.filter(function (e) {
			return $(e).hasClass("collocation");
		});
		var usexes = usexTags.filter(function (e) { return collocations.indexOf(e) === -1; });
		
		setupToggle(usexes, "usage examples", true /* show by default */);
		setupToggle(collocations, "collocations", true /* show by default */);
	}
	
	
	window.createNavToggle = createNavToggle;
	window.setupHiddenQuotes = setupHiddenQuotes;
	window.viewSwitching = viewSwitching;
	window.getToggleCategory = getToggleCategory;
	
	/* == Apply four functions defined above == */
	mw.hook("wikipage.content").add(function($content) {
		// NavToggles
		$(".NavFrame", $content).each(function(){
			createNavToggle(this);
		});
		$(".inflection-table-collapsible", $content).each(function(){
			createNavToggleForInflectionTable(this);
		});
		
		// order nyms -> usexes -> quotes, to match the conventional order in entries
		
		// synonyms and such under definitions
		// if (mw.config.get("wgNamespaceNumber") === 0) {
			$("dl:has(dd > .nyms)", $content).each(setupNyms);
		// }
		
		// usage examples and collocations
		var namespaceNumber = mw.config.get("wgNamespaceNumber");
		if (window.defaultVisibilityTogglesForUsageExamples) {
			if (namespaceNumber === 0) {
				$("ol > li dl:has(dd > .h-usage-example)", $content).each(setupUsageExampleCollapses);
			}
		}
	
		// quotes
		if (namespaceNumber === 0 || namespaceNumber === 100 || namespaceNumber === 118) {
			// First, find all the ordered lists, i.e. all the series of definitions.
			$("ol > li", $content).each(function(){
				setupHiddenQuotes(this);
			});
		}
	
		//view switching
		$(".vsSwitcher", $content).each(function(){
			viewSwitching(this);
		});
	
		// list switching
		$(".list-switcher", $content).each(function () {
			enableListSwitchGeneric(this);
		});
	});
	
	jQuery(mw).on("LivePreviewDone", function (ev, sels) {
		var ols = jQuery(sels.join(",")).find("ol");
		for (var i = 0; i < ols.length; i++) {
			for (var j = 0; j < ols.childNodes.length; j++) {
				var li = ols.childNodes;
				if (li.nodeName.toUpperCase() == "LI") {
					setupHiddenQuotes(li);
				}
			}
		}
	});
})();