Ця сторінка повністю захищена, оскільки містить текст інтерфейсу цієї вікі.

MediaWiki:Gadget-betterRandom.js

Матеріал з Minecraft Wiki
Перейти до навігації Перейти до пошуку
Іншими мовами

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

Google Chrome, Firefox, Microsoft Edge, and Safari: Hold down the Shift key and click the Reload toolbar button.
For details and instructions about other browsers, see Wikipedia:Bypass your cache.

$(() => {
	const mwconfig = mw.config.get([
		'wgContentNamespaces',
		'wgCanonicalSpecialPageName',
		'wgTitle',
		'wgFormattedNamespaces',
		'wgNamespaceIds',
		'wgArticlePath',
	]);
	
	const config = {
		blockDisambiguations: true,
		blockedCategories: [
			'Категорія:М\'які перенаправлення',
		],
		blockedTemplates: [
			'Шаблон:Версія навігація',
		],
		allowedSubpages: [
			'Команди консолі',
			'Керівництва',
			'Minecraft Dungeons:Керівництва',
		],
		queryLimit: 5,
		sidebarLinks: {
			'n-randompage': mwconfig.wgContentNamespaces,
			'n-in-Minecraft': [0],
			'n-in-Dungeons': [10000],
			'n-in-Earth': [10002],
			'n-in-Story-Mode': [10004],
			'n-in-Legends': [10006],
		},
		specialpage: {
			heading: 'Випадкова стаття',
			text: 'Незабаром вас буде перенаправлено на випадкову статтю.'
		},
	};
	
	if (mwconfig.wgCanonicalSpecialPageName === 'Blankpage') {
		let [, pagename, namespace] = mwconfig.wgTitle.split('/');
		if (pagename === 'random') {
			document.getElementById('firstHeading').textContent = config.specialpage.heading;
			document.getElementById('mw-content-text').textContent = config.specialpage.text;
			let namespaces = [];
			if (namespace) {
				namespace = namespace.toLowerCase().replace(/_/g, ' ').trim().replace(/ /g, '_');
				if ( namespace.includes(',') ) {
					namespaces = namespace.split(/_*,_*/).map(ns => mwconfig.wgNamespaceIds[ns] || -1);
				}
				else namespaces = [mwconfig.wgNamespaceIds[namespace] || 0];
			}
			namespaces = [...new Set(namespaces.filter(ns => ns >= 0))];
			if (!namespaces.length) namespaces = mwconfig.wgContentNamespaces;
			let fallback = mw.util.getParamValue('fallback') || 'Special:RandomRootpage/' + (namespace || '');
			return redirect(namespaces, fallback);
		}
	}
	
	// Replace "Random page" buttons on Vector skin
	for (let sidebarLinkId in config.sidebarLinks) {
		let sidebarItem = document.getElementById(sidebarLinkId);
		if (sidebarItem) {
			let sidebarLink = sidebarItem.getElementsByTagName('a')[0];
			if (sidebarLink) generateListener(sidebarLink, config.sidebarLinks[sidebarLinkId]);
		}
	}
	
	// Replace "Random page" button on Minerva skin
	let mobileSidebarLink = document.querySelector('#p-navigation > li:nth-child(2) > a');
	if (mobileSidebarLink) generateListener(mobileSidebarLink, mwconfig.wgContentNamespaces);
	
	function generateListener(sidebarLink, namespaces) {
		sidebarLink.addEventListener('click', function(e) {
			e.preventDefault();
			redirect(namespaces, this.dataset.fallback || 'Special:RandomRootpage');
		});
		let articlePath = mwconfig.wgArticlePath.replace('$1', '');
		let fallback = '';
		if (sidebarLink.pathname.startsWith(articlePath)) {
			fallback = decodeURI(sidebarLink.pathname.slice(articlePath.length));
		}
		let pagename = 'Special:BlankPage/random';
		if (namespaces !== mwconfig.wgContentNamespaces) {
			let namespaceNames = namespaces.map(ns => mwconfig.wgFormattedNamespaces[ns]).join(',') || 'Main';
			pagename += '/' + namespaceNames;
			if (!fallback) fallback = 'Special:RandomRootpage/' + namespaceNames;
		}
		sidebarLink.href = mw.util.getUrl(pagename);
		if (fallback) {
			sidebarLink.dataset.fallback = fallback;
			sidebarLink.search = '?fallback=' + fallback.replace(/&/g, '%26');
		}
	}

	function redirect(namespaces, fallback) {
		const api = new mw.Api();
		api.get({
			action: 'query',
			generator: 'random',
			grnnamespace: namespaces,
			grnfilterredir: 'nonredirects',
			grnlimit: config.queryLimit,
			prop: [
				'info',
				'pageprops',
				'categories',
				'templates',
			],
			inprop: 'url',
			ppprop: [
				'noindex',
				'disambiguation',
			],
			tltemplates: config.blockedTemplates,
			tllimit: 'max',
			clcategories: config.blockedCategories,
			cllimit: 'max',
			formatversion: 2,
			requestid: 'gadget-betterRandom',
		}).then(result => {
			let pages = result.query.pages;
			
			// Remove strongly disallowed pages
			pages = pages.filter(page => {
				if (page.pageprops && 'noindex' in page.pageprops) return false;
				if (page.categories && config.blockedCategories.length) return false;
				if (page.title.includes('/')) {
					let split = page.title.split('/');
					if (split.length > 2) return false;
					return config.allowedSubpages.includes(split[0]);
				}
				return true;
			});
			
			// Use fallback if no valid pages remain
			if (!pages.length) {
				location.href = mw.util.getUrl(fallback);
				return;
			}
			
			// Find allowed page
			let page = pages.find(page => {
				if (page.pageprops && 'disambiguation' in page.pageprops && config.blockDisambiguations) return false;
				if (page.templates && config.blockedTemplates.length) return false;
				return true;
			}) || pages[0];
			
			location.href = page.fullurl;
		}).catch(error => {
			console.log(error);
			location.href = mw.util.getUrl(fallback);
		});
	}
});