LLWiki正在建设中,欢迎加入我们

MediaWiki:Gadget-Wikiplus.js

来自LLWiki
跳转到导航 跳转到搜索

注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:前往菜单 → 设置(Mac为Opera → Preferences),然后隐私和安全 → 清除浏览数据 → 缓存的图片和文件
//<nowiki>
/* global mw */
/**
* @Name: Wikiplus
* @Author: +Eridanus Sora/@妹空酱
* @Github: [https://github.com/Last-Order/Wikiplus]
*/
/**
* @Dependency: MoeNotification
* @Source: [https://github.com/Last-Order/MoeNotification]
*/
"use strict";
const api = new mw.Api();

var _createClass = (function () {
	function defineProperties(target, props) {
		for (var i = 0; i < props.length; i++) {
			var descriptor = props[i];
			descriptor.enumerable = descriptor.enumerable || false;
			descriptor.configurable = true;
			if ('value' in descriptor) { descriptor.writable = true; }
			Object.defineProperty(target, descriptor.key, descriptor);
		}
	}
	return function (Constructor, protoProps, staticProps) {
		if (protoProps) { defineProperties(Constructor.prototype, protoProps); }
		if (staticProps) { defineProperties(Constructor, staticProps); }
		return Constructor;
	};
})();

function _classCallCheck(instance, Constructor) {
	if (!(instance instanceof Constructor)) {
		throw new TypeError('Cannot call a class as a function');
	}
}

function MoeNotification() {
	var self = this;
	this.display = function () {
		var text = arguments.length <= 0 || arguments[0] === undefined ? '喵~' : arguments[0];
		var type = arguments.length <= 1 || arguments[1] === undefined ? 'success' : arguments[1];
		var callback = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2];

		$("#MoeNotification").append($("<div>").addClass('MoeNotification-notice').addClass('MoeNotification-notice-' + type).append('<span>' + text + '</span>'));
		$("#MoeNotification").find('.MoeNotification-notice').last().fadeIn(300);
		self.bind();
		self.clear();
		callback($("#MoeNotification").find('.MoeNotification-notice').last());
	};
	this.create = {
		success: function success(text, callback) {
			var _callback = callback || function () {};
			self.display(text, 'success', _callback);
		},
		warning: function warning(text, callback) {
			var _callback = callback || function () {};
			self.display(text, 'warning', _callback);
		},
		error: function error(text, callback) {
			var _callback = callback || function () {};
			self.display(text, 'error', _callback);
		}
	};
	this.clear = function () {
		if ($(".MoeNotification-notice").length >= 10) {
			$("#MoeNotification").children().first().fadeOut(150, function () {
				$(this).remove();
			});
			setTimeout(self.clear, 300);
		} else {
			return false;
		}
	};
	this.empty = function (f) {
		$(".MoeNotification-notice").each(function (i) {
			if ($.isFunction(f)) {
				var object = this;
				setTimeout(function () {
					f($(object));
				}, 200 * i);
			} else {
				$(this).delay(i * 200).fadeOut('fast', function () {
					$(this).remove();
				});
			}
		});
	};
	this.bind = function () {
		$(".MoeNotification-notice").mouseover(function () {
			self.slideLeft($(this));
		});
	};
	this.slideLeft = function (object, speed) {
		object.css('position', 'relative');
		object.animate({
			left: "-200%"
		}, speed || 150, function () {
			$(this).fadeOut('fast', function () {
				$(this).remove();
			});
		});
	};
	this.init = function () {
		$("body").append('<div id="MoeNotification"></div>');
	};
	if ($("#MoeNotification").length === 0) {
		this.init();
	}
}

