User:Catonif/Gadget-PagePreviews.js

Hello, you have come here looking for the meaning of the word User:Catonif/Gadget-PagePreviews.js. In DICTIOUS you will not only get to know all the dictionary meanings for the word User:Catonif/Gadget-PagePreviews.js, but we will also tell you about its etymology, its characteristics and you will know how to say User:Catonif/Gadget-PagePreviews.js in singular and plural. Everything you need to know about the word User:Catonif/Gadget-PagePreviews.js you have here. The definition of the word User:Catonif/Gadget-PagePreviews.js will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofUser:Catonif/Gadget-PagePreviews.js, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.
// Page Previews for Wiktionary, by ]
// <nowiki>

// Generated using the following Python code:
// import requests
// import re
// data = requests.get("https://en.wikipedia.org/w/api.php?action=query&meta=siteinfo&siprop=interwikimap&formatversion=2&format=json").json()
// prefix_data = {item: (re.findall("https://(+).wikipedia.orghttps://dictious.com/en/\$1$", item) or ) for item in data}
// prefix_data = 0
// prefix_data_array = 
// print(f"const INTERWIKI_PREFIXES = new Map(" + str(prefix_data_array).replace(" ", "").replace("'", "\"") + ");")
const INTERWIKI_PREFIXES = new Map(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]);

// From https://meta.wikimedia.orghttps://dictious.com/en/List_of_Wikipedias#All_Wikipedias_ordered_by_number_of_articles.
// Generated using the following JavaScript code:
// let langList = .map(row => {
//     let lang = row.children.textContent;
//     let code = row.children.textContent;
//     return ``
// }).join(",");
// console.log(`const WP_LANGUAGES = new Map();`);
const WP_LANGUAGES = new Map(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]);

const animationSpeed = 0.2; // seconds
mw.util.addCSS(`
	.page-preview ol {
		margin: 0 0.5em 0 1.5em;
		padding: 0;
	}
	.page-preview dl {
		margin-bottom: 0;
	}
	.page-preview p {
		margin: 0;
	}

	/* popupContainer has the opacity animation, while popup gets translated. */
	.popup-fade-in-up, .popup-fade-in-down {
		animation: popup-fade-in ${animationSpeed}s ease forwards;
	}
	.popup-fade-out-up, .popup-fade-out-down {
		animation: popup-fade-out ${animationSpeed}s ease forwards;
	}
	.popup-fade-in-up > div {
		animation: popup-move-in-up ${animationSpeed}s ease forwards;
	}
	.popup-fade-in-down > div {
		animation: popup-move-in-down ${animationSpeed}s ease forwards;
	}
	.popup-fade-out-up > div {
		animation: popup-move-out-up ${animationSpeed}s ease forwards;
	}
	.popup-fade-out-down > div {
		animation: popup-move-out-down ${animationSpeed}s ease forwards;
	}

	@keyframes popup-move-in-up {
		0% {
			transform: translate(0, 20px);
		}
	}
	@keyframes popup-move-in-down {
		0% {
			transform: translate(0, -20px);
		}
	}
	@keyframes popup-move-out-up {
		100% {
			transform: translate(0, -20px);
		}
	}
	@keyframes popup-move-out-down {
		100% {
			transform: translate(0, 20px);
		}
	}
	@keyframes popup-fade-out {
		100% {
			opacity: 0;
		}
	}
	@keyframes popup-fade-in {
		0% {
			opacity: 0;
		}
	}

	.ring-loader {
		margin: auto;
		width: 24px;
		height: 24px;
		border-radius: 50%;
		border-top: 5px solid var(--wikt-palette-black, #202122);
		border-bottom: 5px solid var(--wikt-palette-black, #202122);
		border-left: 5px solid transparent;
		border-right: 5px solid transparent;
		animation: spin 1.2s linear infinite;
	}
	@keyframes spin {
		100% {
			transform: rotate(360deg);
		}
	}

	.preview-headerlink, .preview-headerlink:visited {
		color: inherit;
		font-weight: bold;
	}

	/* Hack: get the speaker icon on Wikipedia articles without having to load Phonos. */
	.ext-phonos .oo-ui-buttonElement-button:after {
		content: "🔊";
	}
	.ext-phonos * {
		display: inline !important;
		padding: 0 !important;
		margin: 0 !important;
	}
`);

const definitionIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M15 2a7.65 7.65 0 00-5 2 7.65 7.65 0 00-5-2H1v15h4a7.65 7.65 0 015 2 7.65 7.65 0 015-2h4V2zm2.5 13.5H14a4.38 4.38 0 00-3 1V5s1-1.5 4-1.5h2.5z"></path></g></svg>`;
const glossaryIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M12.43 14.34A5 5 0 0110 15a5 5 0 113.95-2L17 16.09V3a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 001.45-.63z"></path><circle cx="10" cy="10" r="3"></circle></g></svg>`;
const articleIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M5 1a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 002-2V3a2 2 0 00-2-2zm0 3h5v1H5zm0 2h5v1H5zm0 2h5v1H5zm10 7H5v-1h10zm0-2H5v-1h10zm0-2H5v-1h10zm0-2h-4V4h4z"></path></g></svg>`;
const bibliographyIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true" fill="currentColor"><g><path d="M3 2h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H3c0 0 .5-.5.5-1V3c0-.5-.5-1-.5-1zM4 6h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H4c0 0 .5-.5.5-1V7c0-.5-.5-1-.5-1zM3 10h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H3c0 0 .5-.5.5-1v-1c0-.5-.5-1-.5-1zM4 14h12c.5 0 1 .5 1 1v1c0 .5-.5 1-1 1H4c0 0 .5-.5.5-1v-1c0-.5-.5-1-.5-1z"></path></g></svg>`;

const loader = document.createElement("div");
loader.className = "ring-loader";

const popupContainer = document.createElement("div");
const popup = document.createElement("div");
const popupContent = document.createElement("div");

popupContainer.style = `display: none; position: absolute; filter: drop-shadow(0px 30px 30px rgba(0, 0, 0, 0.15)) drop-shadow(0px 0px 0.75px var(--wikt-palette-dullblue, #49555f)); z-index: 801`;
popupContainer.className = "page-preview";
popup.style = "box-sizing: border-box; height: 100%; background: var(--wikt-palette-white, #ffffff)";
popupContent.style = "display: flex; flex-direction: column; border-radius: 2px; box-sizing: border-box; color: var(--wikt-palette-black, #202122); overflow: auto; height: 100%; overflow-wrap: break-word; scrollbar-width: thin";

document.body.append(popupContainer);
popupContainer.append(popup);
popup.append(popupContent);

let popupTimer;
let openLink;
let mouseX, mouseY;

let API_controller = new AbortController();

function closePopup() {
	if (!openLink) return;
	openLink.dispatchEvent(new Event("pagePreviewClosed"));
	openLink = null;

	API_controller.abort();
	API_controller = new AbortController();

	if (popupContainer.classList.contains("popup-fade-in-up")) {
		popupContainer.classList.remove("popup-fade-in-up");
		popupContainer.classList.add("popup-fade-out-down");
	} else {
		popupContainer.classList.remove("popup-fade-in-down");
		popupContainer.classList.add("popup-fade-out-up");
	}

	// After the animation has completed, reset the popup to its initial state.
	setTimeout(() => {
		popupContainer.style.display = "none";
		popupContainer.classList.remove("popup-fade-out-down", "popup-fade-out-up");
	}, animationSpeed * 1000);
}

popup.addEventListener("pointerenter", () => {
	clearTimeout(popupTimer);
});

popup.addEventListener("pointerleave", () => {
	clearTimeout(popupTimer);
	popupTimer = setTimeout(closePopup, 300);
});

