User:SunAfterRain/js/ForkAPage.js

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

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

/* eslint-disable mediawiki/msg-doc, no-alert */
/**
 * Fork a Page https://ja.wikipedia.org/wiki/Help:ページ複製ガジェット
 * Cover from https://ja.wikipedia.org/w/index.php?title=MediaWiki:Gadget-ForkAPage.js&oldid=56796804
 *
 * Author: https://ja.wikipedia.org/wiki/青子守歌
 *
 * 使用說明請見 https://zh.wikipedia.org/wiki/User:SunAfterRain/ForkAPage
 **/
// eslint-disable-next-line spaced-comment
/// <reference types="jqueryui" />

$.when(
	mw.loader.getState( "ext.gadget.HanAssist" )
		? mw.loader.using( [ "jquery.ui", "ext.gadget.HanAssist" ] )
		: new Promise( ( resolve, reject ) => {
			const hook = mw.hook( "userscript.SunAfterRain.HanAssist.ready" );
			function hookCallback( HanAssist ) {
				hook.remove( hookCallback );
				mw.loader.using( [ "jquery.ui" ] )
					.then( ( origRequire ) => resolve(
						( module ) => module === "ext.gadget.HanAssist"
							? HanAssist
							: origRequire( module )
					) );
			}
			hook.add( hookCallback );
		} ),
	$.ready
).then( function ( require ) {
	if ( mw.config.get( "wgNamespaceNumber" ) < 0 ) {
		return;
	}

	var prefix = "forkapage-";
	
	const batchLocalize = require( "ext.gadget.HanAssist" ).batchConv || mw.libs.HanAssist.parse;
	var messeges = batchLocalize( {
		"tab-label": { hans: "复制", hant: "複製" },
		"tab-tooltip": { hans: "复制本页", hant: "複製本頁" },
		"dialog-title": { hans: "复制页面", hant: "複製頁面" },
		"dialog-header": { hans: "复制目标页设置", hant: "複製目標頁面設定" },
		"dialog-forkto": { hans: "复制目标页面名:", hant: "複製目標頁面名:" },
		"dialog-reason": { hans: "复制理由:", hant: "複製理由:" },
		"dialog-fork": { hans: "复制", hant: "複製" },
		"dialog-error": { hans: "发生未知错误。", hant: "發生未知錯誤。" },
		"dialog-close": { hans: "关闭", hant: "關閉" },
		"override-header": { hans: "确认覆盖", hant: "確認覆蓋" },
		"override-exists": { hans: "复制目标页“$1”已存在。", hant: "複製頁面「$1」已存在。" },
		"override-time": { hans: "最后编辑时间", hant: "最後編輯時間" },
		"override-user": { hans: "最后编辑用户", hant: "最後編輯用戶" },
		"override-ask": { hans: "要覆盖么?", hant: "要覆寫嗎?" },
		"override-yes": { hans: "覆盖", hant: "覆寫" },
		"override-no": { hans: "取消", hant: "取消" },
		"query-error": { hans: "查询页面内容时发生错误:$1", hant: "查詢頁面內容時發生錯誤:$1" },
		"edit-header": { hans: "编辑中", hant: "編輯中" },
		"edit-move": { hans: "编辑完毕,将在5秒后自动跳转到复制目标页“$1”。", hant: "編輯完畢,將在5秒後自動跳轉到複製目標頁「$1」。" },
		"edit-error": { hans: "编辑时发生错误:$2($1)", hant: "編輯時發生錯誤:$2($1)" },
		"edit-unknown": { hans: "编辑时发生未知错误。", hant: "編輯時發生未知錯誤。" },
		"edit-summary": "複製自[[$1]]的版本[[Special:PermaLink/$2|$2]]:$3 ([[User:SunAfterRain/ForkAPage|FAP]]|[[User:SunAfterRain/ForkAPage.js|source]])"
	} );

	Object.keys( messeges ).forEach( function ( key ) {
		mw.messages.set( prefix + key, messeges[ key ] );
	} );

	var Api = new mw.Api();

	/**
	 * @param {string} title
	 * @return {JQuery.Promise<import('mwn').ApiPage>}
	 * @throws {Error} Api Error.
	 * @throws {ReferenceError} Page didn't exist.
	 */
	function queryPage( title ) {
		var deferred = $.Deferred();

		Api.get( {
			action: "query",
			titles: title,
			prop: "revisions",
			rvprop: "timestamp|content|user|ids",
			rvslots: "main",
			indexpageids: true
		} ).then( function ( result ) {
			if (
				!result ||
				!result.query ||
				!result.query.pages ||
				!result.query.pageids
			) {
				mw.log.error( "[FORKAPAGE] Query page \"" + title + "\" fail.", result );

				deferred.reject( new Error( "ApiError." ) );
				return;
			}

			/**
			 * @type {import('mwn').ApiPage}
			 */
			var page = result.query.pages instanceof Array ?
				result.query.pages[ 0 ] :
				result.query.pages[ result.query.pageids[ 0 ] ];

			if ( !page || Object.prototype.hasOwnProperty.call( page, "missing" ) ) {
				deferred.reject( new ReferenceError( "Page didn't exist." ) );
				return;
			} else {
				deferred.resolve( page );
			}
		}, function ( err ) {
			deferred.reject( err );
		} );

		return deferred;
	}

	$( mw.util.addPortletLink(
		"p-cactions",
		"#",
		mw.msg( prefix + "tab-label" ),
		"ca-fork",
		mw.msg( prefix + "tab-tooltip" ),
		null,
		window.ForkAPagePortletLinkTop ? "#ca-move" : null
	) ).on( "click", function ( e ) {
		e.preventDefault();

		var $dialog = $( "<div>" )
			.attr( {
				id: "dialog",
				title: mw.msg( prefix + "dialog-title" )
			} )
			.append( $( "<h2>" ).text( mw.msg( prefix + "dialog-header" ) ) )
			.append( $( "<form>" )
				.append( $( "<div>" )
					.append( $( "<label>" )
						.attr( "for", "forkto" )
						.text( mw.msg( prefix + "dialog-forkto" ) )
					)
					.append( $( "<input>" )
						.attr( {
							id: "forkto",
							type: "text"
						} )
						.val( mw.config.get( "wgPageName" ) )
					)
				)
				.append( $( "<div>" )
					.append( $( "<label>" )
						.attr( "for", "reason" )
						.text( mw.msg( prefix + "dialog-reason" ) )
					)
					.append( $( "<input>" )
						.attr( {
							id: "reason",
							type: "text"
						} )
					)
				)
			)
			.dialog( {
				minHeight: window.ForkAPageDiaLogHeight || 100,
				width: "auto",
				modal: true,
				// 按紐
				buttons: [ {
					text: mw.msg( prefix + "dialog-fork" ),
					// 點擊時
					click: function () {
						var forkToTitle = $dialog.find( "#forkto" ).val();

						function showCloseButton() {
							$dialog.dialog( {
								buttons: [
									{
										text: mw.msg( prefix + "dialog-close" ),
										click: function () {
											$dialog.dialog( "close" );
										}
									}
								]
							} );
						}

						function editPage() {
							$dialog.dialog( {
								buttons: []
							} );

							queryPage( mw.config.get( "wgPageName" ) ).then( function ( page ) {
								var lastRevision = page.revisions[ 0 ];

								Api.postWithEditToken( {
									action: "edit",
									title: forkToTitle,
									assert: "user",
									summary: mw.msg( prefix + "edit-summary", mw.config.get( "wgPageName" ), lastRevision.revid, $dialog.find( "#reason" ).val() ),
									text: lastRevision.slots.main.content || lastRevision.slots.main[ "*" ]
								} ).then( function ( result ) {
									if ( result && result.edit && result.edit.result === "Success" ) {
										$dialog
											.append( $( "<h2>" ).text( mw.msg( prefix + "edit-header" ) ) )
											.append( $( "<p>" ).text( mw.msg( prefix + "edit-move", forkToTitle ) ) );

										setTimeout( function () {
											window.location.href = mw.util.getUrl( forkToTitle );
										}, 5000 );
									} else {
										mw.log.error( "[FORKAPAGE] Edit \"" + forkToTitle + "\" fail.", result );
										alert( mw.msg( prefix + "edit-unknown" ) );

										showCloseButton();
									}
								}, function ( err ) {
									mw.log.error( "[FORKAPAGE] Edit \"" + forkToTitle + "\" fail.", err );
									if ( err && err.error ) {
										alert( mw.msg( prefix + "edit-error", err.error.code, err.error.info ) );
									} else {
										alert( mw.msg( prefix + "edit-unknown" ) );
									}

									showCloseButton();
								} );
							}, function ( err ) {
								if ( err instanceof Error ) {
									alert( mw.msg( prefix + "query-error", err.message ) );
								} else {
									mw.log.error( "[FORKAPAGE] Error", err );

									alert( mw.msg( prefix + "dialog-error" ) );
								}
								showCloseButton();
							} );
						}

						queryPage( forkToTitle ).then( function ( page ) {
							var lastRevision = page.revisions[ 0 ];

							$dialog.append( $( "<h2>" ).text( mw.msg( prefix + "override-header" ) ) )
								.append( $( "<p>" ).text( mw.msg( prefix + "override-exists", forkToTitle ) ) )
								.append(
									$( "<dl>" )
										.append( $( "<dt>" ).text( mw.msg( prefix + "override-time" ) ) )
										.append( $( "<dd>" ).text( lastRevision.timestamp ) )
										.append( $( "<dt>" ).text( mw.msg( prefix + "override-user" ) ) )
										.append( $( "<dd>" ).text( lastRevision.user ) )
										.append( $( "<p>" ).text( mw.msg( prefix + "override-ask" ) ) )
								);

							$dialog.dialog( {
								buttons: [
									{
										text: mw.msg( prefix + "override-yes" ),
										click: function () {
											editPage();
										}
									},
									{
										text: mw.msg( prefix + "override-no" ),
										click: function () {
											$dialog.dialog( "close" );
										}
									}
								]
							} );
						}, function ( err ) {
							if ( err instanceof ReferenceError ) {
								editPage();
								return;
							} else if ( err instanceof Error ) {
								alert( mw.msg( prefix + "query-error", err.message ) );
							} else {
								mw.log.error( "[FORKAPAGE] Error", err );

								alert( mw.msg( prefix + "dialog-error" ) );
							}

							showCloseButton();
						} );
					}
				} ]
			} );
	} );
} );