doge24190的狗窝

一个很乱的wiki

用户工具

站点工具


Action disabled: revisions
wikiplus

wikiplus源码存档

源码

Main.js
/* global mw */
/// <reference path="../typings/jquery/jquery.d.ts"/>
/**
 * Wikiplus
 * Author: +Eridanus Sora/@妹空酱
 * Github: https://github.com/Last-Order/Wikiplus
 */
/**
 * 依赖组件: MoeNotification
 * https://github.com/Last-Order/MoeNotification
 */
'use strict';
 
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) {
            var isFunction = function isFunction(f) {
                if (typeof f === 'function') return true;
                var t = Object.prototype.toString(f);
                return t === '[object Function]' || t === '[object GeneratorFunction]';
            };
            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 () {
    var i18nData = {};
    var scriptPath = location.protocol + '//wikiplus-app.com';
    i18nData['zh-cn'] = {
        "__language": "zh-cn",
        "__author": ["Eridanus Sora"],
        "__version": "212",
        "unknown_error_name": "未知的错误名",
        "api_unaccessiable": "无可用的API",
        "api_unwriteable": "无可用的写入API",
        "fail_to_get_timestamp": "无法获得页面编辑起始时间戳",
        "fail_to_get_edittoken": "无法获得页面编辑权标",
        "fail_to_get_pageinfo": "无法获得页面信息",
        "not_autoconfirmed_user": "非自动确认用户",
        "hit_abusefilter": "被防滥用过滤器拦截",
        "unknown_edit_error": "未知编辑错误",
        "unknown_edit_error_message": "未知编辑错误($1)",
        "notitle": "无法编辑空标题页面",
        "notext": "缺少页面内容",
        "notoken": "空编辑权标",
        "invalidsection": "段落编号非法",
        "protectedtitle": "该标题被保护,无法创建",
        "cantcreate": "无新建页面权限",
        "cantcreate_anon": "匿名用户无新建页面权限",
        "articleexists": "无法创建已经存在的页面",
        "noimageredirect_anon": "匿名用户无新建文件重定向权限",
        "noimageredirect": "无新建文件重定向权限",
        "spamdetected": "文本含有敏感内容,被SPAM过滤器拦截",
        "filtered": "编辑被过滤器拦截",
        "contenttoobig": "文本超过最大长度限制",
        "noedit_anon": "匿名用户无编辑页面权限",
        "noedit": "无编辑页面权限",
        "pagedeleted": "编辑时,此页面被删除",
        "emptypage": "无法新建空内容页面",
        "emptynewsection": "无法新建空内容段落",
        "editconflict": "编辑冲突,请手工检查页面当前内容与提交内容差异并修正后,刷新页面提交",
        "revwrongpage": "编辑的修订版本与编辑的页面不匹配",
        "undofailure": "由于存在冲突的中间版本,无法撤销编辑",
        "missingtitle": "无法创建或编辑空标题页面",
        "mustbeposted": "必须使用POST方式提交编辑",
        "readapidenied": "无读取API使用权限",
        "writeapidenied": "无通过API编辑页面权限",
        "noapiwrite": "本Wiki未开启可用的写入API",
        "badtoken": "非法的编辑权标",
        "missingparam": "缺少必要参数,页面名和页面ID不能均为空",
        "invalidparammix": "参数重复,页面名和页面ID不能同时给定",
        "invalidtitle": "非法的标题",
        "nosuchpageid": "不存在的页面ID",
        "pagecannotexist": "该名称空间不允许新建一般页面",
        "nosuchrevid": "不存在的修订版本",
        "badmd5": "非法的MD5值",
        "hookaborted": "编辑被扩展Hook拦截",
        "parseerror": "无法解析页面文本",
        "summaryrequired": "编辑摘要不能为空",
        "blocked": "已被封禁",
        "ratelimited": "达到操作速率上限,请稍后重试",
        "unknownerror": "未知错误",
        "nosuchsection": "无法编辑不存在的段落",
        "sectionsnotsupported": "该页面不支持段落编辑",
        "editnotsupported": "该页面不支持通过API编辑",
        "appendnotsupported": "该页面无法在前后插入文本",
        "redirect_appendonly": "在遵循重定向的情况下,只能进行前后插入或创建新段落",
        "badformat": "文本格式错误",
        "customcssprotected": "无法编辑用户CSS页",
        "customjsprotected": "无法编辑用户JS页",
        "cascadeprotected": "该页面被级联保护",
        "network_edit_error": "由于网络原因编辑失败",
        "redirect_to_summary": "重定向页面至[[$1]] \/\/ Wikiplus",
        "redirect_from_summary": "将[[$1]]重定向至[[$2]] \/\/ Wikiplus",
        "need_init": "页面类未加载完成",
        "fail_to_get_wikitext": "无法获得页面文本",
        "quickedit_topbtn": "快速编辑",
        "quickedit_sectionbtn": "快速编辑",
        "fail_to_init_quickedit": "无法加载快速编辑",
        "back": "返回",
        "goto_editbox": "到编辑框",
        "summary_placehold": "请输入编辑摘要",
        "submit": "提交",
        "publish_page": "发布页面",
        "publish_change": "发布更改",
        "preview": "预览",
        "cancel": "取消",
        "mark_minoredit": "标记为小编辑",
        "onclose_confirm": "[Wikiplus] 您确认要关闭/刷新页面吗?这会导致您的编辑数据丢失",
        "fail_to_get_wikitext_when_edit": "无法获得页面文本以编辑",
        "cant_parse_wikitext": "无法解析维基文本",
        "loading_preview": "正在读取预览",
        "submitting_edit": "正在提交编辑",
        "edit_success": "编辑成功 用时$1ms",
        "empty_page_confirm": "您向编辑函数传入了空内容参数 这将清空页面\r\n由于该行为危险 请将config参数的empty键值设定为true来确认",
        "cross_page_edit": "编辑目标位于其他页面 正在获取基础信息",
        "cross_page_edit_submit": "基础信息获取成功 正在提交编辑",
        "cross_page_edit_error": "无法获得基础信息>.<",
        "install_tip": "您是否允许Wikiplus采集非敏感数据用于改进Wikiplus及为当前Wiki:$1提供改进建议?",
        "accept": "接受",
        "decline": "拒绝",
        "install_finish": "Wikiplus安装完毕",
        "loading": "正在载入",
        "cant_add_funcbtn": "无法增加功能按钮",
        "wikiplus_settings": "Wikiplus设置",
        "wikiplus_settings_desc": "请在下方按规范修改Wikiplus设置",
        "wikiplus_settings_placeholder": "当前设置为空 请在此处按规范修改Wikiplus设置",
        "wikiplus_settings_grammar_error": "设置存在语法错误 请检查后重试",
        "wikiplus_settings_saved": "设置已保存",
        "redirect_from": "将页面重定向至此",
        "redirect_desc": "请输入要重定向至此的页面名",
        "empty_input": "输入不能为空",
        "redirect_saved": "重定向完成",
        "uninited": "Wikiplus未加载完毕 请刷新重试",
        "cant_parse_i18ncache": "无法解析多语言定义文件缓存",
        "cant_load_language": "无法获取多语言定义文件",
        "history_edit_warning": " // 正试图编辑历史版本 这将会应用到本页面的最新版本 请慎重提交",
        "create_page_tip": "<!-- 正在创建新页面 请删去此行注释后继续 -->",
        "continue": "仍然继续",
        "default_summary_suffix": "// Edit via Wikiplus",
        'cross_page_history_revision_edit_warning': '暂不支持历史版本跨页面编辑'
    };
    i18nData['en-us'] = {
        "__language": "en-us",
        "__author": ["Eridanus Sora", "AnnAngela", "YinYan"],
        "__version": "212",
        "unknown_error_name": "Unknown error",
        "api_unaccessiable": "API of this wiki is not available",
        "api_unwriteable": "Write API of this wiki is not available",
        "fail_to_get_timestamp": "Failed to get the timestamp of this page.",
        "fail_to_get_edittoken": "Failed to get the EditToken of this page.",
        "fail_to_get_pageinfo": "Failed to load infomation of this page",
        "not_autoconfirmed_user": "You are not an autoconfiremd user",
        "hit_abusefilter": "Your edit hit the abusefilter(s)",
        "unknown_edit_error": "Unknown edit error",
        "unknown_edit_error_message": "Unknown edit error($1)",
        "notitle": "The title parameter must be set",
        "notext": "The text parameter must be set",
        "notoken": "The token parameter must be set",
        "invalidsection": "The section parameter must be set to an integer or 'new'",
        "protectedtitle": "This title has been protected from creation",
        "cantcreate": "You don't have permission to create new pages",
        "cantcreate_anon": "Anonymous users can't create new pages",
        "articleexists": "The article you tried to create has already existed",
        "noimageredirect_anon": "Anonymous users can't create image redirects",
        "noimageredirect": "You don't have the permission to create image redirects",
        "spamdetected": "Your edit was rejected because it contained a spam fragment",
        "filtered": "The filter callback function rejected your edit",
        "contenttoobig": "The content you submitted exceeds the article size limit",
        "noedit_anon": "Anonymous users can't edit pages",
        "noedit": "You don't have the permission to edit pages",
        "pagedeleted": "The page was deleted during your edit",
        "emptypage": "Creating new, empty pages is not allowed",
        "emptynewsection": "Creating empty new sections is not possible.",
        "editconflict": "Edit Conflict! Don't panic. Please check the difference between your content below and the existing revision, then refresh the page to make another submit",
        "revwrongpage": "The revision you are editing now is not one a valid reversions of this page",
        "undofailure": "Undo failed due to conflicts.",
        "missingtitle": "Missing title in your edit/creation",
        "mustbeposted": "The edit must be submited by POST method",
        "readapidenied": "Read API Denied",
        "writeapidenied": "Write API Denied",
        "noapiwrite": "No available write API in this wiki",
        "badtoken": "Invalid EditToken",
        "missingparam": "One of the parameters title, pageid is required",
        "invalidparammix": "The parameters title, pageid can not be used together",
        "invalidtitle": "Invalid page title",
        "nosuchpageid": "Inexistent page ID",
        "pagecannotexist": "No access to create a new page in this namespace",
        "nosuchrevid": "Inexisting reversion ID",
        "badmd5": "Invalid MD5",
        "hookaborted": "Your edit was rejected by the hook(s)",
        "parseerror": "Failed to parse the wikitext of this page",
        "summaryrequired": "No summary in your edit",
        "blocked": "You have been already BLOCKED",
        "ratelimited": "You've exceeded your rate limit. Please have a tea and try again later",
        "unknownerror": "Unknown error",
        "nosuchsection": "There is no such section",
        "sectionsnotsupported": "Can't edit in this section",
        "editnotsupported": "Can't edit in this section by writing section",
        "appendnotsupported": "Can't append/prepend wikitext to this page",
        "redirect_appendonly": "Only append/prepend can be made to this page because of the rules of the redirect page",
        "badformat": "The requested serialization format can not be applied to the page's content model",
        "customcssprotected": "You're not allowed to edit custom CSS pages",
        "customjsprotected": "You're not allowed to edit custom JavaScript pages",
        "cascadeprotected": "This page is under a cascading protection",
        "network_edit_error": "Failed to edit this page because of network errors",
        "redirect_to_summary": "Redirect to [[$1]] \/\/ Wikiplus",
        "redirect_from_summary": "Redirect [[$1]] to [[$2]] \/\/ Wikiplus",
        "need_init": "Wikiplus haven't been loaded completely. It's a rare occasion so you can try to refresh and try again.",
        "fail_to_get_wikitext": "Failed to load the wikitext of this page",
        "quickedit_topbtn": "QuickEdit",
        "quickedit_sectionbtn": "QuickEdit",
        "fail_to_init_quickedit": "Failed to initialize Wikiplus",
        "back": "Back",
        "goto_editbox": "Jump to editbox",
        "summary_placehold": "Edit summary",
        "submit": "Submit",
        "publish_page": "Publish Page",
        "publish_change": "Publish Changes",
        "preview": "Preview",
        "cancel": "Cancel",
        "mark_minoredit": "Mark this edit as a minor edit",
        "onclose_confirm": "[Wikiplus] Do you really want to close this page when you are still editing it, as you will lose all your unsaved work?",
        "fail_to_get_wikitext_when_edit": "Failed to load wikitext for your edit",
        "cant_parse_wikitext": "Failed to parse the wikitext",
        "loading_preview": "Loading the preview",
        "submitting_edit": "Submitting your edit",
        "edit_success": "Your edit is submitted within $1ms",
        "empty_page_confirm": "The wikitext in your edit is empty, which will empty this page.\r\nPlease set the value of key \"empty\" true to allow this kind of edits. (This is a tip for developers)",
        "cross_page_edit": "The content you are editing belongs to another page, please wait...",
        "cross_page_edit_submit": "Submitting your edit...",
        "cross_page_edit_error": "Failed to load the infomation",
        "install_tip": "Do you allow Wikiplus to collect insensitive data to help us develop Wikiplus and provide feedback to current site: $1 ?",
        "accept": "Yes",
        "decline": "No",
        "install_finish": "Wikiplus is installed, enjoy it",
        "loading": "Loading",
        "cant_add_funcbtn": "Failed to add buttons for Wikiplus",
        "wikiplus_settings": "Wikiplus Setting",
        "wikiplus_settings_desc": "Please modify your setting according to the standards below",
        "wikiplus_settings_placeholder": "Your setting is empty, please modify your setting according to the documentation.",
        "wikiplus_settings_grammar_error": "Syntax error in your setting",
        "wikiplus_settings_saved": "Your settings have been saved",
        "redirect_from": "Redirect from",
        "redirect_desc": "Which page do you want to redirect here?",
        "empty_input": "Empty input",
        "redirect_saved": "Redirection is finished",
        "uninited": "Wikiplus is not completely initialized, please refeash this page",
        "cant_parse_i18ncache": "Failed to parse the cache of i18n file",
        "cant_load_language": "Failed to load i18n file",
        "history_edit_warning": " // You are trying to edit a history revision of this page. This will apply to the latest revision. Please be careful.",
        "create_page_tip": "<!-- You are now creating a new page. Please delete this line and be careful. -->",
        "continue": "Continue anyway",
        "default_summary_suffix": "// Edit via Wikiplus",
        "cross_page_history_revision_edit_warning": "Cross-page edit in history revision is not supported yet."
    };
 
    /**
     * 加载其他语言文件
     * @param {string} language 语言名
     */
    function loadLanguage(language) {
        $.ajax({
            url: scriptPath + '/languages/get.php?lang=' + language,
            dataType: 'json',
            success: function success(data) {
                if (data.__language && data.__version) {
                    if (i18nData[data.__language]) {
                        if (data.__version >= i18nData[data.__language].__version) {
                            i18nData[data.__language] = data;
                            console.log('更新语言版本' + data.___language + '至' + data.___version);
                        } else {
                            // 服务端未跟进语言版本 不更新本地缓存
                        }
                    } else {
                            i18nData[data.__language] = data;
                        }
                    localStorage.Wikiplus_i18nCache = JSON.stringify(i18nData); //更新缓存
                }
            },
            error: function error(e) {
                console.log('无法加载语言' + language);
            }
        });
    }
    /**
     * 多语言转换
     * @param {stirng} key 字段标识名
     * @return {string} 经过转换的内容 如未找到对应的多语言字段 则返回简体中文
     */
    function i18n(key) {
        var language;
        try {
            language = JSON.parse(localStorage.Wikiplus_Settings)['language'] || window.navigator.language.toLowerCase();
        } catch (e) {
            language = window.navigator.language.toLowerCase();
        }
        if (i18nData[language] && i18nData[language][key]) {
            return i18nData[language][key];
        } else if (i18nData['en-us'][key]) {
            return i18nData['en-us'][key];
        } else {
            return;
        }
    }
    /**
     * 获得错误信息
     * @param {stirng} name
     * @return {object} {number,message}
     */
    function getErrorInfo(name) {
        var errorList = {
            unknown_error_name: {
                number: 1001,
                message: i18n('unknown_error_name')
            },
            api_unaccessiable: {
                number: 1002
            },
            api_unwriteable: {
                number: 1003
            },
            fail_to_get_timestamp: {
                number: 1004
            },
            fail_to_get_edittoken: {
                number: 1005
            },
            fail_to_get_pageinfo: {
                number: 1006
            },
            not_autoconfirmed_user: {
                number: 1007
            },
            hit_abusefilter: {
                number: 1008
            },
            unknown_edit_error: {
                number: 1009
            },
            unknown_edit_error_message: {
                number: 1010
            },
            notitle: {
                number: 1011
            },
            notext: {
                number: 1012
            },
            notoken: {
                number: 1013
            },
            invalidsection: {
                number: 1014
            },
            protectedtitle: {
                number: 1015
            },
            cantcreate: {
                number: 1016
            },
            cantcreate_anon: {
                number: 1017
            },
            articleexists: {
                number: 1018
            },
            noimageredirect_anon: {
                number: 1019
            },
            noimageredirect: {
                number: 1020
            },
            spamdetected: {
                number: 1021
            },
            filtered: {
                number: 1022
            },
            contenttoobig: {
                number: 1023
            },
            noedit_anon: {
                number: 1025
            },
            noedit: {
                number: 1026
            },
            pagedeleted: {
                number: 1027
            },
            emptypage: {
                number: 1028
            },
            emptynewsection: {
                number: 1029
            },
            editconflict: {
                number: 1030
            },
            revwrongpage: {
                number: 1031
            },
            undofailure: {
                number: 1032
            },
            missingtitle: {
                number: 1033
            },
            mustbeposted: {
                number: 1034
            },
            readapidenied: {
                number: 1035
            },
            writeapidenied: {
                number: 1036
            },
            noapiwrite: {
                number: 1037
            },
            badtoken: {
                number: 1038
            },
            missingparam: {
                number: 1039
            },
            invalidparammix: {
                number: 1040
            },
            invalidtitle: {
                number: 1041
            },
            nosuchpageid: {
                number: 1042
            },
            pagecannotexist: {
                number: 1043
            },
            nosuchrevid: {
                number: 1044
            },
            badmd5: {
                number: 1045
            },
            hookaborted: {
                number: 1046
            },
            parseerror: {
                number: 1047
            },
            summaryrequired: {
                number: 1048
            },
            blocked: {
                number: 1049
            },
            ratelimited: {
                number: 1050
            },
            unknownerror: {
                number: 1051
            },
            nosuchsection: {
                number: 1052
            },
            sectionsnotsupported: {
                number: 1053
            },
            editnotsupported: {
                number: 1054
            },
            appendnotsupported: {
                number: 1055
            },
            redirect_appendonly: {
                number: 1056
            },
            badformat: {
                number: 1057
            },
            customcssprotected: {
                number: 1058
            },
            customjsprotected: {
                number: 1059
            },
            cascadeprotected: {
                number: 1060
            },
            network_edit_error: {
                number: 1061
            },
            need_init: {
                number: 1062
            },
            fail_to_get_wikitext: {
                number: 1063
            },
            fail_to_init_quickedit: {
                number: 1064
            },
            fail_to_get_wikitext_when_edit: {
                number: 1065
            },
            cant_parse_wikitext: {
                number: 1066
            },
            empty_page_confirm: {
                number: 1067
            },
            uninited: {
                number: 1068
            },
            cant_parse_i18ncache: {
                number: 1069
            },
            cant_load_language: {
                number: 1070
            }
        };
        if (errorList[name]) {
            if (errorList[name].message) {
                return {
                    number: errorList[name].number,
                    message: errorList[name].message
                };
            } else if (i18n(name) !== 'undefined') {
                return {
                    number: errorList[name].number,
                    message: i18n(name)
                };
            } else {
                return {
                    number: errorList[name].number,
                    message: i18n('unknownerror')
                };
            }
        } else {
            return {
                number: errorList.unknown_error_name.number,
                message: errorList.unknown_error_name.message
            };
        }
    }
    /**
     * 抛出错误
     * @param {string} name
     * @return boolean
     */
    function throwError(name, message) {
        var errInfo = getErrorInfo(name);
        var e = new Error();
        e.number = errInfo.number;
        e.message = message || errInfo.message;
        console.log('%c致命错误[' + e.number + ']:' + e.message, 'color:red');
        console.log(e);
        return e;
    }
    /**
     * 将mw的段落的id转换为可显示的文本
     * @param {string} URL
     * @return string
     */
 
    var Wikipage = (function () {
        function Wikipage() {
            var pageName = arguments.length <= 0 || arguments[0] === undefined ? window.mw.config.get('wgPageName') : arguments[0];
 
            _classCallCheck(this, Wikipage);
 
            console.log('页面类构建中');
            //可用性和权限检测
            if (!window.mw) {
                console.log('页面JavaScript载入不完全或这不是一个MediaWiki站点');
                return;
            }
            if (!window.mw.config.get('wgUserGroups').includes('autoconfirmed') && !window.mw.config.get('wgUserGroups').includes('confirmed')) {
                throwError('not_autoconfirmed_user');
                return;
            }
            //从MediaWiki定义的全局变量中获得信息
            this.pageName = pageName.replace(/ /ig, '_'); // MediaWiki处理空格时可能会出错
            this.revisionId = window.mw.config.get('wgRevisionId');
            this.articleId = window.mw.config.get('wgArticleId');
            this.API = location.protocol + '//' + location.host + window.mw.config.get('wgScriptPath') + '/api.php';
            //从API获得编辑令牌和起始时间戳
            this.editToken = {};
            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, config) {
                if (title === undefined) title = this.pageName;
                if (callback === undefined) callback = {};
 
                var self = this;
                callback.success = callback.success || new Function();
                callback.fail = callback.success || new Function();
                $.ajax({
                    type: 'GET',
                    dataType: 'json',
                    url: this.API,
                    data: {
                        'action': 'query',
                        'prop': 'revisions|info',
                        'titles': title,
                        'rvprop': 'timestamp',
                        'format': 'json'
                    },
                    beforeSend: function beforeSend(request) {
                        request.setRequestHeader('Api-User-Agent', 'Wikiplus/2 (' + mw.config.get('wgWikiID') + ')');
                        console.time('获得页面基础信息时间耗时');
                    },
                    success: function success(data) {
                        if (data && data.query && data.query.pages) {
                            var info = data.query.pages;
                            for (var key in info) {
                                if (key !== '-1') {
                                    if (info[key].revisions && info[key].revisions.length > 0) {
                                        self.timeStamp[title] = info[key].revisions[0].timestamp;
                                    } else {
                                        callback.fail(throwError('fail_to_get_timestamp'));
                                    }
                                    if (mw.user.tokens.get('csrfToken') && mw.user.tokens.get('csrfToken') !== '+\\') {
                                        self.editToken[title] = mw.user.tokens.get('csrfToken');
                                        console.log('成功获得编辑令牌 来自前端API');
                                    } else {
                                        //前端拿不到Token 尝试通过API
                                        $.ajax({
                                            url: self.API,
                                            type: 'GET',
                                            dataType: 'json',
                                            data: {
                                                'action': 'query',
                                                'meta': 'tokens',
                                                'format': 'json'
                                            },
                                            beforeSend: function beforeSend(request) {
                                                request.setRequestHeader('Api-User-Agent', 'Wikiplus/2 (' + mw.config.get('wgWikiID') + ')');
                                            },
                                            success: function success(data) {
                                                if (data.query && data.query.tokens && data.query.tokens.csrftoken && data.query.tokens.csrftoken !== '+\\') {
                                                    self.editToken[title] = data.query.tokens.csrftoken;
                                                    console.log('成功获得编辑令牌 通过后端API');
                                                } else {
                                                    callback.fail(throwError('fail_to_get_edittoken'));
                                                }
                                            },
                                            error: function error(e) {
                                                callback.fail(throwError('fail_to_get_edittoken'));
                                            }
                                        });
                                        callback.fail(throwError('fail_to_get_edittoken'));
                                    }
                                } else {
                                    if (mw.config.get('wgArticleId') === 0) {
                                        // 如果是空页面就只拿一个edittoken
                                        if (mw.user.tokens.get('csrfToken') && mw.user.tokens.get('csrfToken') !== '+\\') {
                                            self.editToken[title] = mw.user.tokens.get('csrfToken');
                                            console.log('成功获得编辑令牌 来自前端API');
                                            self.inited = true;
                                        } else {
                                            self.inited = false;
                                            callback.fail(throwError('fail_to_get_edittoken'));
                                        }
                                    } else {
                                        // 如果不是 那就是失败了 抛出错误
                                        self.inited = false;
                                        callback.fail(throwError('fail_to_get_pageinfo'));
                                    }
                                }
                            }
                        }
                    }
                }).done(function () {
                    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 || new Function();
                callback.fail = callback.fail || new Function();
                if (content === undefined) {
                    if (!config.empty === true) {
                        callback.fail(throwError('empty_page_confirm'));
                        return false;
                    }
                }
                if (self.inited) {
                    $.ajax({
                        type: 'POST',
                        url: self.API,
                        data: $.extend({
                            'action': 'edit',
                            'format': 'json',
                            'text': content,
                            'title': title,
                            'token': self.editToken[title] || self.editToken[self.pageName],
                            'basetimestamp': self.timeStamp[title]
                        }, config),
                        beforeSend: function beforeSend(request) {
                            request.setRequestHeader('Api-User-Agent', 'Wikiplus/2 (' + mw.config.get('wgWikiID') + ')');
                        },
                        success: function success(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'));
                            }
                        },
                        error: function error(e) {
                            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 || new Function();
                callback.fail = callback.fail || new Function();
                this.edit(content, title, callback, $.extend({
                    'section': section
                }, config));
            }
 
            /**
             * 重定向页面至
             * @param {string} target 目标页面标题
             * @param {string} title 页面名 默认为当前页面
             * @param {object} callback 回调函数
             */
        }, {
            key: 'redirectTo',
            value: function redirectTo(target) {
                var title = arguments.length <= 1 || arguments[1] === undefined ? this.pageName : arguments[1];
                var callback = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
 
                callback.success = callback.success || new Function();
                callback.fail = callback.fail || new Function();
                this.edit('#REDIRECT [[' + target + ']]', title, callback, {
                    'summary': i18n('redirect_to_summary').replace(/\$1/ig, target)
                });
            }
 
            /**
             * 重定向自
             * @param {string} origin 重定向页标题
             * @param {string} title 重定向目标页标题 默认为当前页
             * @param {object} callback
             */
        }, {
            key: 'redirectFrom',
            value: function redirectFrom(origin) {
                var title = arguments.length <= 1 || arguments[1] === undefined ? this.pageName : arguments[1];
                var callback = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
                var force = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
 
                callback.success = callback.success || new Function();
                callback.fail = callback.fail || new Function();
                var data = {
                    summary: i18n('redirect_from_summary').replace(/\$1/ig, origin).replace(/\$2/ig, title)
                };
                if (!force) {
                    data.createonly = 'true';
                }
                this.edit('#REDIRECT [[' + title + ']]', origin, callback, data);
            }
 
            /**
             * 获得页面维基文本
             * @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 || new Function();
                callback.fail = callback.fail || new Function();
                $.ajax({
                    url: location.protocol + '//' + location.host + mw.config.get('wgScriptPath') + '/index.php',
                    type: 'GET',
                    dataType: 'text',
                    cache: false,
                    data: $.extend({
                        'title': title,
                        'action': 'raw'
                    }, config),
                    beforeSend: function beforeSend(request) {
                        request.setRequestHeader('Api-User-Agent', 'Wikiplus/2 (' + mw.config.get('wgWikiID') + ')');
                        console.time('获得页面文本耗时');
                    },
                    success: function success(data) {
                        console.timeEnd('获得页面文本耗时');
                        callback.success(data);
                    },
                    error: function error(e) {
                        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 || new Function();
                callback.fail = callback.fail || new Function();
                $.ajax({
                    type: 'POST',
                    dataType: 'json',
                    data: $.extend({
                        'format': 'json',
                        'action': 'parse',
                        'text': wikitext,
                        'title': this.pageName,
                        'pst': 'true'
                    }, config),
                    beforeSend: function beforeSend(request) {
                        request.setRequestHeader('Api-User-Agent', 'Wikiplus/2 (' + mw.config.get('wgWikiID') + ')');
                    },
                    url: this.API,
                    success: function success(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;
                    var checkRight = function checkRight() {
                        if (!mw.config.get('wgUserGroups').includes('autoconfirmed') && !mw.config.get('wgUserGroups').includes('confirmed')) {
                            new MoeNotification().create.error(getErrorInfo('not_autoconfirmed_user').message);
                            throwError('not_autoconfirmed_user');
                        }
                    };
                    callback.success = callback.success || new Function();
                    callback.fail = callback.fail || new 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').append($('<span>').append($('<a>').attr('href', 'javascript:void(0)').text('' + i18n('quickedit_topbtn')))).data({
                        number: -1,
                        target: self.kotori.pageName
                    });
                    if (mw.config.get('skin') === 'minerva') {
                        $(topBtn).css({ 'align-items': 'center', 'display': 'flex' });
                        $(topBtn).find('span').addClass('page-actions-menu__list-item');
                        $(topBtn).find('a').addClass('mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-edit-base20 mw-ui-icon-with-label-desktop').css('vertical-align', 'middle');
                    }
                    if ($('#ca-edit').length > 0 && $('#Wikiplus-Edit-TopBtn').length === 0) {
                        mw.config.get('skin') === 'minerva' ? $('#ca-edit').parent().after(topBtn) : $('#ca-edit').after(topBtn);
                        $('#Wikiplus-Edit-TopBtn').click(function () {
                            checkRight();
                            self.initQuickEditInterface($(this)); //直接把DOM传递给下一步
                        });
                    } else if ($('#ca-edit').length === 0) {
                            throwError('fail_to_init_quickedit');
                        }
                    if ($('.mw-editsection').length > 0) {
                        self.sectionMap = {};
                        //段落快速编辑按钮
                        var sectionBtn = mw.config.get('skin') === 'minerva' ? $('<span>').append($('<a>').addClass('Wikiplus-Edit-SectionBtn mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-edit-base20 edit-page mw-ui-icon-flush-right').css('margin-left', '0.75em').attr('href', 'javascript:void(0)').attr('title', i18n('quickedit_sectionbtn'))) : $('<span>').append($('<span>').addClass('mw-editsection-divider').text(' | ')).append($('<a>').addClass('Wikiplus-Edit-SectionBtn').attr('href', 'javascript:void(0)').text(i18n('quickedit_sectionbtn')));
                        $('.mw-editsection').each(function (i) {
                            try {
                                var editURL = $(this).find('a').first().attr('href');
                                var sectionNumber = editURL.match(/&[ve]*section\=([^&]+)/)[1].replace(/T-/ig, '');
                                var sectionTargetName;
                                if (editURL.match(/title=(.+?)&/)) {
                                    sectionTargetName = decodeURIComponent(editURL.match(/title=(.+?)&/)[1]);
                                } else {
                                    var regex = new RegExp(mw.config.get('wgArticlePath').replace('$1', '') + '(.+?)\\?');
                                    if (editURL.match(regex)) {
                                        sectionTargetName = decodeURIComponent(editURL.match(regex)[1]);
                                    } else {
                                        throwError('fail_to_init_quickedit');
                                    }
                                }
                                var cloneNode = $(this).prev().clone();
                                cloneNode.find('.mw-headline-number').remove();
                                var sectionName = cloneNode.text().trim();
                                self.sectionMap[sectionNumber] = {
                                    name: sectionName,
                                    target: sectionTargetName
                                };
                                var _sectionBtn = sectionBtn.clone();
                                _sectionBtn.find('.Wikiplus-Edit-SectionBtn').data({
                                    number: sectionNumber,
                                    name: sectionName,
                                    target: sectionTargetName
                                });
                                mw.config.get('skin') === 'minerva' ? $(this).append(_sectionBtn) : $(this).find('.mw-editsection-bracket').last().before(_sectionBtn);
                            } catch (e) {
                                throwError('fail_to_init_quickedit');
                            }
                        });
                        $('.Wikiplus-Edit-SectionBtn').click(function () {
                            checkRight();
                            self.initQuickEditInterface($(this)); //直接把DOM传递给下一步
                        });
                    }
                }
 
                /**
                 * 加载快速编辑主界面相关内容
                 */
            }, {
                key: 'initQuickEditInterface',
                value: function initQuickEditInterface(obj) {
                    var self = this;
                    var sectionNumber = obj.data('number');
                    var sectionTargetName = obj.data('target');
                    if (this.kotori.inited) {
                        if (sectionTargetName !== self.kotori.pageName && mw.config.get('wgCurRevisionId') !== mw.config.get('wgRevisionId')) {
                            // 在历史版本编辑其他页面有问题 暂时不支持
                            this.notice.create.error(i18n('cross_page_history_revision_edit_warning'));
                            return;
                        }
                        if ($('.noarticletext').length > 0) {
                            //这是一个空页面
                            this.preloadData[sectionTargetName + '.-1'] = i18n('create_page_tip');
                        }
                        if (mw.config.get('wgCurRevisionId') === mw.config.get('wgRevisionId')) {
                            var additionalConfig = {};
                            if (this.preloadData[sectionTargetName + '.' + sectionNumber] === undefined) {
                                if (sectionTargetName === this.kotori.pageName) {
                                    additionalConfig.oldid = mw.config.get('wgRevisionId');
                                }
                                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(e) {
                                        throwError('fail_to_get_wikitext_when_edit');
                                    }
                                }, additionalConfig);
                            } 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(data) {
                                    throwError('fail_to_get_wikitext_when_edit');
                                }
                            }, {
                                'oldid': 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, $('<br>'), isMinorEdit, editSubmitBtn, previewSubmitBtn);
                    this.createDialogBox('' + i18n('quickedit_topbtn') + message, editBody, 1000, function () {
                        $('#Wikiplus-Quickedit').val(sectionContent);
                        $('#Wikiplus-Quickedit-Summary-Input').val(summary);
                        //事件绑定
                        //返回
                        $('#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 class="mw-body-content">' + data + '</div><hr>');
                                        $('#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()));
                                        self.sendStatistic(sectionTargetName, useTime);
                                        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));
                                                self.sendStatistic(sectionTargetName, 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(e) {
                                        $('.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: 'simpleRedirector',
                value: function simpleRedirector() {
                    var self = this;
                    self.addFunctionButton(i18n('redirect_from'), 'Wikiplus-SR-Intro', function () {
                        var input = $('<input>').addClass('Wikiplus-InterBox-Input');
                        var applyBtn = $('<div>').addClass('Wikiplus-InterBox-Btn').attr('id', 'Wikiplus-SR-Apply').text(i18n('submit'));
                        var cancelBtn = $('<div>').addClass('Wikiplus-InterBox-Btn').attr('id', 'Wikiplus-SR-Cancel').text(i18n('cancel'));
                        var continueBtn = $('<div>').addClass('Wikiplus-InterBox-Btn').attr('id', 'Wikiplus-SR-Continue').text(i18n('continue'));
                        var content = $('<div>').append(input).append($('<hr>')).append(applyBtn).append(cancelBtn); //拼接
                        self.createDialogBox(i18n('redirect_desc'), content, 600, function () {
                            applyBtn.click(function () {
                                if ($('.Wikiplus-InterBox-Input').val() != '') {
                                    var title = $('.Wikiplus-InterBox-Input').val();
                                    $('.Wikiplus-InterBox-Content').html('<div class="Wikiplus-Banner">' + i18n('submitting_edit') + '</div>');
                                    self.kotori.redirectFrom(title, self.kotori.pageName, {
                                        success: function success() {
                                            $('.Wikiplus-Banner').text(i18n('redirect_saved'));
                                            $('.Wikiplus-InterBox').fadeOut(300);
                                            location.href = mw.config.get('wgArticlePath').replace(/\$1/ig, title);
                                        },
                                        fail: function fail(e) {
                                            $('.Wikiplus-Banner').css('background', 'rgba(218, 142, 167, 0.65)');
                                            $('.Wikiplus-Banner').text(e.message);
                                            if (e.number === 1018) {
                                                // 目标页面已经存在 确认哟
                                                $('.Wikiplus-InterBox-Content').append($('<hr>')).append(continueBtn).append(cancelBtn);
                                                continueBtn.click(function () {
                                                    $('.Wikiplus-InterBox-Content').html('<div class="Wikiplus-Banner">' + i18n('submitting_edit') + '</div>');
                                                    self.kotori.redirectFrom(title, self.kotori.pageName, {
                                                        success: function success() {
                                                            $('.Wikiplus-Banner').text(i18n('redirect_saved'));
                                                            $('.Wikiplus-InterBox').fadeOut(300);
                                                            location.href = mw.config.get('wgArticlePath').replace(/\$1/ig, title);
                                                        },
                                                        fail: function fail(e) {
                                                            $('.Wikiplus-Banner').css('background', 'rgba(218, 142, 167, 0.65)');
                                                            $('.Wikiplus-Banner').text(e.message);
                                                        }
                                                    }, true);
                                                });
                                                cancelBtn.click(function () {
                                                    $('.Wikiplus-InterBox-Close').click();
                                                });
                                            }
                                        }
                                    });
                                } else {
                                    self.showNotice.create.warning(i18n('empty_input'));
                                }
                            });
                            $('#Wikiplus-SR-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: 'checki18nCache',
                value: function checki18nCache() {
                    if (localStorage.Wikiplus_i18nCache) {
                        try {
                            var _i18nData = JSON.parse(localStorage.Wikiplus_i18nCache);
                            for (var languages in _i18nData) {
                                if (_i18nData[languages]['__version'] === this.langVersion) {
                                    i18nData[_i18nData[languages]['__language']] = _i18nData[languages];
                                } else {
                                    console.log('多语言文件[' + languages + ']已经过期');
                                    loadLanguage(_i18nData[languages]['__language']); //尝试重新取
                                }
                            }
                        } catch (e) {
                            throwError('cant_parse_i18ncache');
                        }
                    } else {
                        localStorage.Wikiplus_i18nCache = JSON.stringify(i18nData);
                    }
                }
 
                /**
                 * 为所有可能的编辑链接加上快速编辑按钮
                 */
            }, {
                key: 'editEveryWhere',
                value: function editEveryWhere() {
                    var self = this;
                    $('#mw-content-text a.external').each(function (i) {
                        var url = $(this).attr('href');
                        var reg = /(([^?&=]+)(?:=([^?&=]*))*)/g;
                        var params = {},
                            match;
                        while (match = reg.exec(url)) {
                            try {
                                params[match[2]] = decodeURIComponent(match[3]);
                            } catch (e) {
                                // cannot decode
                                params[match[2]] = match[3];
                            }
                        }
                        if (params.action === 'edit' && params.title !== undefined && params.section !== 'new') {
                            $(this).after($('<a>').attr({
                                'href': 'javascript:void(0)',
                                'class': 'Wikiplus-Edit-EveryWhereBtn'
                            }).text('(' + i18n('quickedit_sectionbtn') + ')').data({
                                'target': decodeURIComponent(params.title),
                                'number': params.section || -1
                            }));
                        }
                    });
                    $('.Wikiplus-Edit-EveryWhereBtn').click(function () {
                        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 ? new Function() : arguments[3];
 
                    if ($('.Wikiplus-InterBox').length > 0) {
                        $('.Wikiplus-InterBox').each(function () {
                            $(this).remove();
                        });
                    }
                    var clientWidth = window.innerWidth;
                    var clientHeight = window.innerHeight;
                    var dialogWidth = Math.min(clientWidth, width);
                    var diglogBox = $('<div>').addClass('Wikiplus-InterBox').css({
                        'margin-left': clientWidth / 2 - dialogWidth / 2,
                        '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>').addClass('mw-list-item mw-list-item-js').attr('id', id);
                    var href = $('<a>').attr('href', 'javascript:void(0);');
                    button = mw.config.get('skin') === 'minerva' ? button.addClass('toggle-list-item').append(href.addClass('toggle-list-item__anchor').append($('<span>').addClass('mw-ui-icon mw-ui-icon-portletlink-' + id.toLowerCase())).append($('<span>').addClass('toggle-list-item__label').text(text))) : mw.config.get('skin') === 'vector' ? button.append(href.append($('<span>').text(text))) : button.append(href.text(text));
                    if (mw.config.get('skin') === 'minerva') {
                        if ($('#p-tb').length > 0) {
                            $('#p-tb').append(button);
                            $('#' + id).click(clickEvent);
                        }
                    } else if ($('#p-cactions').length > 0) {
                        $('#p-cactions ul').append(button);
                        $('#' + id).find('a').click(clickEvent);
                    } else {
                        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 || new Function();
                    callback.fail = callback.fail || new Function();
                    var self = this;
                    if (config.oldid !== undefined) {
                        // 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, $.extend({
                        section: section === -1 ? '' : section
                    }, config));
                }
 
                /**
                 * 提交统计数据
                 * @param {string} title 页面名
                 * @param {interger} useTime 用时 单位毫秒
                 */
            }, {
                key: 'sendStatistic',
                value: function sendStatistic(title, useTime) {
                    if (title === undefined) title = mw.config.get('wgPageName');
 
                    if (localStorage.Wikiplus_SendStatistics === 'True') {
                        $.ajax({
                            url: scriptPath + '/statistics/api/submit',
                            type: 'POST',
                            dataType: 'json',
                            data: {
                                'wikiname': mw.config.get('wgSiteName'),
                                'usetime': useTime,
                                'username': mw.config.get('wgUserName'),
                                'pagename': title
                            },
                            success: function success(data) {
                                //提交成功
                            }
                        });
                    }
                }
 
                /**
                 * 检查安装
                 * @param {function} callback 回调函数
                 */
            }, {
                key: 'checkInstall',
                value: function checkInstall(callback) {
                    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();
                            });
                        };
                        var notice = $('<div>').text(i18n('install_tip').replace(/\$1/ig, mw.config.get('wgSiteName'))).attr('id', 'Wikiplus-InterBox-Content');
                        var applyBtn = $('<div>').addClass('Wikiplus-InterBox-Btn').attr('id', 'Wikiplus-Setting-Apply').text(i18n('accept'));
                        var cancelBtn = $('<div>').addClass('Wikiplus-InterBox-Btn').attr('id', 'Wikiplus-Setting-Cancel').text(i18n('decline'));
                        var content = $('<div>').append(notice).append($('<hr>')).append(applyBtn).append(cancelBtn); //拼接
                        self.createDialogBox('安装Wikiplus', content, 600, function () {
                            $('#Wikiplus-InterBox-Content').css('text-align', 'left');
                            $('#Wikiplus-Setting-Apply').click(function () {
                                localStorage.Wikiplus_SendStatistics = 'True';
                                install();
                            });
                            $('#Wikiplus-Setting-Cancel').click(function () {
                                localStorage.Wikiplus_SendStatistics = 'False';
                                install();
                            });
                        });
                    }
                }
 
                /**
                 * 获取设置值
                 * @param {string} key 键名
                 * @param {object} object 传入可用参数
                 */
            }, {
                key: 'getSetting',
                value: function getSetting(key, object) {
                    var w = object;
                    try {
                        var 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() {
                    var self = this;
                    mw.hook('wikipage.content').add(function (item) {
                        if (item.attr('id') === 'mw-content-text') {
                            self.initQuickEdit(); //加载快速编辑
                            !self.getSetting('disableEditEveryWhere') && self.editEveryWhere(); //任意编辑
                        }
                    });
                    this.editSettings(); //编辑设置
                    this.simpleRedirector(); //快速重定向
                    this.preloadEventBinding(); //预读取
                }
            }, {
                key: 'initRecentChangesPageFunctions',
                value: function initRecentChangesPageFunctions() {}
            }, {
                key: 'initAdvancedFunctions',
                value: function initAdvancedFunctions() {}
            }]);
 
            function Wikiplus() {
                _classCallCheck(this, Wikiplus);
 
                this.version = '2.3.10';
                this.langVersion = '212';
                this.releaseNote = '修正一些问题';
                this.notice = new MoeNotification();
                this.inValidNameSpaces = [-1, 8964];
                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);
                //载入CSS
                $('head').append('<link>');
                $('head').children(':last').attr({
                    rel: 'stylesheet',
                    type: 'text/css',
                    href: scriptPath + '/wikiplus.css'
                });
                //一些初始化工作
                this.preloadData = {};
                this.checkInstall(); //安装检查
                //语言检测
                var language = this.getSetting('language') && this.getSetting('language').toLowerCase() || window.navigator.language.toLowerCase();
                //版本检查
                if (this.version !== localStorage.Wikiplus_Version) {
                    localStorage.Wikiplus_Version = this.version;
                    this.notice.create.success('Wikiplus ' + this.version);
                    this.notice.create.success(language === 'zh-cn' ? this.releaseNote : 'Minor bug fixes'); // 避免给其他语言用户不必要的理解困难
                }
                if (i18nData[language] === undefined) {
                    loadLanguage(language);
                }
                //真正的初始化
                if (!this.inValidNameSpaces.includes(mw.config.get('wgNamespaceNumber')) && mw.config.get('wgIsArticle') && mw.config.get('wgAction') === 'view') {
                    this.kotori = new Wikipage();
                    this.checki18nCache();
                    this.initBasicFunctions();
                } else {
                    console.log('不符合加载条件 Wikiplus终止');
                }
            }
 
            return Wikiplus;
        })();
 
        window.Wikiplus = new Wikiplus();
    });
});

评论

请输入您的评论. 可以使用维基语法:
V J F N R
 
wikiplus.txt · 最后更改: 2024/01/23 19:21 由 doge24190