function processLink(link) {
	let linkTitle = decodeURIComponent(link.pathname.split("https://dictious.com/en/"));
	let titlePrefix = linkTitle.includes(":") ? linkTitle.toLowerCase().split(":") : "";
	let resolvedTitle = linkTitle;
	let API_domain = link.origin;
	let linkAnchor = decodeURIComponent(link.hash.slice(1) || "");
	let isWPlink = link.href.match(/^https:\/\/+.wikipedia.org\/wiki\//);
	let isPreviewLink = Boolean(link.closest(".page-preview"));

	// Start with various checks to determine whether a link should be processed.
	if (link.matches(`nav a, .cancelLink a, .mw-widget-titleOptionWidget a, .new, .preview-headerlink, .external, `))
		return;
	let hasLowercaseAnchor = linkTitle === "Appendix:Glossary" || linkTitle.startsWith("Appendix:Bibliography/")
	if ((hasLowercaseAnchor && !linkAnchor) || (!hasLowercaseAnchor && !isWPlink && /^/.test(linkAnchor)))
		return;

	if (link.href.startsWith("https://en.wiktionary.orghttps://dictious.com/en/")) {
		// Filter out all interwiki prefixes.
		if (INTERWIKI_PREFIXES.has(titlePrefix))
			return;

		let titleObject = new mw.Title(linkTitle);
		if (titleObject.namespace === 0) { // Mainspace
			if (titleObject.title.endsWith("/translations"))
				return;
		} else if (titleObject.namespace === 100) { // Appendix space
			let appendixWithSlash = ;
			let appendixNoSlash = ;
			if (!appendixWithSlash.some(lang => titleObject.title.startsWith(lang + "/")) && !appendixNoSlash.includes(titleObject.title))
				return;
		} else if (titleObject.namespace !== 118) { // Reconstruction space
			return;
		}
	} else if (isWPlink) {
		// Filter out invalid interwiki prefixes.
		if (INTERWIKI_PREFIXES.get(titlePrefix) === 0)
			return;

		// Get the resolved title if it's a language interwiki.
		if (INTERWIKI_PREFIXES.has(titlePrefix)) {
			API_domain = "https://" + INTERWIKI_PREFIXES.get(titlePrefix) + ".wikipedia.org";
			resolvedTitle = linkTitle.substring(linkTitle.indexOf(":") + 1);
			// If the resolved title contains another interwiki, return.
			let resolvedTitlePrefix = resolvedTitle.includes(":") ? resolvedTitle.toLowerCase().split(":") : ""; // same as linkPrefix
			if (INTERWIKI_PREFIXES.has(resolvedTitlePrefix))
				return;
		}
	} else {
		return;
	}

	link.addEventListener("pointerover", event => {
		clearTimeout(popupTimer);

		// Ignore links which are already open.
		if (link === openLink)
			return;

		if (!isPreviewLink)
			closePopup();

		// Track mouse movements.
		mouseX = event.clientX;
		mouseY = event.clientY;

		// Fetch popup text immediately on hover to reduce delay.
		let responsePromise = fetch(API_domain + "/api/rest_v1/page/html/" + encodeURIComponent(resolvedTitle), {
			headers: {"Api-User-Agent": "Gadget developed by ]"},
			signal: API_controller.signal
		}).then(r => r.text()).catch(() => { /* fetch was aborted */ });

		popupTimer = setTimeout(() => {
			popupContainer.style.display = "";
			popupContent.innerHTML = "";
			popupContent.append(loader);
			popupContent.style.padding = "14px 16px 8px";

			// Disable link hovering until animation has completed.
			popupContent.style.pointerEvents = "none";
			setTimeout(() => popupContent.style.pointerEvents = "", animationSpeed * 1000);

			// Adapt the popup for large, standard, and small size preference in Vector 2022.
			let sizeSetting = 0;
			if (document.documentElement.matches(".vector-feature-custom-font-size-clientpref-1"))
				sizeSetting = 1;
			else if (document.documentElement.matches(".vector-feature-custom-font-size-clientpref-2"))
				sizeSetting = 2;

			let width = ;
			let height = ;
			let triangleSize = ;

			popupContainer.style.fontSize = ;
			popupContainer.style.lineHeight = ;
			popupContainer.style.width = width + "px";
			popupContainer.style.height = height + "px";

			if (isPreviewLink) {
				// Trigger fade-in-down animation.
				popupContainer.classList.remove("popup-fade-in-up", "popup-fade-in-down");
				void popupContainer.offsetLeft; // force reflow
				popupContainer.classList.add("popup-fade-in-down");
			} else {
				openLink = link;
				openLink.dispatchEvent(new Event("pagePreviewOpened"));

				// Get list of rects (lines) of the target element, then find the one whose midpoint is closest to mouseY.
				// This ensures that the code can correctly handle multi-line links.
				let linkBlock = Array.from(event.target.getClientRects()).reduce((prev, next) => Math.abs((next.top + next.bottom) / 2 - mouseY) < Math.abs((prev.top + prev.bottom) / 2 - mouseY) ? next : prev);

				// Horizontal position. Choose left or right depending on the side of the screen the mouse is in.
				let leftPosition = mouseX - 30;
				if (mouseX > document.documentElement.clientWidth / 2)
					leftPosition = mouseX - width + 30;
				// Ensure that the popup is at least 5px away from the side of the screen.
				leftPosition = Math.max(5, Math.min(leftPosition, document.documentElement.clientWidth - width - 5));
				popupContainer.style.left = leftPosition + document.documentElement.scrollLeft + "px";

				// Vertical position. Prioritize fade-in-down unless there would be less than 10px of room above.
				if (linkBlock.top > height + 10 || linkBlock.top > document.documentElement.clientHeight - linkBlock.bottom) {
					popupContainer.style.top = linkBlock.top + document.documentElement.scrollTop - height + "px";
					popupContainer.classList.add("popup-fade-in-down");
					popup.style.padding = `0 0 ${triangleSize}px`;
					// Create a triangle on the bottom.
					popup.style.clipPath = `polygon(0 0, 100% 0, 100% calc(100% - ${triangleSize}px), ${mouseX - leftPosition + triangleSize}px calc(100% - ${triangleSize}px), ${mouseX - leftPosition}px 100%, ${mouseX - leftPosition - triangleSize}px calc(100% - ${triangleSize}px), 0 calc(100% - ${triangleSize}px))`;
				} else {
					popupContainer.style.top = linkBlock.bottom + document.documentElement.scrollTop + "px";
					popupContainer.classList.add("popup-fade-in-up");
					popup.style.padding = `${triangleSize}px 0 0`;
					// Create a triangle on top.
					popup.style.clipPath = `polygon(0 ${triangleSize}px, ${mouseX - leftPosition - triangleSize}px ${triangleSize}px, ${mouseX - leftPosition}px 0, ${mouseX - leftPosition + triangleSize}px ${triangleSize}px, 100% ${triangleSize}px, 100% 100%, 0 100%)`;
				}
			}

			responsePromise.then(response => {
				if (!response) return; // if the fetch was aborted

				popupContent.innerHTML = "";
				let responseDocument = new DOMParser().parseFromString(response, "text/html");
				// Convert to absolute URLs.
				responseDocument.querySelectorAll("a").forEach(link => link.setAttribute("href", link.href));
				let anchoredElement = responseDocument.getElementById(linkAnchor);

				let popupHeader = document.createElement("div");
				popupHeader.style = "font-size: 90%; color: var(--wikt-palette-deepblue, #2f445c)";
				popupContent.append(popupHeader);

				let iconContainer = document.createElement("span");
				iconContainer.style = "float: right; margin-left: 10px; height: 20px; color: var(--wikt-palette-black, #202122)";
				popupHeader.append(iconContainer);

				let titleLink = document.createElement("a");
				titleLink.href = link.href;
				titleLink.title = link.title;
				titleLink.className = "preview-headerlink";

				// Scrape entry content.
				if (isWPlink) {
					iconContainer.innerHTML = articleIcon;
					titleLink.textContent = linkTitle.replaceAll("_", " ");
					if (responseDocument.title)
						titleLink.innerHTML = responseDocument.title; // sometimes gives HTML text
					let WikipediaName = WP_LANGUAGES.get(API_domain.substr(8).split("."));
					popupHeader.append(WikipediaName + " Wikipedia article for ", titleLink);

					let articleContent = document.createElement("div");
					articleContent.style.margin = "5px 0 0 10px";

					let firstSection = responseDocument.querySelector("section");
					if (firstSection && responseDocument.querySelector(`meta`)) {
						firstSection.querySelectorAll("b").forEach(boldElem => boldElem.outerHTML = boldElem.innerHTML);
						firstSection.querySelectorAll(":scope > p, :scope > ul, :scope > ol").forEach(elem => articleContent.append(elem));
					}
					if (articleContent.childElementCount)
						popupContent.append(articleContent);
				} else if (linkTitle === "Appendix:Glossary") {
					iconContainer.innerHTML = glossaryIcon;
					titleLink.textContent = linkAnchor.replaceAll("_", " ");
					popupHeader.append("Glossary definition of ", titleLink);

					if (anchoredElement && anchoredElement.matches(".template-anchor")) {
						let glossaryDefinition = anchoredElement.parentElement.nextElementSibling;
						if (glossaryDefinition && glossaryDefinition.matches("dd")) {
							glossaryDefinition.style = "margin: 5px 0 0 15px";
							popupContent.append(glossaryDefinition);
						}
					}
				} else if (linkTitle.startsWith("Appendix:Bibliography/")) {
					iconContainer.innerHtml = glossaryIcon;
					console.log("using the glossary icon now")
					popupHeader.append(linkTitle.replaceAll("_", " ").replace(/^.+?\/(.+)$/, "$1 bibliography"));

					if (anchoredElement && anchoredElement.matches(".senseid")) {
						let bibliographyCitation = document.createElement("div");
						bibliographyCitation.style = "margin: 5px 0 0 15px";
						bibliographyCitation.innerHTML = anchoredElement.innerHTML;
						bibliographyCitation.removeChild(bibliographyCitation.querySelector(".vsHide"));
						popupContent.append(bibliographyCitation);
					}
				} else {
					const hasDefinitions = elem => Boolean(elem.querySelector("ol:not(.references), .ja-see, .zh-see"));
					iconContainer.innerHTML = definitionIcon;
					// Try to resolve the anchor element to #Chinese.
					if (!anchoredElement && .includes(linkAnchor))
						anchoredElement = responseDocument.querySelector("#Chinese");

					// Try to guess the anchor target in the following order: English, Chinese, Translingual, 
					// Always prioritize an L2 section which contains definitions.
					if (!linkAnchor) {
						let pageH2s = Array.from(responseDocument.querySelectorAll("h2"));
						if (pageH2s.some(h2 => hasDefinitions(h2.parentElement)))
							pageH2s = pageH2s.filter(h2 => hasDefinitions(h2.parentElement));

						anchoredElement = pageH2s.find(h2 => h2.id === "English");
						if (!anchoredElement) anchoredElement = pageH2s.find(h2 => h2.id === "Chinese");
						if (!anchoredElement) anchoredElement = pageH2s.find(h2 => h2.id === "Translingual");
						if (!anchoredElement) anchoredElement = pageH2s;
					}

					let displayTitle = document.createElement("strong");
					displayTitle.textContent = linkTitle.split("/").pop().replaceAll("_", " ");
					if (linkTitle.startsWith("Reconstruction:"))
						displayTitle.textContent = "*" + displayTitle.textContent;

					// Find localest section containing an h2.
					let languageSection = anchoredElement;
					while (languageSection && !languageSection.querySelector(":scope > h2"))
						languageSection = languageSection.parentElement.closest("section");

					// Make sure that the entry is well-formed.
					if (languageSection) {
						let language = languageSection.querySelector(":scope > h2").textContent;
						let scrapeSection = anchoredElement.closest("section");

						// Find localest section which contains any definitions.
						while (scrapeSection && !hasDefinitions(scrapeSection))
							scrapeSection = scrapeSection.parentElement.closest("section");

						if (scrapeSection) {
							let headwords = scrapeSection.querySelectorAll(".headword-line > strong");
							if (new Set(Array.from(headwords).map(h => h.textContent)).size === 1) {
								// If there is a single unique headword, replace the display title with that.
								if (headwords.querySelector("a > img"))
									displayTitle = headwords.querySelector("a > img").cloneNode();
								else
									displayTitle = headwords;
							} else if (new Set(Array.from(headwords).map(h => h.cloneNode().outerHTML)).size === 1) {
								// If there is a single unique set of element attributes, use that with the display title.
								let temp = displayTitle.innerHTML;
								displayTitle = headwords.cloneNode(); // this clears out the inner HTML
								displayTitle.innerHTML = temp;
							}
							// Remove links in the headword (if there are any).
							displayTitle.querySelectorAll("a").forEach(elem => elem.replaceWith(elem.textContent));

							let ols = scrapeSection.querySelectorAll(":scope > ol:not(.references), section > ol:not(.references)");
							if (anchoredElement.matches(".senseid")) {
								Array.from(anchoredElement.parentElement.childNodes).forEach(child => {
									if (child !== anchoredElement) {
										child.remove();
									}
								});
								ols = ;
							}

							for (let ol of ols) {
								let POS_container = document.createElement("div");
								POS_container.style.margin = "8px 0 5px 0";

								let POS = document.createElement("span");
								POS.style = "font-size: 110%; font-weight: bold";
								POS.textContent = ol.closest("section").firstChild.textContent;
								POS_container.append(POS);

								let tlb = ol.closest("section").querySelector(".headword-line ~ .usage-label-term");
								if (tlb)
									POS_container.append(document.createElement("br"), tlb);

								popupContent.append(POS_container, ol);
							}
							// {{ja-see}} and {{zh-see}} don't follow the normal format...
							for (let seeTemplate of scrapeSection.querySelectorAll(".ja-see, .zh-see"))
								popupContent.append(seeTemplate);
						}
						titleLink.append(displayTitle);
						popupHeader.append("Preview definitions of " + language + " ", titleLink);
					} else {
						titleLink.append(displayTitle);
						popupHeader.append("Preview definitions of ", titleLink);
					}
				}

				if (popupContent.childElementCount > 1) {
					// Clean up HTML.
					popupContent.querySelectorAll("link, .previewonly, .maintenance-line, .mw-empty-elt, .reference, .Inline-Template").forEach(elem => elem.remove());
					if (!isWPlink)
						popupContent.querySelectorAll("li > ul").forEach(elem => elem.remove()); // remove quotations
					for (let elem of popupContent.querySelectorAll("*"))
						elem.removeAttribute("id"); // avoid inadvertently repeating IDs within a page
				} else if (isWPlink) {
					// Display a message if the Wikipedia article was invalid or not in mainspace.
					let noArticle = document.createElement("div");
					noArticle.style = "margin: 5px 0 0 15px; font-size: 90%";
					noArticle.textContent = "(article content could not be previewed)";
					popupContent.append(noArticle);
				} else if (linkAnchor && !anchoredElement) {
					// Display a message if the anchor is invalid.
					let noSectionFound = document.createElement("div");
					noSectionFound.style = "margin: 10px 0 0 7.5px; font-size: 90%";
					let strong = document.createElement("strong");
					strong.textContent = linkAnchor.replaceAll("_", " ");
					noSectionFound.append("The ", strong, " section was not found on this page.");
					popupContent.append(noSectionFound);
				} else {
					// Display a message if no definitions were found in the section.
					let noDefinitionsFound = document.createElement("div");
					noDefinitionsFound.style = "margin: 5px 0 0 15px; font-size: 90%";
					noDefinitionsFound.textContent = "(no definitions found)";
					popupContent.append(noDefinitionsFound);
				}

				// Reduce the padding if a scrollbar is present. The intended padding is 16px on each side.
				if (width - popupHeader.clientWidth > 32)
					popupContent.style.paddingRight = Math.max(4, 48 + popupHeader.clientWidth - width) + "px";
			});
			// (Hack?) make sure that `link pointerleave` doesn't cause the popup to immediately close.
			setTimeout(() => clearTimeout(popupTimer), 0);
		}, isPreviewLink ? 1200 : 400);
	});

	link.addEventListener("pointerout", () => {
		clearTimeout(popupTimer);
		if (link === openLink) {
			popupTimer = setTimeout(closePopup, 300);
		} else {
			API_controller.abort();
			API_controller = new AbortController();
		}
	});

	link.addEventListener("pointermove", event => {
		mouseX = event.clientX;
		mouseY = event.clientY;
	});

	link.addEventListener("click", () => clearTimeout(popupTimer));
}

// Process all links.
document.querySelectorAll("a").forEach(processLink);

// Process links which are added to the DOM after the gadget has run.
(new MutationObserver(events => events.flatMap(event => ).forEach(node => {
	if (node instanceof HTMLAnchorElement)
		processLink(node);
	if (node instanceof HTMLElement)
		node.querySelectorAll("a").forEach(processLink);
}))).observe(document.body, {childList: true, subtree: true});

// </nowiki>