User:Xiplus/js/TranslateVariants.js

维基百科,自由的百科全书

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

// <nowiki>
/* globals TranslateVariants:true */
/**
 * 使用說明請見 https://zh.wikipedia.org/wiki/User:Xiplus/js/TranslateVariants
 */
(function() {

	if (mw.config.get('wgPageName').match(/^MediaWiki:[^/]+(\/zh)?$/)) {
		mw.loader.using(['mediawiki.api', 'mediawiki.ForeignApi', 'mediawiki.diff.styles']).then(function() {
			let link = mw.util.addPortletLink(
				'p-cactions',
				'#',
				'轉換變體'
			)
			$(link).on('click', function() {
				this.remove();
				main();
			});
		});
	} else {
		return;
	}

	if (typeof (TranslateVariants) == 'undefined') {
		TranslateVariants = {};
	}
	if (typeof (TranslateVariants.summary) != 'string') {
		TranslateVariants.summary = '自動轉換變體自[[$1]] via [[User:Xiplus/js/TranslateVariants.js|TranslateVariants]]'
	}

	async function main() {
		const langs = ['zh', 'zh-hans', 'zh-cn', 'zh-my', 'zh-sg', 'zh-hant', 'zh-hk', 'zh-mo', 'zh-tw'];
		const langname = {
			'zh': '原始',
			'zh-hans': '简体',
			'zh-cn': '大陆简体',
			'zh-my': '大马简体',
			'zh-sg': '新加坡简体',
			'zh-hant': '繁體',
			'zh-hk': '香港繁體',
			'zh-mo': '澳門繁體',
			'zh-tw': '臺灣正體',
		}
		let result = {};

		var api = new mw.Api();
		var zhwpapi;
		if (mw.config.get('wgDBname') === 'zhwiki') {
			var zhwpapi = new mw.Api();
		} else {
			var zhwpapi = new mw.ForeignApi('//zh.wikipedia.org/w/api.php');
		}
		var basepagetext = '';
		let table = $('<div id="TranslateVariants">').prependTo('#bodyContent');

		let submitall = $('<button>發佈所有變更</button>');
		submitall.on('click', function() {
			let buttons = $('.TranslateVariants-publish-changes');
			if (buttons.length === 0) {
				mw.notify('沒有任何變更可發佈', { type: 'error' });
				return;
			}
			if (!confirm('發佈 ' + buttons.length + ' 個變更?')) {
				mw.notify('已取消發佈', { type: 'warn' });
				return;
			}
			buttons.each(function(_, button) {
				$(button).click();
			});
		});
		table.append($('<div style="text-align: right;">').append(submitall));

		$('<div style="color:red">提醒:TranslateVariants工具使用IT及MediaWiki兩個轉換組進行自動轉換,請確認轉換結果是否正確!</div>').appendTo(table);

		var defaultlangs = 'zh,zh-hans,zh-cn,zh-my,zh-sg,zh-hant,zh-hk,zh-mo,zh-tw';
		var runlangs = prompt('轉換以下語言(以逗號隔開):', defaultlangs);
		if (runlangs === null) {
			runlangs = defaultlangs;
		}

		var langqueue = runlangs.split(',').map(function(lang) {
			return lang.trim()
		}).filter(function(lang) {
			return langs.indexOf(lang) !== -1
		});

		let text;
		if ($('#wpTextbox1').length === 1) {
			text = $('#wpTextbox1').val();
		} else {
			let data = await api.get({
				action: 'query',
				prop: 'revisions',
				rvprop: ['content', 'timestamp'],
				titles: [mw.config.get('wgPageName')],
				formatversion: '2',
				curtimestamp: true,
			});
			if (!data.query || !data.query.pages) {
				alert('unknown error');
				return;
			}
			let page = data.query.pages[0];
			if (!page || page.invalid) {
				alert('invalidtitle');
				return;
			}
			if (page.missing) {
				alert('nocreate-missing');
				return;
			}
			let revision = page.revisions[0];
			text = revision.content;
		}
		result['zh'] = text;

		text = text.replace(/[[\]{}<>|:*'_#&\s]/gim, function(s) {
			return "&#" + s.charCodeAt(0) + ";";
		});
		text = text.replace(/(&#91;&#91;)((?:(?!&#124;)(?!&#93;).)+?)(&#124;(?:(?!&#93;).)+?&#93;&#93;)/g, '$1-{$2}-$3');
		text = text.replace(/-&#123;(.*?)&#125;-/g, function(s) {
			return s
				.replace('-&#123;', '-{')
				.replace('&#125;-', '}-')
				.replace(/&#124;/g, '|')
				.replace(/&#32;/g, ' ')
				.replace(/&#61;/g, '=')
				.replace(/&#62;/g, '>')
				.replace(/&#58;/g, ':')
		});
		basepagetext = text;

		process();

		function process() {
			if (langqueue.length === 0) {
				return;
			}

			var lang = langqueue.shift();
			var diffTable = $('<div id="TranslateVariants-diff-' + lang + '">').appendTo(table);
			$('<hr>').appendTo(table);

			const basename = mw.config.get('wgPageName').replace(/\/zh$/, '');
			var targetTitle;
			if (lang == 'zh') {
				targetTitle = basename + '';
			} else {
				targetTitle = basename + '/' + lang;
			}

			var newtext;

			zhwpapi.parse(
				'{{NoteTA|G1=IT|G2=MediaWiki}}<div id="TVcontent">' + basepagetext + '</div>',
				{
					'uselang': lang,
					'prop': 'text',
				}
			).then(function(data) {
				newtext = $('<div/>').html(data).find('#TVcontent').text();

				return api.post({
					action: 'query',
					prop: 'revisions',
					titles: [targetTitle],
					rvdifftotext: newtext,
					formatversion: '2',
				});
			}, function(err) {
				mw.notify('解析' + lang + '時發生錯誤:' + err);
			}).then(function(data) {
				let tool = $('<div><a href="' + mw.util.getUrl(targetTitle) + '">' + lang + '(' + langname[lang] + ')</a>(<a href="' + mw.util.getUrl(targetTitle, { action: 'edit' }) + '">編</a>)</div>').appendTo(diffTable);
				let page = data.query.pages[0];
				if (page.missing) {
					let submit = $('<button style="float: right;">發佈頁面</button>').appendTo(tool);
					submit.on('click', function() {
						this.remove();
						api.create(
							targetTitle,
							{ summary: TranslateVariants.summary.replace(/\$1/g, mw.config.get('wgPageName')) },
							newtext
						).then(function() {
							mw.notify('已編輯 ' + targetTitle);
						}, function(e) {
							mw.notify('編輯 ' + targetTitle + ' 發生錯誤:' + e);
						});
					});
					$('<pre>').html(newtext.replace(/[<>&]/gim, function(s) {
						return "&#" + s.charCodeAt(0) + ";";
					})).appendTo(diffTable);
					return;
				}
				let diff = page.revisions[0].diff.body;
				if (diff == '') {
					$('<span style="float: right;">無變更</span>').appendTo(tool);
				} else {
					let submit = $('<button class="TranslateVariants-publish-changes" style="float: right;">發佈變更</button>').appendTo(tool);
					submit.on('click', function() {
						this.remove();
						api.edit(
							targetTitle,
							function() {
								return {
									text: newtext,
									summary: TranslateVariants.summary.replace(/\$1/g, mw.config.get('wgPageName')),
									nocreate: false,
								};
							}
						).then(function() {
							mw.notify('已編輯 ' + targetTitle);
						}, function(e) {
							mw.notify('編輯 ' + targetTitle + ' 發生錯誤:' + e);
						});
					});
					$('<table class="diff">').html(diff).prepend('<colgroup><col class="diff-marker"><col class="diff-content"><col class="diff-marker"><col class="diff-content"></colgroup>').appendTo(diffTable);
				}
			}, function(err) {
				mw.notify('取得' + lang + '差異時發生錯誤:' + err);
			}).always(function() {
				process();
			});
		}
	}

})();
// </nowiki>