“User:Irukaza/common.css”与“User:Irukaza/common.js”:页面之间的差异

H萌娘,万物皆可H的百科全书!
< User:Irukaza(页面间差异)
跳到导航 跳到搜索
imported>=海豚=
无编辑摘要
 
imported>=海豚=
(创建页面,内容为“→‎global mediaWiki:​ (function(mw) { if (!String.prototype.includes) String.prototype.includes = function includes(search, start) { 'use strict';…”
 
第1行: 第1行:
#ca-conv{
/* global mediaWiki */
float: right;
(function(mw) {
}
   if (!String.prototype.includes) String.prototype.includes = function includes(search, start) {
     'use strict';
     if (typeof start !== 'number') start = 0;
     if (start + search.length > this.length) return false;
     return this.indexOf(search, start) !== -1;
   };
   mw.loader.implement('AnnToolsSendWelcomeMessage', function() {
     var message = '{{Welcome}}',
       errorFun = function errorFun(_, self) {
         unbindFun();
         self.addClass('unsend');
         return false;
       },
       unbindFun = function unbindFun() {
         if ($('#welcomeClear').length > 0) $('#welcomeClear').remove();
         $('#welcomeAsk').append('<span id="welcomeClear">返回</span>');
         $('#welcomeClear').on('click.welcome', function() {
           $('#welcomeAsk').remove();
         });
       };
     if (mw.config.get('wgNamespaceIds').user_talk == mw.config.get('wgNamespaceNumber') && !mw.config.get('wgPageName').includes('/') && mw.config.get('wgEditMessage') == 'creating' && $('#wpTextbox1')[0] && !$('#wpTextbox1').val()) $('#wpTextbox1').val(message);
 
     function check(that, onClick) {
       if (!$(that).is('#mw-content-text a.new')) return;
       if (!/(?=title\=user\_talk\:)[^\&]+/i.test(that.href)) return;
       var self = $(that),
         href = self.attr('href'),
         userName = decodeURIComponent(href.match(/(?=user\_talk\:)[^\&]+/i)[0].replace(/user_talk\:/i, ''));
       if (href.includes('User_talk') && href.includes('redlink=1') && href.includes('action=edit') && !userName.includes('/')) {
         self.addClass('sendWelcomeMessageLink unsend nopopus').on('click.sendWelcomeMessage', function() {
           if ($('#welcomeAskFinished')[0]) $('#welcomeClear').click();
           if ($('#welcomeAsk')[0]) {
             self.after('<span class="welcomeAsk">一次只能发送一份欢迎辞哦,不要太贪心了~<span id="welcomeClear2">返回</span></span>');
             $('#welcomeClear2').on('click.welcome', function() {
               $(this).parent().remove();
             });
             return false;
           }
           if (/[&\/]+/.test(userName)) {
             window.open(href, '_blank');
             return errorFun('地址解析出错!\n原地址:' + href + ',解析用户讨论页标题结果:User talk:' + userName, self);
           }
           self.removeClass('unsend').after('<span id="welcomeAsk">你想直接发送欢迎辞还是访问该未创建页面?<span id="welcomeYes">发送欢迎辞</span> · <span id="welcomeNo">访问该页面</span> · <span id="welcomeClear">返回</span></span>');
           $('#welcomeNo').on('click.welcome', function() {
             window.open(href, '_blank');
           });
           $('#welcomeClear').on('click.welcome', function() {
             $('#welcomeAsk').remove();
           });
           $('#welcomeYes').on('click.welcome', function() {
             var api = new mw.Api();
             $('#welcomeAsk').empty().append('正在通信中……');
             api.postWithToken('csrf', {
               'action': 'edit',
               'format': 'json',
               'title': 'User talk:' + userName,
               'summary': 'Welcome to MoegirlPedia',
               'text': message,
               'tags': 'Welcome to MoegirlPedia',
               'createonly': true
             }).then(function(data) {
               $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">通信成功!继续努力哦~</span>');
               console.debug('和萌百服务器通信成功,编辑成功! \n编辑详情:' + JSON.stringify(data).replace(/[{}\"]/g, '').replace(/\:\,/, ',') + '。');
               unbindFun();
               $('#mw-content-text a.new[href="' + href + '"]').removeClass('new sendWelcomeMessageLink unsend').attr('href', '/User_talk:' + userName).off('click.sendWelcomeMessage'); //js<a>对象的href是绝对url……
             }, function(f, s) {
               /*
               * 第一个参数是错误代码,如果是连接错误值为httpss,如果是后端错误值为articleexists等;
               * 第二个参数是错误信息对象,如果是连接错误值为{ xhr: JQueryXHR, exception: String, textStatus: String },如果是后端错误值为后端返回的内容;
               * 如果是后端错误,第三个参数与第二个参数目视一致;
               * 如果是后端错误,第四个参数则是jQueryXHR。
               */
               console.debug('sendWelcomeMessage');
               console.debug.apply(console, arguments);
               if (f === 'internal_api_error_Exception') {
                 $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">通信成功!继续努力哦~</span>');
                 console.debug('和萌百服务器通信成功,编辑成功! \n萌百服务器返回"internal_api_error_Exception",你们都懂的_(:3 」∠ )_ 。');
                 unbindFun();
                 $('#mw-content-text a.new[href="' + href + '"]').removeClass('new sendWelcomeMessageLink unsend').attr('href', '/User_talk:' + userName).off('click.sendWelcomeMessage'); //js<a>对象的href是绝对url……
               } else if (f === 'articleexists') {
                 $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">通信成功!该讨论页已经存在,请注意哦~</span>');
                 errorFun('和萌百服务器通信成功,但编辑失败!\n编辑详情:' + JSON.stringify(s).replace(/[{}\"]/g, '').replace(/\:\,/g, ','), self);
                 unbindFun();
                 $('#mw-content-text a.new[href="' + href + '"]').removeClass('new sendWelcomeMessageLink unsend').attr('href', '/User_talk:' + userName).off('click.sendWelcomeMessage'); //js<a>对象的href是绝对url……
               } else {
                 var reason = '';
                 var object = s.error || s;
                 for (var i in object) {
                   if (['*', 'xhr'].indexOf(i) !== -1) {
                     if (reason) reason += ', ';
                     reason += i + ': ' + JSON.stringify(object[i]).replace(/[{}\"]/g, '').replace(/\:\,/g, ',');
                   }
                 }
                 if (typeof f === 'string') reason = f + '(' + reason + '. )';
                 else reason += '. ';
                 $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">正在通信中……失败!请重试!【 ' + reason + '】</span>');
                 errorFun('和萌百服务器通信成功,但编辑失败!\n编辑详情:' + JSON.stringify(s).replace(/[{}\"]/g, '').replace(/\:\,/g, ','), self);
                 unbindFun();
                 self.addClass('unsend');
               }
             });
           });
           return false;
         });
         if (onClick) self.trigger('click.sendWelcomeMessage');
         return false;
       }
     }
     $(document.body).on('click', function(event) {
       check(event.target, true);
     });
     $('#mw-content-text a.new').each(function() {
       check(this);
     });
     $("<style>#welcomeAsk,.welcomeAsk{border:#bbeeff 1px solid;margin:0 3px 0 7px} #welcomeYes,#welcomeNo,#welcomeClear,#welcomeClear2{cursor:pointer;color:purple}.sendWelcomeMessageLink.unsend:after{content:'S';color:purple;line-height:1;vertical-align:super;font-size:smaller}.sendWelcomeMessageLink{text-decoration:none!important}</style>").appendTo("head");
   });
})(mediaWiki);
//</pre>
//Explanations for this javaScript code in https://zh.moegirl.org/User:AnnAngela/js
// <pre>
(function(mw) {
   mw.loader.implement('AnnToolsMWPanel', function($, jQuery) {
     $('#t-upload').after('<li id="t-expandtemplates"><a href="//www.hmoegirl.com/index.php?title=Special:%E5%B1%95%E5%BC%80%E6%A8%A1%E6%9D%BF&wpRemoveComments=1&wpInput={{' + mw.config.get("wgPageName") + '}}">展开模板</a></li><li id="t-Prefixindex"><a href="https://www.hmoegirl.com/index.php?title=Special%3A前缀索引&prefix=' + mw.config.get("wgTitle") + '&namespace=' + mw.config.get("wgNamespaceNumber") + '">前缀页面</a></li><li id="t-pagelog"><a href="//www.hmoegirl.com/index.php?title=Special:%E6%97%A5%E5%BF%97&page=' + mw.config.get("wgPageName") + '">页面日志</a></li><li id="t-replacetext" class="sysop-show"><a href="/Special:替换文本">替换文本</a></li>');
     $('#n-recentchanges').after('<li id="n-log"><a href="/Special:log" title="所有日志">所有日志</a></li><li id="n-ListDuplicatedFiles"><a href="/Special:ListDuplicatedFiles" title="重复文件">重复文件</a></li><style>/* 配合左栏 */#t-expandtemplates, #t-userlog, .ns-2 #t-pagelog, .ns-3 #t-pagelog, .ns--1 #t-pagelog {display:none;}.ns-10 #t-expandtemplates, .ns-2 #t-userlog, .ns-3 #t-userlog {display:list-item!important;}');
     $('#t-log a').text("用户日志");
   });
})(mediaWiki);
// </pre>
$(function(){
// 小头像放大镜
setTimeout(function(){
$('.userlink-avatar').hover(function(){
var imgUrl = $(this).find('.userlink-avatar-small:first').attr('src')
var container = $('<div id="userHeadMagnifier" style="display:inline-block; padding:10px; background:white; border:1px black solid; position:absolute; top:-139px; left:-135px;">')
.append('<img src="' + imgUrl + '" width="128">')
$(this).css('position', 'relative').append(container)
}, function(){
$(this).css('position', 'static').find('#userHeadMagnifier').remove()
})
}, 1000)
// 阻止复制时添加版权信息
$('#mw-content-text').off('copy')
// action=purge页面自动点击刷新
if(! location.search){
$("#p-cactions ul").append('<li id="btn-renovate"><a title="刷新此页">刷新此页</a></li>')
$('#btn-renovate').click(function(){
mw.notify('刷新中...', { type : 'warn' })
var url = decodeURIComponent(location.href)
var pageName = url.replace(/^https:\/\/www.hmoegirl.com\/(.+)$/, '$1')
var api = new mw.Api()
var deferredTimeoutKey = 0
$.ajax({
url: 'https://www.hmoegirl.com/api.php',
type: 'post',
timeout: 10000,
data: {
"action": "purge",
"format": "json",
"titles": pageName
}
}).done(function(){
location.reload(true)
}).fail(function(e){
mw.notify('网络错误,刷新失败!', { type : 'error' })
})
})
}
// tab键改为输出2个空格
$('#wpTextbox1').keydown(function(e){
if(e.keyCode == 9){
e.preventDefault()
var position = this.selectionStart,
left = this.value.substring(0, position),
right = this.value.substring(position),
code = left + '  ' + right
this.value = code
this.selectionStart = this.selectionEnd = position + 2
}
})
// AJAX编辑预览代替方案(快捷键为:ctrl + shift + s)
if(/((?!\.css|\.js|模块|module).+)action=(edit|submit)/.test(location.href)){
setTimeout(function(){
$('#wikiEditor-ui-toolbar .tabs').append($('<span id="edit-ajaxPreviewBtn" class="tab"><a href="#" role="button" aria-pressed="false">预览</a></span>'))
$('#edit-ajaxPreviewBtn').click(foo)
}, 3000)
var removeBtn = $('<div id="edit-ajaxPreviewRm" style="width:43px; height:30px; text-align:center; line-height:30px; color:black; font-size:26px; background:white; box-shadow:0 0 5px black; opacity:0.8; position:fixed; top:20px; right:0; cursor:pointer; display:none; z-index:1001;">×</div>')
.click(function(){
viewHide()
})
$('body').append(removeBtn)
var saveBtn = $('<div id="edit-ajaxPreviewSave" style="width:43px; height:30px; text-align:center; line-height:30px; color:black; font-size:26px; background:white; box-shadow:0 0 5px black; opacity:0.8; position:fixed; top:73px; right:0; cursor:pointer; display:none; z-index:1001;">√</div>')
.click(function(){
$('#wpSave').click()
})
$('body').append(saveBtn)
 
var requestTimeoutKey = 0,
deferred = null
function viewHide(){
deferred && deferred.abort()
clearTimeout(requestTimeoutKey)
$('#edit-ajaxPreview').remove()
$('#edit-ajaxPreviewRm').hide()
$('#edit-ajaxPreviewSave').hide()
$('body').css('overflow', 'visible')
}
$(window).keydown(function(e){
if(e.ctrlKey && e.keyCode == 83){
if($('#edit-ajaxPreview').length){
viewHide()
}else{
foo(e)
}
}
})
var api = new mw.Api()
function foo(e){
var previewElement = $('<div id="edit-ajaxPreview" style="width:90%; min-width:800px; height:90%; min-height:400px; padding:15px; background:white; box-shadow:0 0 15px #666; overflow:auto; position:fixed; margin:auto; top:0; left:0; right:0; bottom:0; z-index:1000;">').append('<span id="edit-ajaxPreview-LoadingMsg" style="font-size:30px; position:fixed; top:50%; left:50%; transform:translate(-50%, -50%);">获取预览中...</span>')
$('body').append(previewElement)
 
var wikiText = $('#wpTextbox1').val(),
titleName = decodeURIComponent(location.href.replace(/^.+[?&]title=([^&]+)&.+$/, '$1'))
$('#edit-ajaxPreviewRm').show()
$('#edit-ajaxPreviewSave').show()
$('body').css('overflow', 'hidden')
deferred = api.post({
"action": "parse",
"format": "json",
"text": wikiText,
"title": titleName,
"contentmodel": "wikitext"
}).done(function(data){
$('#edit-ajaxPreview').html($(data.parse.text['*']).addClass('mw-body-content'))
})
requestTimeoutKey = setTimeout(function(){
if(deferred.state() != 'resolved'){
viewHide()
foo(e)
}
}, 8000)
return false
}
}
// ctrl + alt快速添加变量命名空间
if (mw.config.values.wgAction == "edit" || mw.config.values.wgAction == "submit"){
var editor = $('#wpTextbox1')
var title = mw.config.values.wgTitle.replace(/./, function(s){
return s.toLowerCase()
})
editor.keydown(function(e){
if(e.ctrlKey && e.altKey){
editor.val(editor.val().replace(/(\{\{#var(define|):)([^\|\}]+)/g, function(s, s1, s2, s3){
if(!new RegExp('^' + title + '\\.').test(s3)){
if(['num', 'key', 'value', 'time', 'times'].includes(s3)){ return s }
return s1 + title + '.' + s3
}
return s
}))
mw.notify('已添加变量命名空间。')
}
})
}
})
 
// $.getScript("/User:Imbushuo/MonacoEditor/MediaWikiTokenizer.js‎?action=raw&ctype=text/javascript",
// function (data, textStatus, jqxhr) {
//   $.getScript("/User:imbushuo/MediaWikiLint.js‎?action=raw&ctype=text/javascript",
//   function (data, textStatus, jqxhr) {
//     // Loader for Monaco editor
//     mw.loader.load('https://zh.moegirl.org/User:Imbushuo/MonacoEditor.js?action=raw&ctype=text/javascript');
//   });
// });
 
 
// 搜索引擎代替方案
/*
$(function(){
var input = $('#searchInput').attr('placeholder', '搜索萌娘百科')
$('#searchButton').off().on('click', function() {
   var keyword = input.val();
   if (!keyword) window.alert('请输入关键词后再行搜索!');
   else {
     var self = $(this),
       check_url = 'https://hmoegirl.com/' + keyword,
       open_url = 'https://www.bing.com/search?q=' + encodeURIComponent(keyword) + '+site%3Azh.hmoegirl.com&ie=UTF-8';
     self[0].disabled = true;
     self.data({
       'background-image': self.css('background-image'),
       'background-size': self.css('background-size')
     });
     self.css({
       'background-image': 'url(https://static.mengniang.org/common/d/d1/Windows_10_loading.gif)',
       'background-size': '80%'
     });
     $.ajax({
       url: check_url,
       type: 'HEAD',
       success: function(_, __, response) {
         if (response.status < 400) location.href = check_url;
         else this.error();
       },
       error: function() {
         location.href = open_url
       },
       complete: function() {
         self[0].disabled = false;
         self.css(self.data());
       }
     });
   }
   return false;
});
})
*/
mw.loader.load('MediaWiki:Gadget-DotsSyntaxHighlighter.js');
/* 给wikiplus添加快速填写摘要 */
$(function () {
   var observar = new MutationObserver(function (record) {
     if ($('.Wikiplus-InterBox').find('#Wikiplus-Quickedit-Summary-Input')[0] &&
       (!$('.Wikiplus-InterBox').find('#summary_list')[0])) {
       var list = ['新条目', '修饰语句', '修正笔误', '内容扩充', '排版', '内部链接', '分类', '消歧义', '萌百化']
       var summary = document.createElement('span')
       summary.id = 'summary_list';
       summary.style.marginLeft = '0.5em';
       for (var i = 0; i < list.length; i++) {
         if (i != 0) summary.innerHTML += ' | ';
         summary.innerHTML += '<a href="#.">' + list[i] + '</a>';
       }
       $('.Wikiplus-InterBox').find('#Wikiplus-Quickedit-Summary-Input')[0].after(summary);
       $('#summary_list').children().each(function () {
         $(this)[0].onclick = function () {
           var str = $('#Wikiplus-Quickedit-Summary-Input')[0].value;
           if (/\/\/ Edit via Wikiplus\s*$/.test(str)) {
             $('#Wikiplus-Quickedit-Summary-Input')[0].value = str.replace(/^(.*?)( ?\/\/ Edit via Wikiplus\s*)$/, '$1 ' + $(this)[0].innerText + ' // Edit via Wikiplus');
           } else {
             $('#Wikiplus-Quickedit-Summary-Input')[0].value += ' ' + $(this)[0].innerText;
           }
         };
       });
     }
   });
   observar.observe(document.body, { childList: true });
});
/*
注意:该插件必须依附于Wikiplus才能生效。
载入后将在Wikiplus快速编辑的界面中添加一个“+”加号按钮,点击后可以新建快速替换的方案,完成后将生成一个按钮。
在名称栏中,输入#号后面的文字将作为摘要使用,在执行匹配成功后将自动把摘要的文字置于编辑摘要栏中。
在替换栏中可以使用 _@br_ 来指代换行,无论是否为正则模式。
左键点击按钮执行预先设置好的替换,右键点击按钮删除该替换方案。
注意:替换方案保存在当前浏览器中,而不是帐号内,若更换浏览器、更换电脑或清除缓存等,替换方案将不会同步。
*/
$(function(){
if(typeof MutationObserver == 'undefined'){
mw.notify('你使用的浏览器版本过低或不符合规范,无法使用Wikiplus-replace插件!', { type : 'warn' })
return false
}
var topBtn = document.getElementById('Wikiplus-Edit-TopBtn')
topBtn && topBtn.addEventListener('click', function(e){
if($('.Wikiplus-InterBox').length == 1){
$('.Wikiplus-InterBox').remove()
}
}, true)
   $.each(document.getElementsByClassName('mw-editsection'), function(index, value){
     value.addEventListener('click', function(e){
       if(e.target.classList.contains('Wikiplus-Edit-SectionBtn') && $('.Wikiplus-InterBox').length == 1){
     $('.Wikiplus-InterBox').remove()
     }
     }, true)
   })
   var observar = new MutationObserver(function(record){
     var wikiplus = null
     var wikiplusTextarea = $('#Wikiplus-Quickedit')
     $.each(record[0].addedNodes, function(item, element){
       if(element.classList && element.classList.contains('Wikiplus-InterBox')){
         wikiplus = element
       }
     })
     if(wikiplus){
     var br = '\n' //用于快捷指代替换中的换行
       $(wikiplus).find('.Wikiplus-InterBox-Content')
       .find('div:first').find('#Wikiplus-Quickedit-Jump')
       .after('<span id="Wikiplus-Quickedit-addReplace" class="Wikiplus-Btn">✚</span>')
 
       $(wikiplus).contextmenu(function(){ return false })
 
       if(localStorage.getItem('Quickedit-replace')){
         var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
         $.each(replaceData, function(item, data){
           var newButton = $('<span class="Wikiplus-Btn" data-id="' + data[3] + '">' + data[0] + '</span>')
           newButton.mousedown(function(e){
             if(e.which == 1){
               var code = wikiplusTextarea.val()
               var newCode = code.replace(new RegExp(data[1], 'gm'), data[2] ? data[2] : '')
               .replace(/_@br_/g ,br)
               if(code == newCode){
                 mw.notify('匹配结果为空!', { type : 'warn' })
               }else{
                 wikiplusTextarea.val(newCode)
                 data[4] && $('#Wikiplus-Quickedit-Summary-Input').val(data[4])
                 mw.notify('已完成替换!')
               }
             }
            
             if(e.which == 3){
               var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
               .filter(function(repData){
                 return repData[3] != $(e.target).data('id')
               })
               localStorage.setItem('Quickedit-replace', JSON.stringify(replaceData))
               $(this).remove()
             }
           })
           $(wikiplus).find('.Wikiplus-InterBox-Content')
           .find('div:first').find('.Wikiplus-Btn:last').after(newButton)
         })
       }
 
       $('#Wikiplus-Quickedit-addReplace').click(function(){
         var addReplaceHTML = '\
         <div id="Wikiplus-Quickedit-replace" style="width:400px; background:#EDF9F7; border:1px #666 solid; font-size:80%; box-shadow: 2px 2px 5px #aaa; overflow:hidden; padding:5px; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; z-index:300;">\
         <div style="padding:10px; padding-bottom:0;">添加快速替换<div class="Quickedit-replace-hide" style="float:right; font-size:26px; font-weight:bold; margin-top:-8px; -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; cursor:pointer">×</div></div>\
         <hr style="height:1px; margin-bottom:-5px; background:#66CCFF; border:none;">\
         <div style="height:110px; border-radius:3px; padding:10px;">\
           <p>名称:<input id="Quickedit-replace-Name" style="width:300px; height:25px; text-indent:3px;"></p>\
           <p>查找:<input id="Quickedit-replace-Lookup" style="width:300px; height:25px; text-indent:3px;"></p>\
           <p>替换:<input id="Quickedit-replace-Replace" style="width:300px; height:25px; text-indent:3px;"></p>\
           <p>正则模式:<input type="checkbox" id="Quickedit-replace-pattern" value="reg" style="width:16px; height:16px; position:relative; top:3px;">\
           <input class="Quickedit-replace-hide" type="button" value="关闭" style="float:right; width:50px; height:25px; background:white; box-shadow: 0 1px 2px #aaa; -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; margin:0 5px;">\
           <input id="Quickedit-replace-add" type="button" value="添加" style="float:right; width:50px; height:25px; background:white; box-shadow: 0 1px 2px #aaa; -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; margin:0 5px;"></p>\
         </div>\
         </div>'
         $(document.body).append(addReplaceHTML)
 
         var addReplace = $('#Wikiplus-Quickedit-replace'),
         name = $('#Quickedit-replace-Name'),
         lookup = $('#Quickedit-replace-Lookup'),
         replace = $('#Quickedit-replace-Replace'),
         patternSwitch = $('#Quickedit-replace-pattern'),
         hideBtn = $('.Quickedit-replace-hide'),
         addBtn = $('#Quickedit-replace-add')
 
         hideBtn.click(function(){
           addReplace.remove()
         })
 
         addBtn.click(function(){
           var text = name.val()
           if(/#/.test(text)){
           var note = text.replace(/(.+)#(.+)/, '$2')
           text = text.replace(/(.+)#(.+)/, '$1')
           }
           var pattern = lookup.val()
           var replaceText = replace.val()
           try{
             if(! patternSwitch.prop('checked')){
               pattern = pattern.replace(/([\\\(\)\[\]\{\}\+\.\*\^\$\!\?\|])/g,'\\$1')
             }
             new RegExp(pattern, 'gm')
           }catch(e){
             mw.notify('正则表达式有误,请核对后重新输入!', { type : 'error' })
             return false
           }
           var id = Math.random()
           if(localStorage.getItem('Quickedit-replace')){
             var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
             replaceData.push([text, pattern, replaceText, id, note || null])
             replaceData = JSON.stringify(replaceData)
             localStorage.setItem('Quickedit-replace', replaceData)
           }else{
             var replaceData = JSON.stringify([[text, pattern, replaceText, id, note || null]])
             localStorage.setItem('Quickedit-replace', replaceData)
           }
           var newButton = $('<span class="Wikiplus-Btn" data-id="' + id + '">' + text + '</span>')
           newButton.mousedown(function(e){
             if(e.which == 1){
               var code = wikiplusTextarea.val()
               var newCode = code.replace(new RegExp(pattern, 'gm'), replaceText ? replaceText : '')
               .replace(/_@br_/g ,br)
               if(code == newCode){
                 mw.notify('匹配结果为空!', { type : 'warn' })
               }else{
                 wikiplusTextarea.val(newCode)
                 note && $('#Wikiplus-Quickedit-Summary-Input').val(note)
                 mw.notify('已完成替换!')
               }
             }
 
             if(e.which == 3){
               var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
               .filter(function(repData){
                 return repData[3] != $(e.target).data('id')
               })
               localStorage.setItem('Quickedit-replace', JSON.stringify(replaceData))
               $(this).remove()
             }
           })
           $(wikiplus).find('.Wikiplus-InterBox-Content')
           .find('div:first').find('.Wikiplus-Btn:last').after(newButton)
           mw.notify('已添加新的替换方案!')
         })
 
       })
       $('#Wikiplus-Quickedit-Back, .Wikiplus-InterBox-Close').click(function(){
         $('#Wikiplus-Quickedit-replace').remove()
       })
     }
   })
   var options = {
     childList : true
   }
   observar.observe(document.body, options)
})
/*
载入该插件后,将对wikitext语法所使用的符号和html标签进行成对的补全。
该插件并不会计算整个源代码中的html标签配对情况,标签的补全仅发生在输入大于号(>)时,补全距离最近的html标签。
在输入无其他信息的标签后(如:<div></div>),若按下退格(backspace)键,可以直接删除这一组标签。
注意:因为每次输入时都会对整个源代码进行查找匹配,为了防止卡顿,默认限制为500个字符,但这会导致当标签过长(例如在节点上添加了大量css代码)时,无法自动补全。
过长的源代码会使输入时性能大幅下降,造成卡顿。当总字符数大于20000时,将自动关闭补全,请合理使用段落编辑的功能。
*/
 
$(function(){
   if(/action=(edit|submit)/.test(location.href)){
   var wpText = $('#wpTextbox1')
  
   if(wpText.val().length > 20000){
   mw.notify('因源代码过长,补全功能被关闭!', { type : 'warn' })
   return
   }
  
var retrospect = 500
var pattern = [
['-{', '}-'],
['[', ']'],
['{', '}'],
["'", "'"],
['"', '"'],
['(', ')'],
['<!--', '-->']
]
   //光标后插入信息
   function insertText(obj, str){
var content = obj.value,
position = obj.selectionEnd,
left = content.substring(0, position),
right = content.substring(position)
obj.value = left + str + right
   }
 
var original = null
wpText.one('click', function(){
original = {
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
}
})
   // 缓存输入内容 & 判断
var end = 0,
thisLength = 0,
lastLength = 0,
code = '',
thisCode = '',
deletedKeyword = '',
// 需要暂停补全的状态
typewritingMode = false,
cutPaste = false,
selectInput = false,
selectDelete = false,
inputFinish = false
var codeSave = [{
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
}],
inputMark = false
   function selectionReset(){
     end = wpText[0].selectionEnd
     lastLength = wpText.val().length
}
   wpText.click(function(){
     selectionReset()
   }).keyup(function(e){
     if(e.keyCode > 36 && e.keyCode < 41){
       selectionReset()
       code = ''
     }
   }).on('keydown keyup', function(e){
if(e.keyCode == 8){
var subStart = (this.selectionEnd - 1) < 0 ? 0 : (this.selectionEnd - 1)
var left = thisCode.substring(subStart, this.selectionEnd)
deletedKeyword = left
selectionReset()
}
}).on('compositionstart', function(){
typewritingMode = true
}).on('compositionend', function(){
typewritingMode = false
       inputFinish = true
       $(this).trigger('input')
       selectionReset()
}).on('cut paste', function(){
cutPaste = true
codeSave.push({
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
})
inputMark = false
setTimeout(selectionReset, 0)
}).on('keydown', function(e){
selectInput = !! document.getSelection().toString()
if(selectInput){ end = wpText[0].selectionStart}
if(selectInput && (e.keyCode == 8 || e.keyCode == 46)){ selectDelete = true }
}).on('input', function(){
;(function(_this){
         if(typewritingMode){ return }
         if(inputFinish){ inputFinish = false; return }
if(cutPaste){ cutPaste = false; return }
if(selectDelete){ selectDelete = false; return }
     thisCode = $(_this).val()
     var right = thisCode.substring(end)
     thisLength = $(_this).val().length
     if(thisLength - lastLength == 1 || selectInput){
code += right.substring(0, 1)
     }else{
       code = ''
      
       if(lastLength - thisLength == 1){
       var subStart = (_this.selectionEnd - 20) < 0 ? 0 : (_this.selectionEnd - 20),
       subEnd = (_this.selectionEnd + 20) > thisLength ? thisLength : (_this.selectionEnd + 20)
      
       var subLeft = thisCode.substring(0, subStart),
       subRight = thisCode.substring(subEnd)
      
       var left = thisCode.substring(subStart, _this.selectionEnd),
       right = thisCode.substring(_this.selectionEnd, subEnd),
       leftRE = /([\s\S]*)<(.+)$/,
rightRE = /^\<\/(.+?)>([\s\S]*)/
       var tagLeft = left.replace(leftRE, '$2')
var tagRight = right.replace(rightRE, '$1')
       if(tagLeft == tagRight){
       var leftCode = left.replace(leftRE, '$1')
       var rightCode = right.replace(rightRE, '$2')
       $(_this).val(subLeft + leftCode + rightCode + subRight)
       var cursorPos = new String(subLeft + leftCode).length
       _this.selectionStart = _this.selectionEnd = cursorPos
       }
$.each(pattern, function(){
var $this = wpText[0]
if(lastLength - thisLength == 1){
var subStart = $this.selectionEnd < 0 ? 0 : $this.selectionEnd
var subEnd = ($this.selectionEnd + 1) > thisLength ? thisLength : ($this.selectionEnd + 1)
$this.selectionEnd == subEnd && subEnd++
var subLeft = thisCode.substring(0, $this.selectionEnd),
subRight = thisCode.substring(subEnd)
var left = thisCode.substring(subStart, $this.selectionEnd),
right = thisCode.substring($this.selectionEnd, subEnd)
if(deletedKeyword == this[0] && right == this[1]){
$($this).val(subLeft + subRight)
$this.selectionStart = $this.selectionEnd = subLeft.length
selectionReset()
}
}
})
       }
      
     }
     function pair(keyword, char, num){
       if(code.indexOf(keyword) != -1){
var num = num || char.length
var position = wpText[0].selectionEnd
         insertText(wpText[0], char)
         wpText[0].selectionStart = wpText[0].selectionEnd = position
         selectionReset()
         code = ''
       }
     }
 
     function addPair(arr){
     $.each(arr, function(){
pair(this[0], this[1], this[2])
})
     }
       selectionReset()
     addPair(pattern)
      
// 配对标签
       if(code.indexOf('>') != -1){
       var start = (end - retrospect) < 0 ? 0 : (end - retrospect)
         var left = wpText.val().substring(start, end)
         var ptn = /[\s\S]*<((?!br|hr|img|references|templatestyles|\!--|\/|\>)[^\s<>]+)[^>]*?>$/
         if(ptn.test(left)){
var tagEnd = '</' + left.replace(ptn, '$1') + '>'
var position = wpText[0].selectionEnd
           insertText(wpText[0], tagEnd)
         wpText[0].selectionStart = wpText[0].selectionEnd = position
           selectionReset()
           code = ''            
         }         
       }
})(this)
      
codeSave.push({
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
})
inputMark = true      
input = false
})
wpText.on('keydown', function(e){
if(e.ctrlKey && e.keyCode == 90){
e.preventDefault()
if(inputMark){
codeSave.pop()
inputMark = false
}
var history = codeSave.pop() || original
if(history){
wpText.val(history.code).focus()
wpText[0].selectionStart = history.start
wpText[0].selectionEnd = history.end
}
}
})
   }
})
/*
这是一个保存编辑内容的小插件,载入后将在“显示更改”按钮后生成一个“还原备份”按钮。
萌百本身有一个缓存编辑的内容的插件,但是我用得感觉很迷,曾经两次在开了那个插件的情况下提交编辑后发生网络错误,
然而再次回到编辑页面后却无法还原,不知道是有Bug还是我没用好。
这个插件将在点击“提交编辑、显示预览、显示更改”中任意一个按钮时备份当前的编辑。当存在备份时,“还原备份”按钮变为可以点击。
备份会保存7天,7天后自动清除。
*/
$(function(){
  if(! /action=(edit|submit)/.test(location.href)){ return }
 
  var editBox = $('#wpTextbox1'),
  btns = $('#wpSaveWidget, #wpPreviewWidget, #wpDiffWidget'),
  title = decodeURIComponent(location.search.match(/title=([^&]+)/)[1]),
  backupList = JSON.parse(localStorage.getItem('Moegirl-koharubiyori-editBackup') || '{}')
 
  $.each(backupList, function(key, val){
  var time = new Date().getTime()
  if(val.expires < time){
  delete backupList[key]
  }
  })
 
setTimeout(function(){
  var backup = backupList[title]
  if(backup){
var btn = $('<span class="oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-buttonInputWidget"><input type="button" value="还原备份" class="oo-ui-inputWidget-input oo-ui-buttonElement-button" /></span>')
.click(function(){
editBox.val(backup.content)
   mw.notify('已还原备份!', { type: 'warn' })  
})  
  }else{
  var btn = $('<span class="oo-ui-widget oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-buttonInputWidget oo-ui-widget-disabled"><input type="button" value="还原备份" class="oo-ui-inputWidget-input oo-ui-buttonElement-button" disabled /></span>')
  }
  $('#wpDiffWidget').after(btn)
})
 
  btns.mousedown(function(e){
    var content = editBox.val()
  var expire = new Date().getTime() + 1000 * 60 * 60 * 24 * 7
  backupList[title] = {
  expires : expire,
  content : content
  }
  localStorage.setItem('Moegirl-koharubiyori-editBackup', JSON.stringify(backupList))
  })
})

2020年3月10日 (二) 16:13的版本

/* global mediaWiki */
(function(mw) {
    if (!String.prototype.includes) String.prototype.includes = function includes(search, start) {
        'use strict';
        if (typeof start !== 'number') start = 0;
        if (start + search.length > this.length) return false;
        return this.indexOf(search, start) !== -1;
    };
    mw.loader.implement('AnnToolsSendWelcomeMessage', function() {
        var message = '{{Welcome}}',
            errorFun = function errorFun(_, self) {
                unbindFun();
                self.addClass('unsend');
                return false;
            },
            unbindFun = function unbindFun() {
                if ($('#welcomeClear').length > 0) $('#welcomeClear').remove();
                $('#welcomeAsk').append('<span id="welcomeClear">返回</span>');
                $('#welcomeClear').on('click.welcome', function() {
                    $('#welcomeAsk').remove();
                });
            };
        if (mw.config.get('wgNamespaceIds').user_talk == mw.config.get('wgNamespaceNumber') && !mw.config.get('wgPageName').includes('/') && mw.config.get('wgEditMessage') == 'creating' && $('#wpTextbox1')[0] && !$('#wpTextbox1').val()) $('#wpTextbox1').val(message);

        function check(that, onClick) {
            if (!$(that).is('#mw-content-text a.new')) return;
            if (!/(?=title\=user\_talk\:)[^\&]+/i.test(that.href)) return;
            var self = $(that),
                href = self.attr('href'),
                userName = decodeURIComponent(href.match(/(?=user\_talk\:)[^\&]+/i)[0].replace(/user_talk\:/i, ''));
            if (href.includes('User_talk') && href.includes('redlink=1') && href.includes('action=edit') && !userName.includes('/')) {
                self.addClass('sendWelcomeMessageLink unsend nopopus').on('click.sendWelcomeMessage', function() {
                    if ($('#welcomeAskFinished')[0]) $('#welcomeClear').click();
                    if ($('#welcomeAsk')[0]) {
                        self.after('<span class="welcomeAsk">一次只能发送一份欢迎辞哦,不要太贪心了~<span id="welcomeClear2">返回</span></span>');
                        $('#welcomeClear2').on('click.welcome', function() {
                            $(this).parent().remove();
                        });
                        return false;
                    }
                    if (/[&\/]+/.test(userName)) {
                        window.open(href, '_blank');
                        return errorFun('地址解析出错!\n原地址:' + href + ',解析用户讨论页标题结果:User talk:' + userName, self);
                    }
                    self.removeClass('unsend').after('<span id="welcomeAsk">你想直接发送欢迎辞还是访问该未创建页面?<span id="welcomeYes">发送欢迎辞</span> · <span id="welcomeNo">访问该页面</span> · <span id="welcomeClear">返回</span></span>');
                    $('#welcomeNo').on('click.welcome', function() {
                        window.open(href, '_blank');
                    });
                    $('#welcomeClear').on('click.welcome', function() {
                        $('#welcomeAsk').remove();
                    });
                    $('#welcomeYes').on('click.welcome', function() {
                        var api = new mw.Api();
                        $('#welcomeAsk').empty().append('正在通信中……');
                        api.postWithToken('csrf', {
                            'action': 'edit',
                            'format': 'json',
                            'title': 'User talk:' + userName,
                            'summary': 'Welcome to MoegirlPedia',
                            'text': message,
                            'tags': 'Welcome to MoegirlPedia',
                            'createonly': true
                        }).then(function(data) {
                            $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">通信成功!继续努力哦~</span>');
                            console.debug('和萌百服务器通信成功,编辑成功! \n编辑详情:' + JSON.stringify(data).replace(/[{}\"]/g, '').replace(/\:\,/, ',') + '。');
                            unbindFun();
                            $('#mw-content-text a.new[href="' + href + '"]').removeClass('new sendWelcomeMessageLink unsend').attr('href', '/User_talk:' + userName).off('click.sendWelcomeMessage'); //js<a>对象的href是绝对url……
                        }, function(f, s) {
                            /*
                             * 第一个参数是错误代码,如果是连接错误值为httpss,如果是后端错误值为articleexists等;
                             * 第二个参数是错误信息对象,如果是连接错误值为{ xhr: JQueryXHR, exception: String, textStatus: String },如果是后端错误值为后端返回的内容;
                             * 如果是后端错误,第三个参数与第二个参数目视一致;
                             * 如果是后端错误,第四个参数则是jQueryXHR。
                             */
                            console.debug('sendWelcomeMessage');
                            console.debug.apply(console, arguments);
                            if (f === 'internal_api_error_Exception') {
                                $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">通信成功!继续努力哦~</span>');
                                console.debug('和萌百服务器通信成功,编辑成功! \n萌百服务器返回"internal_api_error_Exception",你们都懂的_(:3 」∠ )_ 。');
                                unbindFun();
                                $('#mw-content-text a.new[href="' + href + '"]').removeClass('new sendWelcomeMessageLink unsend').attr('href', '/User_talk:' + userName).off('click.sendWelcomeMessage'); //js<a>对象的href是绝对url……
                            } else if (f === 'articleexists') {
                                $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">通信成功!该讨论页已经存在,请注意哦~</span>');
                                errorFun('和萌百服务器通信成功,但编辑失败!\n编辑详情:' + JSON.stringify(s).replace(/[{}\"]/g, '').replace(/\:\,/g, ','), self);
                                unbindFun();
                                $('#mw-content-text a.new[href="' + href + '"]').removeClass('new sendWelcomeMessageLink unsend').attr('href', '/User_talk:' + userName).off('click.sendWelcomeMessage'); //js<a>对象的href是绝对url……
                            } else {
                                var reason = '';
                                var object = s.error || s;
                                for (var i in object) {
                                    if (['*', 'xhr'].indexOf(i) !== -1) {
                                        if (reason) reason += ', ';
                                        reason += i + ': ' + JSON.stringify(object[i]).replace(/[{}\"]/g, '').replace(/\:\,/g, ',');
                                    }
                                }
                                if (typeof f === 'string') reason = f + '(' + reason + '. )';
                                else reason += '. ';
                                $('#welcomeAsk').empty().append('<span id="welcomeAskFinished">正在通信中……失败!请重试!【 ' + reason + '】</span>');
                                errorFun('和萌百服务器通信成功,但编辑失败!\n编辑详情:' + JSON.stringify(s).replace(/[{}\"]/g, '').replace(/\:\,/g, ','), self);
                                unbindFun();
                                self.addClass('unsend');
                            }
                        });
                    });
                    return false;
                });
                if (onClick) self.trigger('click.sendWelcomeMessage');
                return false;
            }
        }
        $(document.body).on('click', function(event) {
            check(event.target, true);
        });
        $('#mw-content-text a.new').each(function() {
            check(this);
        });
        $("<style>#welcomeAsk,.welcomeAsk{border:#bbeeff 1px solid;margin:0 3px 0 7px} #welcomeYes,#welcomeNo,#welcomeClear,#welcomeClear2{cursor:pointer;color:purple}.sendWelcomeMessageLink.unsend:after{content:'S';color:purple;line-height:1;vertical-align:super;font-size:smaller}.sendWelcomeMessageLink{text-decoration:none!important}</style>").appendTo("head");
    });
})(mediaWiki);
//</pre>
//Explanations for this javaScript code in https://zh.moegirl.org/User:AnnAngela/js
// <pre>
(function(mw) {
    mw.loader.implement('AnnToolsMWPanel', function($, jQuery) {
        $('#t-upload').after('<li id="t-expandtemplates"><a href="//www.hmoegirl.com/index.php?title=Special:%E5%B1%95%E5%BC%80%E6%A8%A1%E6%9D%BF&wpRemoveComments=1&wpInput={{' + mw.config.get("wgPageName") + '}}">展开模板</a></li><li id="t-Prefixindex"><a href="https://www.hmoegirl.com/index.php?title=Special%3A前缀索引&prefix=' + mw.config.get("wgTitle") + '&namespace=' + mw.config.get("wgNamespaceNumber") + '">前缀页面</a></li><li id="t-pagelog"><a href="//www.hmoegirl.com/index.php?title=Special:%E6%97%A5%E5%BF%97&page=' + mw.config.get("wgPageName") + '">页面日志</a></li><li id="t-replacetext" class="sysop-show"><a href="/Special:替换文本">替换文本</a></li>');
        $('#n-recentchanges').after('<li id="n-log"><a href="/Special:log" title="所有日志">所有日志</a></li><li id="n-ListDuplicatedFiles"><a href="/Special:ListDuplicatedFiles" title="重复文件">重复文件</a></li><style>/* 配合左栏 */#t-expandtemplates, #t-userlog, .ns-2 #t-pagelog, .ns-3 #t-pagelog, .ns--1 #t-pagelog {display:none;}.ns-10 #t-expandtemplates, .ns-2 #t-userlog, .ns-3 #t-userlog {display:list-item!important;}');
        $('#t-log a').text("用户日志");
    });
})(mediaWiki);
// </pre>
$(function(){	
	// 小头像放大镜
	setTimeout(function(){
		$('.userlink-avatar').hover(function(){
			var imgUrl = $(this).find('.userlink-avatar-small:first').attr('src')
			var container = $('<div id="userHeadMagnifier" style="display:inline-block; padding:10px; background:white; border:1px black solid; position:absolute; top:-139px; left:-135px;">')
			.append('<img src="' + imgUrl + '" width="128">')
			
			$(this).css('position', 'relative').append(container)
		}, function(){
			$(this).css('position', 'static').find('#userHeadMagnifier').remove()
		})			
	}, 1000)
	
	// 阻止复制时添加版权信息
	$('#mw-content-text').off('copy')
	
	// action=purge页面自动点击刷新
	if(! location.search){
		$("#p-cactions ul").append('<li id="btn-renovate"><a title="刷新此页">刷新此页</a></li>')
		$('#btn-renovate').click(function(){
			mw.notify('刷新中...', { type : 'warn' })
			var url = decodeURIComponent(location.href)
			var pageName = url.replace(/^https:\/\/www.hmoegirl.com\/(.+)$/, '$1')
			var api = new mw.Api()
			var deferredTimeoutKey = 0
			$.ajax({
				url: 'https://www.hmoegirl.com/api.php',
				type: 'post',
				timeout: 10000,
				data: {
					"action": "purge",
					"format": "json",
					"titles": pageName
				}
			}).done(function(){
				location.reload(true)
			}).fail(function(e){
				mw.notify('网络错误,刷新失败!', { type : 'error' })
			})
		})
	}
	
	// tab键改为输出2个空格
	$('#wpTextbox1').keydown(function(e){
		if(e.keyCode == 9){
			e.preventDefault()
			var position = this.selectionStart,
			left = this.value.substring(0, position),
			right = this.value.substring(position),
			code = left + '  ' + right
			this.value = code
			this.selectionStart = this.selectionEnd = position + 2
		}
	})
	
	// AJAX编辑预览代替方案(快捷键为:ctrl + shift + s)
	if(/((?!\.css|\.js|模块|module).+)action=(edit|submit)/.test(location.href)){
		setTimeout(function(){
			$('#wikiEditor-ui-toolbar .tabs').append($('<span id="edit-ajaxPreviewBtn" class="tab"><a href="#" role="button" aria-pressed="false">预览</a></span>'))
			$('#edit-ajaxPreviewBtn').click(foo)
		}, 3000)
		var removeBtn = $('<div id="edit-ajaxPreviewRm" style="width:43px; height:30px; text-align:center; line-height:30px; color:black; font-size:26px; background:white; box-shadow:0 0 5px black; opacity:0.8; position:fixed; top:20px; right:0; cursor:pointer; display:none; z-index:1001;">×</div>')
		.click(function(){
			viewHide()
		})
		$('body').append(removeBtn)
		
		var saveBtn = $('<div id="edit-ajaxPreviewSave" style="width:43px; height:30px; text-align:center; line-height:30px; color:black; font-size:26px; background:white; box-shadow:0 0 5px black; opacity:0.8; position:fixed; top:73px; right:0; cursor:pointer; display:none; z-index:1001;">√</div>')
		.click(function(){
			$('#wpSave').click()
		})
		$('body').append(saveBtn)

		var requestTimeoutKey = 0,
		deferred = null
		function viewHide(){
			deferred && deferred.abort()
			clearTimeout(requestTimeoutKey)
			$('#edit-ajaxPreview').remove()
			$('#edit-ajaxPreviewRm').hide()
			$('#edit-ajaxPreviewSave').hide()
			$('body').css('overflow', 'visible')
		}
	
		$(window).keydown(function(e){
			if(e.ctrlKey && e.keyCode == 83){
				if($('#edit-ajaxPreview').length){
					viewHide()
				}else{
					foo(e)
				}
			}
		})
		
		var api = new mw.Api()
		function foo(e){
			var previewElement = $('<div id="edit-ajaxPreview" style="width:90%; min-width:800px; height:90%; min-height:400px; padding:15px; background:white; box-shadow:0 0 15px #666; overflow:auto; position:fixed; margin:auto; top:0; left:0; right:0; bottom:0; z-index:1000;">').append('<span id="edit-ajaxPreview-LoadingMsg" style="font-size:30px; position:fixed; top:50%; left:50%; transform:translate(-50%, -50%);">获取预览中...</span>')
			$('body').append(previewElement)

			var wikiText = $('#wpTextbox1').val(),
			titleName = decodeURIComponent(location.href.replace(/^.+[?&]title=([^&]+)&.+$/, '$1'))
			$('#edit-ajaxPreviewRm').show()
			$('#edit-ajaxPreviewSave').show()
			$('body').css('overflow', 'hidden')
			deferred = api.post({
				"action": "parse",
				"format": "json",
				"text": wikiText,
				"title": titleName,
				"contentmodel": "wikitext"
			}).done(function(data){
				$('#edit-ajaxPreview').html($(data.parse.text['*']).addClass('mw-body-content'))
			})
			requestTimeoutKey = setTimeout(function(){
				if(deferred.state() != 'resolved'){
					viewHide()
					foo(e)
				}
			}, 8000)
			return false
		}
	}
	
	// ctrl + alt快速添加变量命名空间
	if (mw.config.values.wgAction == "edit" || mw.config.values.wgAction == "submit"){
		var editor = $('#wpTextbox1')
		var title = mw.config.values.wgTitle.replace(/./, function(s){
			return s.toLowerCase()
		})
		editor.keydown(function(e){
			if(e.ctrlKey && e.altKey){
				editor.val(editor.val().replace(/(\{\{#var(define|):)([^\|\}]+)/g, function(s, s1, s2, s3){
					if(!new RegExp('^' + title + '\\.').test(s3)){
						if(['num', 'key', 'value', 'time', 'times'].includes(s3)){ return s }
						return s1 + title + '.' + s3 
					}
					
					return s
				}))
				
				mw.notify('已添加变量命名空间。')
			}
		})
	}
})

// $.getScript("/User:Imbushuo/MonacoEditor/MediaWikiTokenizer.js‎?action=raw&ctype=text/javascript",
// function (data, textStatus, jqxhr) {
//     $.getScript("/User:imbushuo/MediaWikiLint.js‎?action=raw&ctype=text/javascript", 
//     function (data, textStatus, jqxhr) {
//         // Loader for Monaco editor
//         mw.loader.load('https://zh.moegirl.org/User:Imbushuo/MonacoEditor.js?action=raw&ctype=text/javascript');
//     });
// });


// 搜索引擎代替方案
/*
$(function(){
	var input = $('#searchInput').attr('placeholder', '搜索萌娘百科')
	$('#searchButton').off().on('click', function() {
	    var keyword = input.val();
	    if (!keyword) window.alert('请输入关键词后再行搜索!');
	    else {
	        var self = $(this),
	            check_url = 'https://hmoegirl.com/' + keyword,
	            open_url = 'https://www.bing.com/search?q=' + encodeURIComponent(keyword) + '+site%3Azh.hmoegirl.com&ie=UTF-8';
	        self[0].disabled = true;
	        self.data({
	            'background-image': self.css('background-image'),
	            'background-size': self.css('background-size')
	        });
	        self.css({
	            'background-image': 'url(https://static.mengniang.org/common/d/d1/Windows_10_loading.gif)',
	            'background-size': '80%'
	        });
	        $.ajax({
	            url: check_url,
	            type: 'HEAD',
	            success: function(_, __, response) {
	                if (response.status < 400) location.href = check_url;
	                else this.error();
	            },
	            error: function() {
	                location.href = open_url
	            },
	            complete: function() {
	                self[0].disabled = false;
	                self.css(self.data());
	            }
	        });
	    }
	    return false;
	});
})
*/
mw.loader.load('MediaWiki:Gadget-DotsSyntaxHighlighter.js');
/* 给wikiplus添加快速填写摘要 */
$(function () {
    var observar = new MutationObserver(function (record) {
        if ($('.Wikiplus-InterBox').find('#Wikiplus-Quickedit-Summary-Input')[0] &&
            (!$('.Wikiplus-InterBox').find('#summary_list')[0])) {
            var list = ['新条目', '修饰语句', '修正笔误', '内容扩充', '排版', '内部链接', '分类', '消歧义', '萌百化']
            var summary = document.createElement('span')
            summary.id = 'summary_list';
            summary.style.marginLeft = '0.5em';
            for (var i = 0; i < list.length; i++) {
                if (i != 0) summary.innerHTML += ' | ';
                summary.innerHTML += '<a href="#.">' + list[i] + '</a>';
            }
            $('.Wikiplus-InterBox').find('#Wikiplus-Quickedit-Summary-Input')[0].after(summary);
            $('#summary_list').children().each(function () {
                $(this)[0].onclick = function () {
                    var str = $('#Wikiplus-Quickedit-Summary-Input')[0].value;
                    if (/\/\/ Edit via Wikiplus\s*$/.test(str)) {
                        $('#Wikiplus-Quickedit-Summary-Input')[0].value = str.replace(/^(.*?)( ?\/\/ Edit via Wikiplus\s*)$/, '$1 ' + $(this)[0].innerText + ' // Edit via Wikiplus');
                    } else {
                        $('#Wikiplus-Quickedit-Summary-Input')[0].value += ' ' + $(this)[0].innerText;
                    }
                };
            });
        }
    });
    observar.observe(document.body, { childList: true });
});
/*
	注意:该插件必须依附于Wikiplus才能生效。
	
	载入后将在Wikiplus快速编辑的界面中添加一个“+”加号按钮,点击后可以新建快速替换的方案,完成后将生成一个按钮。
	在名称栏中,输入#号后面的文字将作为摘要使用,在执行匹配成功后将自动把摘要的文字置于编辑摘要栏中。
	在替换栏中可以使用 _@br_ 来指代换行,无论是否为正则模式。
	左键点击按钮执行预先设置好的替换,右键点击按钮删除该替换方案。
	
	注意:替换方案保存在当前浏览器中,而不是帐号内,若更换浏览器、更换电脑或清除缓存等,替换方案将不会同步。
*/
$(function(){
	if(typeof MutationObserver == 'undefined'){
		mw.notify('你使用的浏览器版本过低或不符合规范,无法使用Wikiplus-replace插件!', { type : 'warn' })
		return false
	}
	var topBtn = document.getElementById('Wikiplus-Edit-TopBtn')
	topBtn && topBtn.addEventListener('click', function(e){
		if($('.Wikiplus-InterBox').length == 1){
			 $('.Wikiplus-InterBox').remove()
		}
	}, true)
    $.each(document.getElementsByClassName('mw-editsection'), function(index, value){
        value.addEventListener('click', function(e){
            if(e.target.classList.contains('Wikiplus-Edit-SectionBtn') && $('.Wikiplus-InterBox').length == 1){
		        $('.Wikiplus-InterBox').remove()
	        }
        }, true)
    })
	
    var observar = new MutationObserver(function(record){
        var wikiplus = null
        var wikiplusTextarea = $('#Wikiplus-Quickedit')
        $.each(record[0].addedNodes, function(item, element){
            if(element.classList && element.classList.contains('Wikiplus-InterBox')){
                wikiplus = element
            }
        })
        if(wikiplus){
        	var br = '\n'		//用于快捷指代替换中的换行
            $(wikiplus).find('.Wikiplus-InterBox-Content')
            .find('div:first').find('#Wikiplus-Quickedit-Jump')
            .after('<span id="Wikiplus-Quickedit-addReplace" class="Wikiplus-Btn">✚</span>')

            $(wikiplus).contextmenu(function(){ return false })

            if(localStorage.getItem('Quickedit-replace')){
                var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
                $.each(replaceData, function(item, data){
                    var newButton = $('<span class="Wikiplus-Btn" data-id="' + data[3] + '">' + data[0] + '</span>')
                    newButton.mousedown(function(e){
                        if(e.which == 1){
                            var code = wikiplusTextarea.val()
                            var newCode = code.replace(new RegExp(data[1], 'gm'), data[2] ? data[2] : '')
                            .replace(/_@br_/g ,br)
                            if(code == newCode){
                                mw.notify('匹配结果为空!', { type : 'warn' })
                            }else{
                                wikiplusTextarea.val(newCode)
                                data[4] && $('#Wikiplus-Quickedit-Summary-Input').val(data[4])
                                mw.notify('已完成替换!')
                            }
                        }
                        
                        if(e.which == 3){
                            var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
                            .filter(function(repData){
                                return repData[3] != $(e.target).data('id')
                            })
                            localStorage.setItem('Quickedit-replace', JSON.stringify(replaceData))
                            $(this).remove()
                        }
                    })
                    $(wikiplus).find('.Wikiplus-InterBox-Content')
                    .find('div:first').find('.Wikiplus-Btn:last').after(newButton)
                })
            }

            $('#Wikiplus-Quickedit-addReplace').click(function(){
                var addReplaceHTML = '\
                <div id="Wikiplus-Quickedit-replace" style="width:400px; background:#EDF9F7; border:1px #666 solid; font-size:80%; box-shadow: 2px 2px 5px #aaa; overflow:hidden; padding:5px; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; z-index:300;">\
                <div style="padding:10px; padding-bottom:0;">添加快速替换<div class="Quickedit-replace-hide" style="float:right; font-size:26px; font-weight:bold; margin-top:-8px; -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; cursor:pointer">×</div></div>\
                <hr style="height:1px; margin-bottom:-5px; background:#66CCFF; border:none;">\
                <div style="height:110px; border-radius:3px; padding:10px;">\
                    <p>名称:<input id="Quickedit-replace-Name" style="width:300px; height:25px; text-indent:3px;"></p>\
                    <p>查找:<input id="Quickedit-replace-Lookup" style="width:300px; height:25px; text-indent:3px;"></p>\
                    <p>替换:<input id="Quickedit-replace-Replace" style="width:300px; height:25px; text-indent:3px;"></p>\
                    <p>正则模式:<input type="checkbox" id="Quickedit-replace-pattern" value="reg" style="width:16px; height:16px; position:relative; top:3px;">\
                    <input class="Quickedit-replace-hide" type="button" value="关闭" style="float:right; width:50px; height:25px; background:white; box-shadow: 0 1px 2px #aaa; -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; margin:0 5px;">\
                    <input id="Quickedit-replace-add" type="button" value="添加" style="float:right; width:50px; height:25px; background:white; box-shadow: 0 1px 2px #aaa; -webkit-user-select:none; -moz-user-select:none; -o-user-select:none; user-select:none; margin:0 5px;"></p>\
                </div>\
                </div>'
                $(document.body).append(addReplaceHTML)

                var addReplace = $('#Wikiplus-Quickedit-replace'),
                name = $('#Quickedit-replace-Name'),
                lookup = $('#Quickedit-replace-Lookup'),
                replace = $('#Quickedit-replace-Replace'),
                patternSwitch = $('#Quickedit-replace-pattern'),
                hideBtn = $('.Quickedit-replace-hide'),
                addBtn = $('#Quickedit-replace-add')

                hideBtn.click(function(){
                    addReplace.remove()
                })

                addBtn.click(function(){
                    var text = name.val()
                    if(/#/.test(text)){
                    	var note = text.replace(/(.+)#(.+)/, '$2')
                    	text = text.replace(/(.+)#(.+)/, '$1')
                    }
                    var pattern = lookup.val()
                    var replaceText = replace.val()
                    try{
                        if(! patternSwitch.prop('checked')){
                            pattern = pattern.replace(/([\\\(\)\[\]\{\}\+\.\*\^\$\!\?\|])/g,'\\$1')
                        }
                        new RegExp(pattern, 'gm')
                    }catch(e){
                        mw.notify('正则表达式有误,请核对后重新输入!', { type : 'error' })
                        return false
                    }
                    var id = Math.random()
                    if(localStorage.getItem('Quickedit-replace')){
                        var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
                        replaceData.push([text, pattern, replaceText, id, note || null])
                        replaceData = JSON.stringify(replaceData)
                        localStorage.setItem('Quickedit-replace', replaceData)
                    }else{
                        var replaceData = JSON.stringify([[text, pattern, replaceText, id, note || null]])
                        localStorage.setItem('Quickedit-replace', replaceData)
                    }
                    var newButton = $('<span class="Wikiplus-Btn" data-id="' + id + '">' + text + '</span>')
                    newButton.mousedown(function(e){
                        if(e.which == 1){
                            var code = wikiplusTextarea.val()
                            var newCode = code.replace(new RegExp(pattern, 'gm'), replaceText ? replaceText : '')
                            .replace(/_@br_/g ,br)
                            if(code == newCode){
                                mw.notify('匹配结果为空!', { type : 'warn' })
                            }else{
                                wikiplusTextarea.val(newCode)
                                note && $('#Wikiplus-Quickedit-Summary-Input').val(note)
                                mw.notify('已完成替换!')
                            }
                        }

                        if(e.which == 3){
                            var replaceData = JSON.parse(localStorage.getItem('Quickedit-replace'))
                            .filter(function(repData){
                                return repData[3] != $(e.target).data('id')
                            })
                            localStorage.setItem('Quickedit-replace', JSON.stringify(replaceData))
                            $(this).remove()
                        }
                    })
                    $(wikiplus).find('.Wikiplus-InterBox-Content')
                    .find('div:first').find('.Wikiplus-Btn:last').after(newButton)
                    mw.notify('已添加新的替换方案!')
                })

            })
            $('#Wikiplus-Quickedit-Back, .Wikiplus-InterBox-Close').click(function(){
                $('#Wikiplus-Quickedit-replace').remove()
            })
        }
    })
    var options = {
        childList : true
    }
    observar.observe(document.body, options)
})
/*
	载入该插件后,将对wikitext语法所使用的符号和html标签进行成对的补全。
	该插件并不会计算整个源代码中的html标签配对情况,标签的补全仅发生在输入大于号(>)时,补全距离最近的html标签。
	在输入无其他信息的标签后(如:<div></div>),若按下退格(backspace)键,可以直接删除这一组标签。
	注意:因为每次输入时都会对整个源代码进行查找匹配,为了防止卡顿,默认限制为500个字符,但这会导致当标签过长(例如在节点上添加了大量css代码)时,无法自动补全。
	过长的源代码会使输入时性能大幅下降,造成卡顿。当总字符数大于20000时,将自动关闭补全,请合理使用段落编辑的功能。
*/

$(function(){
    if(/action=(edit|submit)/.test(location.href)){
	    var wpText = $('#wpTextbox1')
	    
	    if(wpText.val().length > 20000){
	    	mw.notify('因源代码过长,补全功能被关闭!', { type : 'warn' })
	    	return
	    }
	    
		var retrospect = 500
		var pattern = [
			['-{', '}-'],
			['[', ']'],
			['{', '}'],
			["'", "'"],
			['"', '"'],
			['(', ')'],
			['<!--', '-->']
		]
	
	    //光标后插入信息
	    function insertText(obj, str){
			var content = obj.value,
			position = obj.selectionEnd,
			left = content.substring(0, position),
			right = content.substring(position)
			obj.value = left + str + right
	    }

		var original = null
		wpText.one('click', function(){
			original = {
				code : wpText.val(),
				start : wpText[0].selectionStart,
				end : wpText[0].selectionEnd
			}
		})	
	
	    // 缓存输入内容 & 判断
		var end = 0, 
		thisLength = 0,
		lastLength = 0,
		code = '',
		thisCode = '',
		deletedKeyword = '',
		
		// 需要暂停补全的状态
		typewritingMode = false,
		cutPaste = false,
		selectInput = false,
		selectDelete = false,
		inputFinish = false
 
		var codeSave = [{
			code : wpText.val(),
			start : wpText[0].selectionStart,
			end : wpText[0].selectionEnd
		}],
		inputMark = false
	    function selectionReset(){
	        end = wpText[0].selectionEnd
	        lastLength = wpText.val().length
		}
	
	    wpText.click(function(){
	        selectionReset()
	    }).keyup(function(e){
	        if(e.keyCode > 36 && e.keyCode < 41){
	            selectionReset()
	            code = ''
	        }
	    }).on('keydown keyup', function(e){
			if(e.keyCode == 8){
				var subStart = (this.selectionEnd - 1) < 0 ? 0 : (this.selectionEnd - 1)
				var left = thisCode.substring(subStart, this.selectionEnd)
				deletedKeyword = left
				selectionReset()
			}
		}).on('compositionstart', function(){
			typewritingMode = true
		}).on('compositionend', function(){
			typewritingMode = false
            inputFinish = true
            $(this).trigger('input')
            selectionReset()
		}).on('cut paste', function(){
			cutPaste = true
			
			codeSave.push({
				code : wpText.val(),
				start : wpText[0].selectionStart,
				end : wpText[0].selectionEnd
			})
			inputMark = false
			setTimeout(selectionReset, 0)
		}).on('keydown', function(e){
			selectInput = !! document.getSelection().toString()
			if(selectInput){ end = wpText[0].selectionStart}
			if(selectInput && (e.keyCode == 8 || e.keyCode == 46)){ selectDelete = true }
		}).on('input', function(){
			;(function(_this){
                if(typewritingMode){ return }
                if(inputFinish){ inputFinish = false; return }
				if(cutPaste){ cutPaste = false; return }
				if(selectDelete){ selectDelete = false; return }
		        thisCode = $(_this).val()
		        var right = thisCode.substring(end)
		        thisLength = $(_this).val().length
		        if(thisLength - lastLength == 1 || selectInput){
					code += right.substring(0, 1)
		        }else{
		            code = ''
		            
		            if(lastLength - thisLength == 1){
		            	var subStart = (_this.selectionEnd - 20) < 0 ? 0 : (_this.selectionEnd - 20),
		            	subEnd = (_this.selectionEnd + 20) > thisLength ? thisLength : (_this.selectionEnd + 20)
		            	
		            	var subLeft = thisCode.substring(0, subStart),
		            	subRight = thisCode.substring(subEnd)
		            	
		            	var left = thisCode.substring(subStart, _this.selectionEnd),
		            	right = thisCode.substring(_this.selectionEnd, subEnd),
		            	leftRE = /([\s\S]*)<(.+)$/,
						rightRE = /^\<\/(.+?)>([\s\S]*)/
		            	var tagLeft = left.replace(leftRE, '$2')
						var tagRight = right.replace(rightRE, '$1')
		            	if(tagLeft == tagRight){
		            		var leftCode = left.replace(leftRE, '$1')
		            		var rightCode = right.replace(rightRE, '$2')
		            		$(_this).val(subLeft + leftCode + rightCode + subRight)
		            		var cursorPos = new String(subLeft + leftCode).length
		            		_this.selectionStart = _this.selectionEnd = cursorPos
		            	}
	 
						$.each(pattern, function(){
							var $this = wpText[0]
							if(lastLength - thisLength == 1){
								var subStart = $this.selectionEnd < 0 ? 0 : $this.selectionEnd
								var subEnd = ($this.selectionEnd + 1) > thisLength ? thisLength : ($this.selectionEnd + 1)
								$this.selectionEnd == subEnd && subEnd++
								var subLeft = thisCode.substring(0, $this.selectionEnd),
								subRight = thisCode.substring(subEnd)
								var left = thisCode.substring(subStart, $this.selectionEnd),
								right = thisCode.substring($this.selectionEnd, subEnd)
	 
								if(deletedKeyword == this[0] && right == this[1]){	
									$($this).val(subLeft + subRight)
									$this.selectionStart = $this.selectionEnd = subLeft.length
									selectionReset()
								}
							}						
						})
		            }
		            
		        }
	 
		        function pair(keyword, char, num){
		            if(code.indexOf(keyword) != -1){
						var num = num || char.length
						var position = wpText[0].selectionEnd
		                insertText(wpText[0], char)
		                wpText[0].selectionStart = wpText[0].selectionEnd = position
		                selectionReset()
		                code = ''
		            }
		        }
	  
		        function addPair(arr){
		        	$.each(arr, function(){
						pair(this[0], this[1], this[2])
					})
					
		        }
	            selectionReset()
	 
		        addPair(pattern)
		
	            
				// 配对标签
	            if(code.indexOf('>') != -1){
	            	var start = (end - retrospect) < 0 ? 0 : (end - retrospect)
	                var left = wpText.val().substring(start, end)
	                var ptn = /[\s\S]*<((?!br|hr|img|references|templatestyles|\!--|\/|\>)[^\s<>]+)[^>]*?>$/
	                if(ptn.test(left)){
						var tagEnd = '</' + left.replace(ptn, '$1') + '>'
						var position = wpText[0].selectionEnd
	                    insertText(wpText[0], tagEnd)
		                wpText[0].selectionStart = wpText[0].selectionEnd = position
	                    selectionReset()
	                    code = ''                        
	                }	                	
	            }	
			})(this)
            
			codeSave.push({
				code : wpText.val(),
				start : wpText[0].selectionStart,
				end : wpText[0].selectionEnd
			})
			inputMark = true            
			
			input = false
		})
		
		wpText.on('keydown', function(e){
			if(e.ctrlKey && e.keyCode == 90){
				e.preventDefault()
				if(inputMark){
					codeSave.pop()
					inputMark = false
				}
				var history = codeSave.pop() || original
				if(history){
					wpText.val(history.code).focus()
					wpText[0].selectionStart = history.start
					wpText[0].selectionEnd = history.end
				}
			}
		})
    }
})
/*
	这是一个保存编辑内容的小插件,载入后将在“显示更改”按钮后生成一个“还原备份”按钮。	
	萌百本身有一个缓存编辑的内容的插件,但是我用得感觉很迷,曾经两次在开了那个插件的情况下提交编辑后发生网络错误,
	然而再次回到编辑页面后却无法还原,不知道是有Bug还是我没用好。
	
	这个插件将在点击“提交编辑、显示预览、显示更改”中任意一个按钮时备份当前的编辑。当存在备份时,“还原备份”按钮变为可以点击。
	备份会保存7天,7天后自动清除。
*/
$(function(){
  if(! /action=(edit|submit)/.test(location.href)){ return }

  var editBox = $('#wpTextbox1'),
  btns = $('#wpSaveWidget, #wpPreviewWidget, #wpDiffWidget'),
  title = decodeURIComponent(location.search.match(/title=([^&]+)/)[1]),
  backupList = JSON.parse(localStorage.getItem('Moegirl-koharubiyori-editBackup') || '{}')
  
  $.each(backupList, function(key, val){
  	var time = new Date().getTime()
  	if(val.expires < time){
  		delete backupList[key]
  	}
  })

	setTimeout(function(){
	  var backup = backupList[title]
	  if(backup){
		var btn = $('<span class="oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-buttonInputWidget"><input type="button" value="还原备份" class="oo-ui-inputWidget-input oo-ui-buttonElement-button" /></span>')
		.click(function(){ 
			editBox.val(backup.content)
	    	mw.notify('已还原备份!', { type: 'warn' })     
		})    	
	  }else{
	  	var btn = $('<span class="oo-ui-widget oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-buttonInputWidget oo-ui-widget-disabled"><input type="button" value="还原备份" class="oo-ui-inputWidget-input oo-ui-buttonElement-button" disabled /></span>')
	  }
	  $('#wpDiffWidget').after(btn)
	})

  btns.mousedown(function(e){
      var content = editBox.val()
	  var expire = new Date().getTime() + 1000 * 60 * 60 * 24 * 7
	  backupList[title] = {
	  	expires : expire,
	  	content : content
	  }
	  localStorage.setItem('Moegirl-koharubiyori-editBackup', JSON.stringify(backupList))
  })
})