Tip of the day
Attributes involving a percent symbol % are multiplicative (For Example: +10% Fine material finding gives 1.1/100).

MediaWiki:Gadget-HideSearchResults.js

From Walkscape Walkthrough
Revision as of 13:06, 30 August 2026 by Bonez565 (talk | contribs)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
(function () {
	'use strict';

	// Matches translated subpages like:
	// /en
	// /fr
	// /it
	// /pt-br
	// /zh-hans
	//
	// Does not usually match normal content subpages like /Mining or /Source
	var translatedSuffixRegex = /\/[a-z]{2,3}(?:-[a-z0-9]{2,8})?$/i;
	
	// Matches recipe subpages like:
	// Item name/Recipe
	var recipeSuffixRegex = /\/Recipe$/i;

	function isHiddenSearchTitle(title) {
		title = (title || '').trim();
	
		return (
			translatedSuffixRegex.test(title) ||
			recipeSuffixRegex.test(title)
		);
	}

	function getSearchResultTitle($result) {
		var $headingLink = $result.find('.mw-search-result-heading a').first();

		if ($headingLink.length) {
			return ($headingLink.attr('title') || $headingLink.text() || '').trim();
		}

		return '';
	}

	function filterSpecialSearchResults() {
		var hiddenCount = 0;

		$('.mw-search-result').each(function () {
			var $result = $(this);
			var title = getSearchResultTitle($result);

			if (!title) {
				return;
			}

			if (isHiddenSearchTitle(title)) {
				$result.hide();
				hiddenCount++;
			} else {
				$result.show();
			}
		});

		updateSearchNotice(hiddenCount);
	}

	function updateSearchNotice(hiddenCount) {
		var noticeId = 'search-subpages-filter-notice';
		var $existing = $('#' + noticeId);
	
		if (!hiddenCount) {
			$existing.remove();
			return;
		}
	
		var message =
			hiddenCount +
			' extra subpage' +
			(hiddenCount === 1 ? '' : 's') +
			' hidden from search results.';
	
		if ($existing.length) {
			$existing.text(message);
			return;
		}
	
		$('<div>')
			.attr('id', noticeId)
			.css({
				margin: '0 0 1em 0',
				padding: '0.75em 1em',
				border: '1px solid #c8ccd1',
				background: '#f8f9fa'
			})
			.text(message)
			.insertBefore('.searchresults, .mw-search-results');
	}

	// Add a strong hiding rule once.
	// Using !important prevents MediaWiki's suggestion code from
	// simply showing the result again after we filter it.
	mw.util.addCSS(
		'.ws-hidden-search-result {' +
			'display: none !important;' +
		'}'
	);

	function getSuggestionTitle($result) {
		var $link = $result.find('a.mw-searchSuggest-link').first();

		if ($link.length) {
			return (
				$link.attr('title') ||
				$link.attr('data-title') ||
				$link.text() ||
				''
			).trim();
		}

		// Fallback for other MediaWiki/OOUI suggestion types
		return (
			$result.attr('title') ||
			$result.attr('data-title') ||
			$result.attr('data-value') ||
			$result.find('.oo-ui-labelElement-label').first().text() ||
			$result.text() ||
			''
		).trim();
	}
	
	function filterSuggestionResults() {
		$('.suggestions-result').each(function () {
			var $result = $(this);
			var title = getSuggestionTitle($result);
	
			if (!title) {
				return;
			}
	
			$result.toggleClass(
				'ws-hidden-search-result',
				isHiddenSearchTitle(title)
			);
		});
	
		$('.oo-ui-optionWidget').each(function () {
			var $result = $(this);
			var title = getSuggestionTitle($result);
	
			if (!title) {
				return;
			}
	
			$result.toggleClass(
				'ws-hidden-search-result',
				isHiddenSearchTitle(title)
			);
		});
	}

	function scheduleSuggestionFilter() {
		// The search suggestions arrive asynchronously.
		// Scan several times so we catch both the initial popup
		// and the completed API response.
		filterSuggestionResults();

		setTimeout(filterSuggestionResults, 50);
		setTimeout(filterSuggestionResults, 150);
		setTimeout(filterSuggestionResults, 300);
		setTimeout(filterSuggestionResults, 600);
	}

	function observeSearchResults() {
		var target = document.querySelector('.mw-search-results') ||
		             document.querySelector('.searchresults');

		if (!target || !window.MutationObserver) {
			return;
		}

		var observer = new MutationObserver(function () {
			filterSpecialSearchResults();
		});

		observer.observe(target, {
			childList: true,
			subtree: true
		});
	}

	function observeSuggestions() {
		if (!window.MutationObserver) {
			return;
		}

		var observer = new MutationObserver(function (mutations) {
			var shouldFilter = false;

			mutations.forEach(function (mutation) {
				if (
					mutation.type === 'childList' ||
					mutation.type === 'characterData'
				) {
					shouldFilter = true;
				}
			});

			if (shouldFilter) {
				scheduleSuggestionFilter();
			}
		});

		observer.observe(document.body, {
			childList: true,
			characterData: true,
			subtree: true
		});
	}

	function bindSearchInputEvents() {
		// Delegated event handler also works if MediaWiki
		// replaces the search input dynamically.
		$(document).on(
			'input keyup focus',
			'#searchInput, #simpleSearch input[name="search"], .mw-searchInput',
			function () {
				scheduleSuggestionFilter();
			}
		);
	}

	$(function () {
		// Filter full search results if on Special:Search
		if (mw.config.get('wgCanonicalSpecialPageName') === 'Search') {
			filterSpecialSearchResults();
			observeSearchResults();
		}
	
		// Filter autocomplete suggestions everywhere
		bindSearchInputEvents();
		filterSuggestionResults();
		observeSuggestions();
	});
}());