$(function () {
	/**
	 * 多语言转换
	 * @param {string} key 字段标识名
	 * @return {string} 经过转换的内容
	 */
	function i18n(key) { return mw.msg( 'wikiplus-' + key ); }
	/**
	 * 获得错误信息
	 * @param {string} name
	 * @return {object} {number, message}
	 */
	function getErrorInfo(name) {
		const message = i18n( name );
		if (message != '⧼wikiplus-' + name + '⧽') {
			return {
				name: name,
				message: message
			};
		}
		return {
			name: 'unknown_error_name',
			message: i18n( 'unknown_error_name' )
		};
	}
	/** 
	 * 抛出错误
	 * @param {string} name
	 * @return boolean
	*/
	function throwError(name, message) {
		var errInfo = getErrorInfo(name);
		var e = new Error();
		e.message = message || errInfo.message;
		console.log('%c致命错误:' + e.message, 'color:red');
		console.log(e);
		return e;
	}
	/**
	 * 将mw的段落的id转换为可显示的文本
	 * @param {string} URL
	 * @return string
	 */

	const wgUserGroups = mw.config.get('wgUserGroups');
	var Wikipage = (function () {
		function Wikipage() {
			var pageName = arguments.length <= 0 || arguments[0] === undefined ? mw.config.get('wgPageName') : arguments[0];

			_classCallCheck(this, Wikipage);

			console.log('页面类构建中');
			//可用性和权限检测
			if (!(wgUserGroups.includes( 'autoconfirmed' ) || wgUserGroups.includes( 'confirmed' ) || wgUserGroups.includes( 'sysop' ))) {
				throwError('not_autoconfirmed_user');
				return;
			}
			//从MediaWiki定义的全局变量中获得信息
			this.pageName = pageName.replace(/ /ig, '_'); // Mediawiki处理空格时可能会出错
			this.revisionId = mw.config.get('wgRevisionId');
			this.articleId = mw.config.get('wgArticleId');
			//从API获得编辑令牌和起始时间戳
			this.timestamp = {};
			this.init(this.pageName, {
				success: function success() {
					console.log('Wikiplus加载完毕');
				},
				fail: function fail(e) {
					console.log('Wikiplus未能正确加载(' + e.message + ')');
				}
			});
		}

		/**
		 * 针对非本页面的编辑 提供重定义时间戳和权标接口
		 * @param {string} titile 标题
		 * @param {object} callback 回调函数
		 */

		_createClass(Wikipage, [{
			key: 'reConstruct',
			value: function reConstruct(title) {
				var callback = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

				this.init(title, callback);
			}

			/**
			 * 获取页面基础信息并记录
			 */
		}, {
			key: 'init',
			value: function init(title, callback) {
				if (title === undefined) { title = this.pageName; }
				if (callback === undefined) { callback = {}; }

				var self = this;
				callback.success = callback.success || function() {};
				callback.fail = callback.success || function() {};
				console.time('获得页面基础信息时间耗时');
				api.get({ action: 'query', prop: 'info', titles: title, curtimestamp: 1, formatversion: 2 })
					.then(function(data) {
					if (data && data.query && data.query.pages) {
						var info = data.query.pages[0];
						if (info.pageid) {
							if (info.lastrevid) {
								self.timestamp[title] = data.curtimestamp;
							} else {
								callback.fail(throwError('fail_to_get_timestamp'));
							}
						} else {
							if (mw.config.get('wgArticleId') !== 0) {
								// 如果不是 那就是失败了 抛出错误
								self.inited = false;
								callback.fail(throwError('fail_to_get_pageinfo'));
							}
						}
					}
					console.timeEnd('获得页面基础信息时间耗时');
					self.inited = self.inited === false ? false : true;
					callback.success();
				});
			}

			/**
			 * 页面编辑
			 * @param {string} content 页面内容
			 * @param {string} title  页面标题 默认为当前页面标题
			 * @param {object} callback 回调函数
			 * @param {object} config 设置 覆盖到默认的设置
			 */
		}, {
			key: 'edit',
			value: function edit(content) {
				var title = arguments.length <= 1 || arguments[1] === undefined ? this.pageName : arguments[1];
				var callback = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
				var config = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];

				var self = this;
				callback.success = callback.success || function() {};
				callback.fail = callback.fail || function() {};
				if (content === undefined) {
					if (!config.empty) {
						callback.fail(throwError('empty_page_confirm'));
						return false;
					}
				}
				if (self.inited) {
					var param = $.extend({ action: 'edit', text: content, title: title,
						baserevid: mw.config.get('wgCurRevisionId')
					}, config);
					api.postWithEditToken( param ).then(function(data) {
						if (data && data.edit) {
							if (data.edit.result && data.edit.result == 'Success') {
								callback.success();
							} else {
								if (data.edit.code) {
									//防滥用过滤器
									callback.fail(throwError('hit_abusefilter', i18n('hit_abusefilter') + ':' + data.edit.info.replace('/Hit AbuseFilter: /ig', '') + '<br><small>' + data.edit.warning + '</small>'));
								} else {
									callback.fail(throwError('unknown_edit_error'));
								}
							}
						} else if (data && data.error && data.error.code) {
							callback.fail(throwError(data.error.code.replace(/-/ig, '_')), i18n('unknown_edit_error_message').replace(/\$1/ig, data.error.code));
						} else if (data.code) {
							callback.fail(throwError('unknown_edit_error'), i18n('unknown_edit_error_message').replace(/\$1/ig, data.code));
						} else {
							callback.fail(throwError('unknown_edit_error'));
						}
					}, function() {
						console.log("以下是本次出错的参数");
						console.log(param);
						callback.fail(throwError('network_edit_error'));
					});
				} else {
					callback.fail(throwError('uninited'));
				}
			}

			/**
			 * 编辑段落
			 * @param {number} section 段落编号
			 * @param {string} content 内容
			 * @param {string} title 页面标题
			 * @param {object} callback 回调函数 
			 * @param {object} config 设置 
			 */
		}, {
			key: 'editSection',
			value: function editSection(section, content) {
				var title = arguments.length <= 2 || arguments[2] === undefined ? this.pageName : arguments[2];
				var config = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
				var callback = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];

				callback.success = callback.success || function() {};
				callback.fail = callback.fail || function() {};
				this.edit(content, title, callback, $.extend({
					'section': section
				}, config));
			}

			/**
			 * 获得页面维基文本
			 * @param {object} callback 回调函数
			 * @param {string} title 页面标题 默认为当前页面
			 * @param {object} config 设置
			 */
		}, {
			key: 'getWikiText',
			value: function getWikiText() {
				var callback = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
				var title = arguments.length <= 1 || arguments[1] === undefined ? this.pageName : arguments[1];
				var config = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

				callback.success = callback.success || function() {};
				callback.fail = callback.fail || function() {};
				console.time('获得页面文本耗时');
				api.get($.extend({
					action: 'query',
					prop: 'revisions',
					rvprop: 'content',
					rvslots: 'main',
					rvlimit: 1,
					titles: title,
					formatversion: 2
				}, config)).then(function(data) {
					console.timeEnd('获得页面文本耗时');
					callback.success( data.query.pages[0].revisions[0].slots.main.content );
				}, function() {
					console.log('title: ' + title);
					callback.fail(throwError('fail_to_get_wikitext'));
				});
			}

			/**
			 * 解析Wikitext
			 * @param {string} wikitext 维基文本
			 * @param {object} callback 回调函数
			 * @param {object} config 设置
			 */
		}, {
			key: 'parseWikiText',
			value: function parseWikiText(wikitext, callback, config) {
				if (wikitext === undefined) { wikitext = ''; }
				if (callback === undefined) { callback = {}; }

				callback.success = callback.success || function() {};
				callback.fail = callback.fail || function() {};
				api.post($.extend( {
					action: 'parse',
					text: wikitext,
					title: this.pageName,
					pst: 1,
					formatversion: 2,
					prop: 'text',
					disablelimitreport: 1,
					disabletoc: 1,
					disableeditsection: 1,
					wrapoutputclass:'mw-parser-output content'
				}, config, mw.config.get('wgNamespaceNumber') == 10 && this.isTop ? {
					templatesandboxtitle: this.pageName,
					templatesandboxtext: wikitext
				} : {} )).then(function(data) {
					if (data && data.parse && data.parse.text) {
						callback.success(data.parse.text);
					} else {
						callback.fail(throwError('cant_parse_wikitext'));
					}
				});
			}
		}]);

		return Wikipage;
	})();

	$(document).ready(function () {
		var Wikiplus = (function () {
			_createClass(Wikiplus, [{
				key: 'initQuickEdit',

				/**
				 * 加载快速编辑 第一步 插入页面按钮并绑定入口事件
				 */
				value: function initQuickEdit() {
					var callback = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

					var self = this;
					callback.success = callback.success || function() {};
					callback.fail = callback.fail || function() {};
					if (!(mw.config.get('wgIsArticle') && mw.config.get('wgAction') === "view" && mw.config.get('wgIsProbablyEditable'))) {
						console.log('该页面无法编辑 快速编辑界面加载终止');
						return;
					}
					//顶部编辑入口
					var topBtn = $('<li>').attr('id', 'Wikiplus-Edit-TopBtn');
					if(mw.config.get('skin') == 'vector') {
						topBtn.append($('<span>').append($('<a>').attr('href', '#').text('' + i18n('quickedit_topbtn')))).data({
							number: -1,
							target: self.kotori.pageName
						});
						if ($('#ca-edit').length > 0 && $('#Wikiplus-Edit-TopBtn').length === 0) {
							topBtn.insertBefore( '#ca-edit' ).addClass( 'collapsible' );
							$(window).resize();
						}
					}
					else {
						topBtn.addClass("page-actions-menu__list-item")
							.data({
								number: -1,
								target: self.kotori.pageName
							})
							.append( $('<a>').attr('href', '#').append('<i class="fa fa-bolt"></i>') );
						$('#page-actions-edit').before(topBtn);
					}
					if ($('.mw-editsection').length > 0 && mw.config.get('wgPageContentModel') == 'wikitext') {
						self.sectionMap = {};
						//段落快速编辑按钮
						var sectionBtn = $('<span>').append($('<span>').addClass('mw-editsection-divider').text(' | ')).append($('<a>').addClass('Wikiplus-Edit-SectionBtn').attr('href', '#').text(i18n('quickedit_sectionbtn')));
						$('.mw-editsection').each(function() {
							try {
								var editURL = $(this).find("a").last().attr('href') ||
									 '/zh?action=submit&title=' + mw.config.get('wgPageName') + '&section=' + $(this).children('a').data('section');
								var sectionNumber = editURL.match(/&[ve]*section\=([^&]+)/)[1];
								var istranscluded = /T-/.test(sectionNumber);
								sectionNumber = sectionNumber.replace(/T-/ig, '');
								var sectionTargetName = decodeURIComponent(editURL.match(/title=(.+?)&/)[1]);
								var cloneNode = $(this).prev().clone();
								cloneNode.find('.mw-headline-number').remove();
								var sectionName = $.trim(cloneNode.text());
								self.sectionMap[sectionNumber] = {
									name: sectionName,
									target: sectionTargetName
								};
								var _sectionBtn = sectionBtn.clone();
								_sectionBtn.find('.Wikiplus-Edit-SectionBtn').data({
									number: sectionNumber,
									name: sectionName,
									target: sectionTargetName
								});
								if(mw.config.get('skin') == 'vector') {
									$(this).find('.mw-editsection-bracket').last().before(_sectionBtn);
								}
								else if(!istranscluded) {
									var mobileSectionBtn = _sectionBtn.find('.Wikiplus-Edit-SectionBtn')
										.text("").removeAttr( 'href' )
										.append('<i class="fa fa-bolt"></i>');
									$(this).children('a').before(mobileSectionBtn);
								}
							} catch (e) {
								throwError('fail_to_init_quickedit');
							}
						});
					}
					$('.Wikiplus-Edit-SectionBtn').click(function (e) {
						e.preventDefault();
						self.kotori.isTop = false;
						self.initQuickEditInterface($(this)); //直接把DOM传递给下一步
					});
					$('#Wikiplus-Edit-TopBtn').click(function (e) {
						e.preventDefault();
						self.kotori.isTop = true;
						self.initQuickEditInterface($(this));
					});
				}

				/**
				 * 加载快速编辑主界面相关内容
				 */
			}, {
				key: 'initQuickEditInterface',
				value: function initQuickEditInterface(obj) {
					var self = this;
					var sectionNumber = obj.data('number');
					var sectionTargetName = obj.data('target');
					if (this.kotori.inited) {
						if ($('.noarticletext').length > 0) {
							//这是一个空页面
							this.preloadData[sectionTargetName + '.-1'] = i18n('create_page_tip');
						}
						if (mw.config.get('wgCurRevisionId') === mw.config.get('wgRevisionId')) {
							if (this.preloadData[sectionTargetName + '.' + sectionNumber] === undefined) {
								this.notice.create.success(i18n('loading'));
								this.preload(sectionNumber, sectionTargetName, {
									success: function success(data) {
										obj.data('content', data);
										self.notice.empty();
										self.displayQuickEditInterface(obj);
									},
									fail: function fail() {
										throwError('fail_to_get_wikitext_when_edit');
									}
								});
							} else {
								obj.data('content', self.preloadData[sectionTargetName + '.' + sectionNumber]);
								self.displayQuickEditInterface(obj);
							}
						} else {
							this.notice.create.warning(i18n('history_edit_warning'));
							this.notice.create.success(i18n('loading'));
							this.preload(sectionNumber, sectionTargetName, {
								success: function success(data) {
									obj.data('content', data);
									self.notice.empty();
									self.displayQuickEditInterface(obj, '' + i18n('history_edit_warning'));
								},
								fail: function fail() {
									throwError('fail_to_get_wikitext_when_edit');
								}
							}, {
								rvstartid: mw.config.get('wgRevisionId')
							});
						}
					}
				}

				/**
				 * 显示快速编辑界面并绑定事件
				 */
			}, {
				key: 'displayQuickEditInterface',
				value: function displayQuickEditInterface(obj) {
					var message = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];

					var self = this;
					var isNewPage = $('.noarticletext').length > 0;
					var sectionNumber = obj.data('number');
					var sectionName = obj.data('name');
					var sectionTargetName = obj.data('target');
					var sectionContent = obj.data('content');
					var summary = self.getSetting('defaultSummary', {
						'sectionName': sectionName,
						'sectionNumber': sectionNumber,
						'sectionTargetName': sectionTargetName
					});
					if (summary === undefined) {
						if (sectionName === undefined) {
							summary = i18n('default_summary_suffix');
						} else {
							summary = '/* ' + sectionName + ' */ ' + i18n('default_summary_suffix');
						}
					}
					//DOM定义
					var heightBefore = $(document).scrollTop(); //记住当前高度
					var backBtn = $('<span>').attr('id', 'Wikiplus-Quickedit-Back').addClass('Wikiplus-Btn').text('' + i18n('back')); //返回按钮
					var jumpBtn = $('<span>').attr('id', 'Wikiplus-Quickedit-Jump').addClass('Wikiplus-Btn').append($('<a>').attr('href', '#Wikiplus-Quickedit').text('' + i18n('goto_editbox'))); //到编辑框
					var inputBox = $('<textarea>').attr('id', 'Wikiplus-Quickedit'); //主编辑框
					var previewBox = $('<div>').attr('id', 'Wikiplus-Quickedit-Preview-Output'); //预览输出
					var summaryBox = $('<input>').attr('id', 'Wikiplus-Quickedit-Summary-Input').attr('placeholder', '' + i18n('summary_placehold')); //编辑摘要输入
					var editSubmitBtn = $('<button>').attr('id', 'Wikiplus-Quickedit-Submit').text(i18n(isNewPage ? 'publish_page' : 'publish_change') + '(Ctrl+S)'); //提交按钮
					var previewSubmitBtn = $('<button>').attr('id', 'Wikiplus-Quickedit-Preview-Submit').text('' + i18n('preview')); //预览按钮
					var isMinorEdit = $('<div>').append($('<input>').attr({ 'type': 'checkbox', 'id': 'Wikiplus-Quickedit-MinorEdit' })).append($('<label>').attr('for', 'Wikiplus-Quickedit-MinorEdit').text(i18n('mark_minoredit') + '(Ctrl+Shift+S)')).css({ 'margin': '5px 5px 5px -3px', 'display': 'inline' });
					//DOM定义结束
					var editBody = $('<div>').append(backBtn, jumpBtn, previewBox, inputBox, summaryBox, isMinorEdit, editSubmitBtn, previewSubmitBtn);
					this.createDialogBox('' + i18n('quickedit_topbtn') + message, editBody, 1000, function () {
						$('#Wikiplus-Quickedit').text(sectionContent);
						$('#Wikiplus-Quickedit-Summary-Input').val(summary);
						mw.hook( 'wikiplus.dialog' ).fire();
						//事件绑定
						//返回
						$("#Wikiplus-Quickedit-Back").click(function () {
							$('.Wikiplus-InterBox').fadeOut('fast', function () {
								window.onclose = window.onbeforeunload = undefined; //取消页面关闭确认
								$(this).remove();
							});
						});
						//预览
						var onPreload = $('<div>').addClass('Wikiplus-Banner').text('' + i18n('loading_preview'));
						$('#Wikiplus-Quickedit-Preview-Submit').click(function () {
							var wikiText = $('#Wikiplus-Quickedit').val();
							$(this).attr('disabled', 'disabled');
							$('#Wikiplus-Quickedit-Preview-Output').fadeOut(100, function () {
								$('#Wikiplus-Quickedit-Preview-Output').html('').append(onPreload);
								$('#Wikiplus-Quickedit-Preview-Output').fadeIn(100);
							});
							$('html, body').animate({ scrollTop: heightBefore }, 200); //返回顶部
							self.kotori.parseWikiText(wikiText, {
								success: function success(data) {
									$('#Wikiplus-Quickedit-Preview-Output').fadeOut('100', function () {
										$('#Wikiplus-Quickedit-Preview-Output').html('<hr><div id="mw-content-text">' + data + '</div><hr>');
										mw.hook( 'wikipage.content' ).fire( $('#Wikiplus-Quickedit-Preview-Output > div') );
										$('#Wikiplus-Quickedit-Preview-Output').fadeIn('100');
										$('#Wikiplus-Quickedit-Preview-Submit').prop('disabled', false);
									});
								}
							});
						});
						//提交
						$('#Wikiplus-Quickedit-Submit').click(function () {
							var wikiText = $('#Wikiplus-Quickedit').val();
							var summary = $('#Wikiplus-Quickedit-Summary-Input').val();
							var timer = new Date().valueOf();
							var onEdit = $('<div>').addClass('Wikiplus-Banner').text('' + i18n('submitting_edit'));
							var addtionalConfig = {
								'summary': summary
							};
							if (sectionNumber !== -1) {
								addtionalConfig.section = sectionNumber;
							}
							if ($('#Wikiplus-Quickedit-MinorEdit').is(':checked')) {
								addtionalConfig.minor = 'true';
							} else {
								addtionalConfig.notminor = 'true';
							}
							//准备编辑 禁用各类按钮 返回顶部 显示信息
							$('#Wikiplus-Quickedit-Submit,#Wikiplus-Quickedit,#Wikiplus-Quickedit-Preview-Submit').attr('disabled', 'disabled');
							$('html, body').animate({ scrollTop: heightBefore }, 200);

							//开始提交编辑
							if (sectionTargetName === self.kotori.pageName) {
								$('#Wikiplus-Quickedit-Preview-Output').fadeOut(100, function () {
									$('#Wikiplus-Quickedit-Preview-Output').html('').append(onEdit);
									$('#Wikiplus-Quickedit-Preview-Output').fadeIn(100);
								});
								self.kotori.edit(wikiText, sectionTargetName, {
									success: function success() {
										var useTime = new Date().valueOf() - timer;
										$('#Wikiplus-Quickedit-Preview-Output').find('.Wikiplus-Banner').css('background', 'rgba(6, 239, 92, 0.44)');
										$('#Wikiplus-Quickedit-Preview-Output').find('.Wikiplus-Banner').text(('' + i18n('edit_success')).replace(/\$1/ig, useTime.toString()));
										window.onclose = window.onbeforeunload = undefined; //取消页面关闭确认
										setTimeout(function () {
											location.reload();
										}, 500);
									},
									fail: function fail(e) {
										console.log(e);
										$('#Wikiplus-Quickedit-Submit,#Wikiplus-Quickedit,#Wikiplus-Quickedit-Preview-Submit').prop('disabled', false);
										$('.Wikiplus-Banner').css('background', 'rgba(218, 142, 167, 0.65)');
										$('.Wikiplus-Banner').html(e.message);
									}
								}, addtionalConfig);
							} else {
								//编辑目标非当前页面
								$('#Wikiplus-Quickedit-Preview-Output').fadeOut(100, function () {
									$('#Wikiplus-Quickedit-Preview-Output').html('').append(onEdit.text(i18n('cross_page_edit')));
									$('#Wikiplus-Quickedit-Preview-Output').fadeIn(100);
								});
								self.kotori.reConstruct(sectionTargetName, {
									success: function success() {
										$('.Wikiplus-Banner').text(i18n('cross_page_edit_submit'));
										self.kotori.edit(wikiText, sectionTargetName, {
											success: function success() {
												var useTime = new Date().valueOf() - timer;
												$('#Wikiplus-Quickedit-Preview-Output').find('.Wikiplus-Banner').css('background', 'rgba(6, 239, 92, 0.44)');
												$('#Wikiplus-Quickedit-Preview-Output').find('.Wikiplus-Banner').text(('' + i18n('edit_success')).replace(/\$1/ig, '' + useTime));
												window.onclose = window.onbeforeunload = undefined; //取消页面关闭确认
												setTimeout(function () {
													location.reload();
												}, 500);
											},
											fail: function fail(e) {
												$('#Wikiplus-Quickedit-Submit,#Wikiplus-Quickedit,#Wikiplus-Quickedit-Preview-Submit').prop('disabled', false);
												$('.Wikiplus-Banner').css('background', 'rgba(218, 142, 167, 0.65)');
												$('.Wikiplus-Banner').text(e.message);
											}
										}, addtionalConfig);
									},
									fail: function fail() {
										$('.Wikiplus-Banner').css('background', 'rgba(218, 142, 167, 0.65)');
										$('.Wikiplus-Banner').text(i18n('cross_page_edit_error'));
									}
								});
							}
						});
						//快捷键
						//Ctrl+S提交 Ctrl+Shift+S小编辑
						$('#Wikiplus-Quickedit,#Wikiplus-Quickedit-Summary-Input,#Wikiplus-Quickedit-MinorEdit').keydown(function (e) {
							if (e.ctrlKey && e.which == 83) {
								if (e.shiftKey) {
									$('#Wikiplus-Quickedit-MinorEdit').click();
								}
								$('#Wikiplus-Quickedit-Submit').click();
								e.preventDefault();
								e.stopPropagation();
							}
						});
						//由于是异步提交 Wikiplus即使编辑失败 也不会丢失数据 唯一丢失数据的可能性是手滑关了页面
						//第一 关闭页面确认
						$('#Wikiplus-Quickedit').keydown(function () {
							window.onclose = window.onbeforeunload = function () {
								return '' + i18n('onclose_confirm');
							};
						});

						//Esc退出
						if (self.getSetting('esc_to_exit_quickedit') === 'true') {
							$(document).keydown(function (e) {
								if (e.which === 27) {
									$("#Wikiplus-Quickedit-Back").click();
								}
							});
						}
					});
				}

				/**
				 * 编辑设置
				 */
			}, {
				key: 'editSettings',
				value: function editSettings() {
					var self = this;
					self.addFunctionButton(i18n('wikiplus_settings'), 'Wikiplus-Settings-Intro', function () {
						var input = $('<textarea>').attr('id', 'Wikiplus-Setting-Input').attr('rows', '10');
						var applyBtn = $('<div>').addClass('Wikiplus-InterBox-Btn').attr('id', 'Wikiplus-Setting-Apply').text(i18n('submit'));
						var cancelBtn = $('<div>').addClass('Wikiplus-InterBox-Btn').attr('id', 'Wikiplus-Setting-Cancel').text(i18n('cancel'));
						var content = $('<div>').append(input).append($('<hr>')).append(applyBtn).append(cancelBtn); //拼接
						self.createDialogBox(i18n('wikiplus_settings_desc'), content, 600, function () {
							if (localStorage.Wikiplus_Settings) {
								$('#Wikiplus-Setting-Input').val(localStorage.Wikiplus_Settings);
							} else {
								$('#Wikiplus-Setting-Input').attr('placeholder', i18n('wikiplus_settings_placeholder'));
							}
							$('#Wikiplus-Setting-Apply').click(function () {
								var settings = $('#Wikiplus-Setting-Input').val();
								try {
									settings = JSON.parse(settings);
								} catch (e) {
									self.notice.create.error(i18n('wikiplus_settings_grammar_error'));
									return;
								}
								localStorage.Wikiplus_Settings = JSON.stringify(settings);
								$('.Wikiplus-InterBox-Content').html('').append($('<div>').addClass('Wikiplus-Banner').text(i18n('wikiplus_settings_saved')));

								$('.Wikiplus-InterBox').fadeOut(300, function () {
									$(this).remove();
								});
							});
							$('#Wikiplus-Setting-Cancel').click(function () {
								$('.Wikiplus-InterBox').fadeOut(300, function () {
									$(this).remove();
								});
							});
						});
					});
				}

				/**
				 * 预读取相关事件绑定
				 */
			}, {
				key: 'preloadEventBinding',
				value: function preloadEventBinding() {
					var self = this;
					$("#toc").children("ul").find("a").each(function (i) {
						$(this).mouseover(function () {
							$(this).unbind('mouseover');
							self.preload(i + 1);
						});
					});
				}

				/**
				 * 为所有可能的编辑链接加上快速编辑按钮
				 */
			}, {
				key: 'editEveryWhere',
				value: function editEveryWhere() {
					var self = this;
					$('#mw-content-text a.external').each(function() {
						var url = $(this).attr('href');
						var reg = /(([^?&=]+)(?:=([^?&=]*))*)/g;
						var params = {},
							match = reg.exec(url);
						while (match) {
							params[match[2]] = decodeURIComponent(match[3]);
							match = reg.exec(url);
						}
						if (params.action === 'edit' && params.title !== undefined && params.section !== 'new' &&
							mw.config.get('wgPageContentModel') == 'wikitext') {
							$(this).after($('<a>').attr({
								'href': "#",
								'class': "Wikiplus-Edit-EveryWhereBtn"
							}).text('(' + i18n('quickedit_sectionbtn') + ')').data({
								'target': decodeURIComponent(params.title),
								'number': params.section || -1
							}));
						}
					});
					$('.Wikiplus-Edit-EveryWhereBtn').click(function (e) {
						e.preventDefault();
						self.kotori.isTop = false;
						self.initQuickEditInterface($(this));
					});
				}

				/**
				 * ===========================
				 * 以上是功能函数 以下是通用函数
				 * ===========================
				 */

				/**
				 * 创建对话框
				 * @param {string} title 对话框标题
				 * @param {HTML} content 内容 
				 * @param {interger} width 宽度 单位像素 默认600px
				 * @param {function} callback 回调函数
				 */
			}, {
				key: 'createDialogBox',
				value: function createDialogBox() {
					var title = arguments.length <= 0 || arguments[0] === undefined ? 'Dialog Box' : arguments[0];
					var content = arguments.length <= 1 || arguments[1] === undefined ? $('<div>') : arguments[1];
					var width = arguments.length <= 2 || arguments[2] === undefined ? 600 : arguments[2];
					var callback = arguments.length <= 3 || arguments[3] === undefined ? function() {} : arguments[3];

					if ($('.Wikiplus-InterBox').length > 0) {
						$('.Wikiplus-InterBox').each(function () {
							$(this).remove();
						});
					}
					var clientWidth = document.body.clientWidth;
					var clientHeight = document.body.clientHeight;
					var dialogWidth = Math.min(clientWidth, width);
					var diglogBox = $('<div>').addClass('Wikiplus-InterBox').css({
						'margin-left': '165px',
						'top': $(document).scrollTop() + clientHeight * 0.2,
						'display': 'none'
					}).append($('<div>').addClass('Wikiplus-InterBox-Header').html(title)).append($('<div>').addClass('Wikiplus-InterBox-Content').append(content)).append($('<span>').text('×').addClass('Wikiplus-InterBox-Close'));
					$('body').append(diglogBox);
					$('.Wikiplus-InterBox').width(dialogWidth);
					$('.Wikiplus-InterBox-Close').click(function () {
						$(this).parent().fadeOut('fast', function () {
							window.onclose = window.onbeforeunload = undefined; //取消页面关闭确认
							$(this).remove();
						});
					});
					//拖曳
					var bindDragging = function bindDragging(element) {
						element.mousedown(function (e) {
							var baseX = e.clientX;
							var baseY = e.clientY;
							var baseOffsetX = element.parent().offset().left;
							var baseOffsetY = element.parent().offset().top;
							$(document).mousemove(function (e) {
								element.parent().css({
									'margin-left': baseOffsetX + e.clientX - baseX,
									'top': baseOffsetY + e.clientY - baseY
								});
							});
							$(document).mouseup(function () {
								element.unbind('mousedown');
								$(document).unbind('mousemove');
								$(document).unbind('mouseup');
								bindDragging(element);
							});
						});
					};
					bindDragging($('.Wikiplus-InterBox-Header'));
					$('.Wikiplus-InterBox').fadeIn(500);
					callback();
				}

				/**
				 * 增加功能按钮
				 * @param {string} text 按钮名
				 * @param {string} id 按钮id
				 * @param {function} clickEvent 点击事件 
				 */
			}, {
				key: 'addFunctionButton',
				value: function addFunctionButton(text, id, clickEvent) {
					var button = $('<li></li>').attr('id', id).append($('<a></a>').attr('href', 'javascript:void(0);').text(text));
					if ($('#p-cactions').length > 0) {
						$('#p-cactions ul').append(button);
						$('#p-cactions ul').find('li').last().click(clickEvent);
					} else if(mw.config.get('skin') == 'vector') {
						throwError('cant_add_funcbtn');
					}
				}

				/**
				 * 预读取内容
				 * @param {interger} section 段落编号 默认为-1即全页
				 * @param {string} title 页面名 默认为当前页面
				 * @param {object} callback 回调
				 */
			}, {
				key: 'preload',
				value: function preload() {
					var section = arguments.length <= 0 || arguments[0] === undefined ? -1 : arguments[0];
					var title = arguments.length <= 1 || arguments[1] === undefined ? this.kotori.pageName : arguments[1];
					var callback = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
					var config = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];

					callback.success = callback.success || function() {};
					callback.fail = callback.fail || function() {};
					var self = this;
					if (config.oldid !== undefined) {
						// oldid 优先于 页面名
						console.log(typeof config.oldid);
						if (this.preloadData[config.oldid + '.' + section]) {
							console.log('[修订版本' + config.oldid + '.' + section + ']已经预读取 跳过本次预读取');
							callback.success(this.preloadData[config.oldid + '.' + section]);
							return;
						}
					} else {
						if (this.preloadData[title + '.' + section]) {
							console.log('[' + title + '.' + section + ']已经预读取 跳过本次预读取');
							callback.success(this.preloadData[title + '.' + section]);
							return;
						}
					}
					this.kotori.getWikiText({
						success: function success(data) {
							if (config.oldid !== undefined) {
								self.preloadData[config.oldid + '.' + section] = data;
								console.log('预读取[修订版本' + config.oldid + '.' + section + ']成功');
							} else {
								self.preloadData[title + '.' + section] = data;
								console.log('预读取[' + title + '.' + section + ']成功');
							}
							callback.success(data);
						},
						fail: function fail(e) {
							if (config.oldid !== undefined) {
								console.log('预读取[修订版本' + config.oldid + '.' + section + ']失败');
							} else {
								console.log('预读取[' + title + '.' + section + ']失败:' + e.message);
							}
							callback.fail(e);
						}
					}, title, section === -1 ? config : $.extend({
						rvsection: section
					}, config) );
				}

				/**
				 * 检查安装
				 * @param {function} callback 回调函数
				 */
			}, {
				key: 'checkInstall',
				value: function checkInstall() {
					var self = this;
					if (!localStorage.Wikiplus_Installed || localStorage.Wikiplus_Installed == 'False') {
						//安装
						var install = function install() {
							localStorage.Wikiplus_Installed = 'True'; //标记已安装
							localStorage.Wikiplus_Version = self.version;
							localStorage.Wikiplus_StartUseAt = new Date().valueOf();
							localStorage.Wikiplus_SrartEditCount = mw.config.get('wgUserEditCount');
							localStorage.Wikiplus_Settings = JSON.stringify(self.defaultSettings);
							$('.Wikiplus-InterBox').fadeOut('fast', function () {
								self.notice.create.success(i18n('install_finish'));
								$(this).remove();
							});
						};
						install();
					}
				}

				/**
				 * 获取设置值
				 * @param {string} key 键名
				 * @param {object} object 传入可用参数
				 */
			}, {
				key: 'getSetting',
				value: function getSetting(key, object) {
					var w = object, settings;
					try {
						settings = JSON.parse(localStorage.Wikiplus_Settings);
					} catch (e) {
						return localStorage.Wikiplus_Settings || '';
					}
					try {
						var _setting = new Function('return ' + settings[key]);
						if (typeof _setting == 'function') {
							try {
								if (_setting()(w) === true) {
									return undefined;
								} else {
									return _setting()(w) || settings[key];
								}
							} catch (e) {
								return settings[key];
							}
						} else {
							return settings[key];
						}
					} catch (e) {
						try {
							return settings[key];
						} catch (e) {
							return undefined;
						}
					}
				}
			}, {
				key: 'initBasicFunctions',
				value: function initBasicFunctions() {
					this.initQuickEdit(); //加载快速编辑
					this.editSettings(); //编辑设置
					this.preloadEventBinding(); //预读取
					if (!this.getSetting('disableEditEveryWhere')) {
						this.editEveryWhere(); //任意编辑
					}
				}
			}]);

			function Wikiplus() {
				_classCallCheck(this, Wikiplus);

				this.version = '2.2.19';
				this.langVersion = '210';
				this.releaseNote = '修正移动版样式';
				this.notice = new MoeNotification();
				this.defaultSettings = {
					'key': 'value',
					'documatation': 'https://zh.moegirl.org.cn/User:%E5%A6%B9%E7%A9%BA%E9%85%B1/Wikiplus/%E8%AE%BE%E7%BD%AE%E8%AF%B4%E6%98%8E'
				};
				console.log('正在加载Wikiplus ' + this.version);
				//一些初始化工作
				this.preloadData = {};
				this.checkInstall(); //安装检查
				//真正的初始化
				if (mw.config.get('wgNameSpaceNumber') >= 0 && mw.config.get('wgIsArticle') && mw.config.get('wgAction') === "view") {
					this.kotori = new Wikipage();
					this.initBasicFunctions();
				} else {
					console.log('不符合加载条件 Wikiplus终止');
				}
			}

			return Wikiplus;
		})();

		window.Wikiplus = new Wikiplus();
	});
});
//</nowiki>