MediaWiki:Gadget-cdn-purger.js[править введение]

Материал из Minecraft Wiki
Перейти к навигации Перейти к поиску
[создать | история | обновить]Документация
У этого скрипта нет документации. Если вы знаете, как использовать этот скрипт, пожалуйста, добавьте соответствующую информацию.

Замечание. Возможно, после сохранения вам придётся очистить кэш своего браузера, чтобы увидеть изменения.

  • Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl-F5 или Ctrl-R (⌘-R на Mac)
  • Google Chrome: Нажмите Ctrl-Shift-R (⌘-Shift-R на Mac)
  • Internet Explorer: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl-F5
  • Opera: Выберите очистку кэша в меню Инструменты → Настройки
/* global OO, mw, $ */

mw.loader.using(['oojs-ui-windows', 'ext.gadget.global-utils']).then((require) => {
	const i18n = {
		en: {
			entryLink: 'CDN purge',
			entryTitle: 'Purge CDN cache',
			dialogTitle: 'Purge CDN cache',
			actionPurge: 'Purge',
			actionCancel: 'Cancel',
			tabCurrent: 'Current',
			tabUrl: 'URL',
			tabPreview: 'Preview',
			tabSearch: 'Search',
			tabInterface: 'Interface',
			quickAction: 'Quick action',
			qaCurrentPage: 'Current page',
			qaCurrentPagePopup: 'Current page (popup)',
			qaCurrentPageSearch: 'Current page (search)',
			qaSidebarVersion: 'Sidebar version',
			urlsToPurge: 'URLs to purge',
			urlsToPurgeHelp: 'One URL per line.',
			searchQueryToPurge: 'Search query to purge',
			searchQueryToPurgeHelp:
				'All subqueries will also be purged, e.g. purging "foo bar" will purge "f", "fo", ..., "foo bar".',
			titlesToPurge: 'Titles to purge',
			titlesToPurgeHelp: 'One title per line.',
			interfaceActions: 'Interface actions',
			ifSiteStyles: 'Site styles',
			ifSiteScripts: 'Site scripts',
			purgeLogin: 'You will be redirected to authenticate with Jigsaw. Continue?',
			purgeSuccess: 'Purge request sent successfully.',
		},
		de: {
			entryLink: 'CDN-Cache leeren',
			entryTitle: 'CDN-Cache leeren',
			dialogTitle: 'CDN-Cache leeren',
			actionPurge: 'Cache leeren',
			actionCancel: 'Abbrechen',
			tabCurrent: 'Allgemein',
			tabUrl: 'URL',
			tabPreview: 'Vorschaubild',
			tabSearch: 'Suche',
			tabInterface: 'Oberfläche',
			quickAction: 'Häufige Aktionen',
			qaCurrentPage: 'Aktuelle Seite',
			qaCurrentPagePopup: 'Aktuelle Seite: Popups',
			qaCurrentPageSearch: 'Aktuelle Seite: Suchergebnisse',
			qaSidebarVersion: 'Seitenleiste: Versionen',
			urlsToPurge: 'Cache für URL(s) leeren',
			urlsToPurgeHelp: 'Eine URL pro Zeile.',
			searchQueryToPurge: 'Cache für Suchanfrage(n) leeren',
			searchQueryToPurgeHelp:
				'Alle Präfixe werden auch geleert, z. B. wird für "foo bar" der Cache für "f", "fo", ... und "foo bar" geleert.',
			titlesToPurge: 'Cache für Artikel-Vorschaubilder leeren',
			titlesToPurgeHelp: 'Ein Artikelname pro Zeile.',
			interfaceActions: 'Cache für Oberfläche leeren',
			ifSiteStyles: 'Website-Stile (CSS)',
			ifSiteScripts: 'Website-Skripte (JavaScript)',
			purgeLogin: 'Du wirst zur Authentifizierung mit Jigsaw weitergeleitet. Fortfahren?',
			purgeSuccess: 'Cache-Leerungs-Anfrage wurde erfolgreich abgesendet.',
		},
	};

	const globalUtils = require('ext.gadget.global-utils');

	/** @type {msg: typeof mw.msg; message: typeof mw.message;} */
	const i18nLang = new globalUtils.MessageParser(i18n);

	const popupUrl = (title) =>
		`${mw.config.get('wgServer')}/api.php?action=query&format=json&prop=info%7Cextracts%7Cpageimages%7Crevisions%7Cinfo&formatversion=2&redirects=true&exintro=true&exchars=525&explaintext=true&exsectionformat=plain&piprop=thumbnail&pithumbsize=640&pilicense=any&rvprop=timestamp&inprop=url&titles=${encodeURIComponent(new mw.Title(title).getPrefixedDb())}&smaxage=300&maxage=300&uselang=content`;

	function searchUrls(title) {
		const chars = [...title];
		let terms = chars.map((_, i) => chars.slice(0, i + 1).join('').trim());

		if (title !== title.toLowerCase()) {
			terms = terms.concat(terms.map((term) => term.toLowerCase()));
		}

		return Array.from(new Set(terms)).map(
			(term) => `${mw.config.get('wgServer')}/rest.php/v1/search/title?q=${encodeURIComponent(term).replace(/%20/g, '+')}&limit=10`
		);
	}

	//#region Current
	function CurrentLayout(name, config) {
		CurrentLayout.super.call(this, name, config);

		this.content = new OO.ui.FieldsetLayout();
		this.radios = new OO.ui.RadioSelectWidget({
			items: [
				new OO.ui.RadioOptionWidget({
					data: 'currentPage',
					label: i18nLang.msg('qaCurrentPage'),
				}),
				new OO.ui.RadioOptionWidget({
					data: 'currentPagePopup',
					label: i18nLang.msg('qaCurrentPagePopup'),
				}),
				new OO.ui.RadioOptionWidget({
					data: 'currentPageSearch',
					label: i18nLang.msg('qaCurrentPageSearch'),
				}),
				new OO.ui.RadioOptionWidget({
					data: 'sidebarVersion',
					label: i18nLang.msg('qaSidebarVersion'),
				}),
			],
		});

		this.field = new OO.ui.FieldLayout(this.radios, {
			label: i18nLang.msg('quickAction'),
			align: 'top',
		});

		this.content.addItems([this.field]);
		this.$element.append(this.content.$element);
	}
	OO.inheritClass(CurrentLayout, OO.ui.PageLayout);

	CurrentLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel(i18nLang.msg('tabCurrent'));
	};

	CurrentLayout.prototype.getPurgeUrls = function () {
		const selected = this.radios.findSelectedItem().getData();
		if (selected === 'currentPage') {
			return [location.href];
		} else if (selected === 'currentPagePopup') {
			return [popupUrl(mw.config.get('wgPageName'))];
		} else if (selected === 'currentPageSearch') {
			return searchUrls(mw.config.get('wgPageName'));
		} else if (selected === 'sidebarVersion') {
			return [
				`${mw.config.get('wgServer')}/api.php?action=parse&format=json&formatversion=2&prop=text&contentmodel=wikitext&disablelimitreport=1&requestid=gadget-lazyloadSidebarVersions&page=MediaWiki%3ASidebar-versions`,
			];
		}
	};
	//#endregion

	//#region Url
	function UrlLayout(name, config) {
		UrlLayout.super.call(this, name, config);

		this.content = new OO.ui.FieldsetLayout();
		this.textarea = new OO.ui.MultilineTextInputWidget({
			rows: 10,
		});

		this.field = new OO.ui.FieldLayout(this.textarea, {
			label: i18nLang.msg('urlsToPurge'),
			align: 'top',
			helpInline: true,
			help: i18nLang.msg('urlsToPurgeHelp'),
		});

		this.content.addItems([this.field]);
		this.$element.append(this.content.$element);
	}
	OO.inheritClass(UrlLayout, OO.ui.PageLayout);

	UrlLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel(i18nLang.msg('tabUrl'));
	};

	UrlLayout.prototype.getPurgeUrls = function () {
		return this.textarea
			.getValue()
			.split('\n')
			.filter((url) => url);
	};
	//#endregion

	//#region Preview
	function PreviewLayout(name, config) {
		PreviewLayout.super.call(this, name, config);

		this.content = new OO.ui.FieldsetLayout();
		this.textarea = new OO.ui.MultilineTextInputWidget({
			rows: 10,
		});

		this.field = new OO.ui.FieldLayout(this.textarea, {
			label: i18nLang.msg('titlesToPurge'),
			align: 'top',
			helpInline: true,
			help: i18nLang.msg('titlesToPurgeHelp'),
		});

		this.content.addItems([this.field]);
		this.$element.append(this.content.$element);
	}
	OO.inheritClass(PreviewLayout, OO.ui.PageLayout);

	PreviewLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel(i18nLang.msg('tabPreview'));
	};

	PreviewLayout.prototype.getPurgeUrls = function () {
		return this.textarea
			.getValue()
			.split('\n')
			.filter((title) => title)
			.map((title) => popupUrl(title));
	};
	//#endregion

	//#region Search
	function SearchLayout(name, config) {
		SearchLayout.super.call(this, name, config);

		this.content = new OO.ui.FieldsetLayout();
		this.textInput = new OO.ui.TextInputWidget();

		this.field = new OO.ui.FieldLayout(this.textInput, {
			label: i18nLang.msg('searchQueryToPurge'),
			align: 'top',
			helpInline: true,
			help: i18nLang.msg('searchQueryToPurgeHelp'),
		});

		this.content.addItems([this.field]);
		this.$element.append(this.content.$element);
	}
	OO.inheritClass(SearchLayout, OO.ui.PageLayout);

	SearchLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel(i18nLang.msg('tabSearch'));
	};

	SearchLayout.prototype.getPurgeUrls = function () {
		return searchUrls(this.textInput.getValue());
	};
	//#endregion

	//#region Interface
	function InterfaceLayout(name, config) {
		InterfaceLayout.super.call(this, name, config);

		this.content = new OO.ui.FieldsetLayout();
		this.radios = new OO.ui.RadioSelectWidget({
			items: [
				new OO.ui.RadioOptionWidget({
					data: 'siteStyles',
					label: i18nLang.msg('ifSiteStyles'),
				}),
				new OO.ui.RadioOptionWidget({
					data: 'siteScripts',
					label: i18nLang.msg('ifSiteScripts'),
				}),
			],
		});

		this.field = new OO.ui.FieldLayout(this.radios, {
			label: i18nLang.msg('interfaceActions'),
			align: 'top',
		});

		this.content.addItems([this.field]);
		this.$element.append(this.content.$element);
	}
	OO.inheritClass(InterfaceLayout, OO.ui.PageLayout);

	InterfaceLayout.prototype.setupOutlineItem = function () {
		this.outlineItem.setLabel(i18nLang.msg('tabInterface'));
	};

	InterfaceLayout.prototype.getPurgeUrls = function () {
		const selected = this.radios.findSelectedItem().getData();
		if (selected === 'siteStyles') {
			return [
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgContentLanguage')}&modules=startup&only=scripts&raw=1&skin=vector`,
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgContentLanguage')}&modules=startup&only=scripts&raw=1&skin=minerva`,
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgUserLanguage')}&modules=startup&only=scripts&raw=1&skin=vector`,
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgUserLanguage')}&modules=startup&only=scripts&raw=1&skin=minerva`,
			];
		} else if (selected === 'siteScripts') {
			return [
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgContentLanguage')}&modules=site.styles&only=styles&skin=vector`,
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgContentLanguage')}&modules=site.styles&only=styles&skin=minerva`,
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgUserLanguage')}&modules=site.styles&only=styles&skin=vector`,
				`${mw.config.get('wgServer')}/load.php?lang=${mw.config.get('wgUserLanguage')}&modules=site.styles&only=styles&skin=minerva`,
			];
		}
	};
	//#endregion

	//#region Dialog
	const dialogFactory = new OO.Factory();
	function PurgeDialog(config) {
		PurgeDialog.super.call(this, config);
	}
	OO.inheritClass(PurgeDialog, OO.ui.ProcessDialog);

	PurgeDialog.static.name = 'purgeDialog';
	PurgeDialog.static.title = i18nLang.msg('dialogTitle');
	PurgeDialog.static.actions = [
		{ action: 'save', label: i18nLang.msg('actionPurge'), flags: ['primary', 'progressive'] },
		{ action: 'cancel', label: i18nLang.msg('actionCancel'), flags: ['safe', 'close'] },
	];

	PurgeDialog.prototype.getBodyHeight = function () {
		return 400;
	};

	PurgeDialog.prototype.getSize = () => 'large';

	PurgeDialog.prototype.initialize = function () {
		PurgeDialog.super.prototype.initialize.apply(this, arguments);
		this.bookletLayout = new OO.ui.BookletLayout({
			outlined: true,
		});
		this.pages = [
			new CurrentLayout('current'),
			new UrlLayout('url'),
			new PreviewLayout('preview'),
			new SearchLayout('search'),
			new InterfaceLayout('interface'),
		];

		this.bookletLayout.addPages(this.pages);
		this.$body.append(this.bookletLayout.$element);
	};

	const authorize = () =>
		OO.ui.confirm(i18nLang.msg('purgeLogin')).then((confirmed) => {
			if (confirmed) {
				window.open(
					`${mw.config.get('wgServer')}/rest.php/oauth2/authorize?response_type=code&client_id=44227d845507b1ec1cdc38db933623a6`
				);
			}
		});

	PurgeDialog.prototype.getActionProcess = function (action) {
		if (action === 'save') {
			if (!mw.cookie.get('Tokens', 'jigsaw')) {
				return new OO.ui.Process(authorize());
			}

			const urls = this.bookletLayout.getCurrentPage().getPurgeUrls();

			return new OO.ui.Process(
				fetch(`https://tools.minecraft.wiki/jigsaw/purge?origin=${location.origin}`, {
					method: 'POST',
					headers: {
						'Content-Type': 'application/json',
					},
					credentials: 'include',
					body: JSON.stringify({ urls }),
				})
					.then((response) => {
						if (response.status === 401) {
							throw new Error('Unauthorized');
						}
						return response;
					})
					.then((response) => response.json())
					.then((_) => OO.ui.alert(i18nLang.msg('purgeSuccess')))
					.catch((error) => {
						if (error.message === 'Unauthorized') {
							return authorize();
						}
						throw error;
					})
			);
		} else if (action === 'cancel') {
			return new OO.ui.Process(() => {
				this.close({ action });
			});
		}
		return PurgeDialog.super.prototype.getActionProcess.call(this, action);
	};
	dialogFactory.register(PurgeDialog);
	//#endregion

	const windowManager = new OO.ui.WindowManager({
		factory: dialogFactory,
	});
	$(document.body).append(windowManager.$element);

	const purgerLink = mw.util.addPortletLink(
		'p-cactions',
		'#',
		i18nLang.msg('entryLink'),
		'ca-purger',
		i18nLang.msg('entryTitle'),
		null,
		'#ca-purge ~ *'
	);
	$(purgerLink)
		.on('click', (e) => {
			e.preventDefault();

			windowManager.openWindow('purgeDialog');
		});
});