User:SunAfterRain/js/blib/archive.js

注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。

// <nowiki>
$.when(
	$.ready,
	mw.loader.using(['mediawiki.api', 'ext.gadget.HanAssist'])
).then((_$, require) => {
	const libPrefix = 'User:Bluedecklibrary/';
	const libTemplateName = 'user:bluedeck/infr/library.card.js';

	if (
		!mw.config.get('wgRevisionId')
		|| mw.config.get('wgAction') !== 'view'
		|| mw.config.get('wgCurRevisionId') !== mw.config.get('wgRevisionId')
		|| mw.config.get('wgPageName').startsWith(libPrefix)
	) {
		return;
	}

	const gadgetName = 'blib-archive.js';

	const HanAssist = require('ext.gadget.HanAssist');

	let $link;
	const api = new mw.Api();
	const messages = HanAssist.batchConv({
		summary: {
			hans: '存档至图书馆:[[Special:PermanentLink/$1]] by [[Special:Contributions/$2|$2]]@$3',
			hant: '存檔至圖書館:[[Special:PermanentLink/$1]] by [[Special:Contributions/$2|$2]]@$3'
		},

		portletLink: { hans: '存档至图书馆', hant: '存檔至圖書館' },

		pageMissing: { hans: '抱歉,页面不存在,无法执行存档。', hant: '抱歉,頁面不存在,無法執行存檔。' },

		saving: { hans: '正在存档', hant: '正在存檔' },
		saveFail: { hans: '存档失败:$1', hant: '存檔失敗:$1' },
		saveNoChange: { hans: '疑似编辑冲突', hant: '疑似編輯衝突' },
		saved: { hans: '已存档。', hant: '已存檔。' },
		viewSaved: { hans: '查看', hant: '檢視' },
	});

	function notify(type, message, options = {}) {
		mw.notify(
			message,
			{
				title: gadgetName,
				tag: gadgetName,
				autoHide: !['warn', 'error'].includes(type),
				type,
				...options
			}
		);
	}

	function buildArchiveWikitext(page, revision) {
		const args = {
			1: page.title,
			time: new Date().toISOString(),
			jst: Date.now(),
			revtime: revision.timestamp,
			revjst: new Date(revision.timestamp).getTime(),
			revid: revision.revid,
			pageid: page.pageid
		};
		let output = `{{${libTemplateName}`;
		for (const [key, value] of Object.entries(args)) {
			output += `|${key}=${value}`;
		}
		output += '}}\n';
		output += revision.slots.main.content
			.split('{{')
			.join('{{((}}')
			.replace(/\[\[(.*?)(\|.*?)?\]\]/g, (orig, title, text) => {
				if (!title.startsWith(':')) {
					const mTitle = mw.Title.newFromText(title.trim());
					if (mTitle?.namespace === 14) {
						return `[[:${title}${text || ''}]]`;
					}
				}
				return orig;
			});
		return output;
	}

	function spliText(input) {
		return input.split(/\r?\n/g)
			.map((line) => [document.createTextNode(line), document.createElement('br')])
			.flat()
			.slice(0, -1);
	}

	async function main() {
		const wgPageName = mw.config.get('wgPageName');
		try {
			const pageData = await api.get({
				action: 'query',
				titles: wgPageName,
				prop: 'revisions',
				rvprop: ['ids', 'content', 'timestamp', 'user'/*, 'comment', 'tags'*/],
				rvslots: 'main',
				rvlimit: 1,
				formatversion: '2'
			});
			const page = pageData?.query?.pages?.[0];
			const revision = page?.revisions?.[0];
			if (!page || page.missing || !revision) {
				notify('warn', messages.pageMissing);
				return;
			}
			const archiveText = buildArchiveWikitext(page, revision);
			console.log(archiveText);
			notify('info', messages.saving);
			const editData = await api.postWithToken('csrf', {
				action: 'edit',
				title: `${libPrefix}${wgPageName}`,
				text: archiveText,
				summary: mw.format(messages.summary, revision.revid, revision.user, revision.timestamp),
				basetimestamp: revision.timestamp,
				starttimestamp: new Date().toISOString(),
				formatversion: '2'
			});
			if (editData.edit.nochange) {
				throw messages.saveNoChange;
			}
			notify(
				'success',
				$('<div>')
					.append(
						document.createTextNode(messages.saved),
						document.createTextNode('['),
						$('<a>')
							.attr({
								href: mw.util.getUrl(`Special:PermanentLink/${editData.edit.newrevid}`)
							})
							.text(messages.viewSaved),
						document.createTextNode(']'),
					)
			);
			$link?.remove();
			$link = undefined;
		} catch (error) {
			console.error(error);
			notify('error', $('<div>').append(...spliText(mw.format(messages.saveFail, String(error)))));
		}
	}

	$link = $(mw.util.addPortletLink(
		'p-tb',
		'#',
		messages.portletLink,
		't-blib-archive'
	))
		.on('click', (e) => {
			e.preventDefault();
			main();
		});
});
// </nowiki>