MediaWiki:Gadget-dykc-nomination.js

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

/** * DYKC nomination tool *  * @version 1.0 (2017-07-02) * @author [[User:WhitePhosphorus]] *///<nowiki>(function($, mw) {'use strict';var site = {DYKCPage: 'Wikipedia:新条目推荐/候选',apiUrl: mw.util.wikiScript('api'),articlePage: mw.config.get('wgArticlePath'),parse: function(wikitext, extraPara, doneFunc, failFunc) {var dataObj = {action: 'parse',title: site.DYKCPage,text: wikitext,prop: 'text',format: 'json'};$.extend(dataObj, extraPara);$.ajax({url: site.apiUrl,data: dataObj}).done(function (data) {var parsedHTML = null;if (data.parse) {if (data.parse.text) {parsedHTML = $.trim(data.parse.text['*']);}}if (parsedHTML !== null) {if ($.isFunction(doneFunc))doneFunc(parsedHTML);} else {if ($.isFunction(failFunc))failFunc(data && data.error && data.error.code ? data.error.code : 'unknown');}}).fail(function(jqXHR, textStatus, errorThrown) {console.log('Error when parsing wikitext: ' + errorThrown);if ($.isFunction(failFunc))failFunc('network');});},loadPage: function(pageTitle, doneFunc, failFunc) {$.ajax({url: site.apiUrl,data: {action: 'query',prop: 'revisions',titles: pageTitle,rvprop: 'content',format: 'json'}}).done(function(data) {var content = null;if (data.query) {if (data.query.pages) {for (var id in data.query.pages) {if (data.query.pages[id]) {var page = data.query.pages[id];if (page.revisions && page.revisions.length) {if (page.revisions[0]['*']) {content = page.revisions[0]['*'];}}}}}}if (content !== null) {if ($.isFunction(doneFunc))doneFunc(content);} else {if ($.isFunction(failFunc))failFunc('missing');}}).fail(function(jqXHR, textStatus, errorThrown) {console.log('Error when loading page ' + pageTitle + ': ' + errorThrown);if ($.isFunction(failFunc))failFunc('network');});},edit: function(pageTitle, newRevision, doneFunc, failFunc) {$.ajax({url: site.apiUrl,dataType: 'json',type: 'POST',data: {action: 'edit',title: pageTitle,summary: msg.edit_summary,text: newRevision,token: mw.user.tokens.get('csrfToken'),format: 'json'}}).done(function(data) {if (data && data.edit && data.edit.result === 'Success') {if ($.isFunction(doneFunc))doneFunc(content);} else {if ($.isFunction(failFunc)) {if (data && data.error) {failFunc(data.error.code ? data.error.code : 'unknown');} else if (data && data.edit && data.edit.code) {var code = data.edit.code;if (code === 'abusefilter-disallowed' || code == 'abusefilter-warning') {failFunc(code, data.edit.warning);} else {failFunc(code);}} else {failFunc('unknown');}}}}).fail(function(jqXHR, textStatus, errorThrown) {console.log('Error when editing page ' + pageTitle + ': ' + errorThrown);if ($.isFunction(failFunc))failFunc('network');});},post: function(image) {dialog.dl.dialog('close');if (dialog.rst && dialog.rst.dialog('isOpen'))dialog.rst.dialog('close');dialog.rst = $('<p>' + msg.msg_posting + '</p>').dialog({title: msg.dialog_title});var dykcArr = ['==== ====','{{ subst:#invoke:Template:DYKEntry|normalize',' | article = ' + article.title,' | question = ' + dialog.config.dykcQuestion,' | image = ' + image,' | type = ' + dialog.config.dykcType,' | author = ' + dialog.config.dykcAuthor,' | nominator = {{subst:REVISIONUSER}}',' | timestamp = {{subst:#time:U}}','}}',''],remark = $.trim(dialog.config.dykcRemarks),remarkStr = (remark.length ? '** {{Remark}}:' + remark + '\n' : ''),dykcStr = dykcArr.join('\n') + remarkStr;site.loadPage(site.DYKCPage, function(revision) {varcurDate = new Date(),curMD = (curDate.getUTCMonth()+1) + '月' + curDate.getUTCDate() + '日',dateRe = new RegExp('===\\s*' + curMD + '\\s*===[\\r\\n]*'),succeed = true;if (!dateRe.test(revision)) {dykcStr = '=== ' + curMD + ' ===\n' + dykcStr;}dykcStr = '\n' + dykcStr;// update here if the insertion position has been changed// the new nomination will be added BEFORE this matchvar match = /\n==== ====\n{{safesubst:DYKEntry\/auto/.exec(revision);if (match === null) {window.prompt(msg.dialog_error_format, dykcStr);if (dialog.rst && dialog.rst.dialog('isOpen'))dialog.rst.dialog('close');return null;}var newText = revision.substring(0, match.index) + dykcStr + revision.substring(match.index, revision.length);site.edit(site.DYKCPage, newText, function() {dialog.rst.html('<p>' + msg.msg_post_complete +'<a href="' + site.articlePage.replace('$1', site.DYKCPage) +'">' + msg.msg_dykc + '</a>' + msg.msg_close_this + '</p>');}, function(code, warning) {if (warning !== undefined) {warning = '<p><span style="error">' + msg.dialog_error_af +'</span><a href="#" id="dykcAFReturn">' +msg.dialog_return + '</a></p>' + warning;dialog.rst.html(warning);$('#dykcAFReturn').click(function(e) {e.preventDefault();dialog.rst.dialog('close');dialog.dl.dialog('open');});} else {window.prompt(msg.dialog_error(code), dykcStr);if (dialog.rst && dialog.rst.dialog('isOpen'))dialog.rst.dialog('close');}});});}};var article = {title: mw.config.get('wgPageName'),images: null,  // parsed html of images used by the articleimageTitles: null  // filename (e.g. File:foo.jpg) of images used by the article};var img = {// Check if there is a <img> in the parsed html.isExists: function(imgHTML) {return $(imgHTML).find('img').length !== 0;},// Check if the image exists on commons.wikimedia.org, not on local wiki,// for most files on local wiki are non-free and copyrighted.isInCommons: function(imgHTML) {return ~imgHTML.indexOf('//upload.wikimedia.org/wikipedia/commons/');},// Normalize input data to something like *File:Foo.jpg* or *Foo.jpg*.normalize: function(image, ns) {var rst = /^\[\[:?(.*?)(\|.*?)?\]\]/.exec(image);if (rst !== null) {image = rst[1];}rst = /^(file|image|文件|[檔档]案)\s*:/i.exec(image);if (rst === null && ns) {image = 'File:' + image;} else if (rst !== null && !ns) {image = image.substring(rst[0].length, image.length);}return image.replace(/[ _]+/g, ' ');}};var msg;switch (mw.config.get('wgUserLanguage')) {case 'zh-cn':case 'zh-hans':case 'zh-my':case 'zh-sg':msg = {link_title: '提交新条目推荐候选',edit_summary: '[[User:WhitePhosphorus/js/dykc.js|半自动提交]]新条目推荐候选',msg_question: '问题',msg_type: '类型',msg_loading_images: '正在加载条目中的图片……',msg_loading_images_failed: '无法加载条目中的图片!',msg_no_required_para: '您没有填写以下必填项目:\n\n',msg_are_you_sure: '\n\n确定要提交吗?',msg_posting: '正在提交,请起身活动一下吧^_^',msg_post_complete: '提交完成。您可以前往',msg_dykc: '推荐页',msg_close_this: '查看,或关闭此对话框留在本页。',dialog_title: '提交新条目推荐候选',dialog_button_submit: '提交',dialog_button_cancel: '取消',dialog_button_preview: '预览',dialog_question: '问题(必填):',dialog_image: '图片(可选):',dialog_other_image: '使用下面的图片',dialog_type: '类型(可选,建议用英文):',dialog_author: '主编(若非一人主编或主编非注册用户,请留空):',dialog_remarks: '其他说明(可选,如果填写则需签名):',dialog_preview: '预览:',dialog_return: '单击返回提交表单',dialog_warning_img_invalid: '警告:图片不存在!',dialog_warning_img_not_in_commons: '警告:图片不存在于维基共享资源,很可能是合理使用而不能用于首页展示!',dialog_warning_img_unused: '警告:图片未被条目使用,不能用于首页展示!',dialog_warning_qus_no_marks: '警告:问题中没有出现问号“?”,请加入之,或修正半角问号“?”。',dialog_warning_qus_not_bold: '警告:问题中没有加粗条目名!',dialog_auto_formatting: '为选中部分加粗、加链接',dialog_auto_bolding: '自动修复',dialog_warning_qus_no_links: '警告:问题中没有到条目的内部链接,请检查是否繁简不同或使用了重定向。',dialog_error: function(code) { return '很抱歉本工具出现问题,未能自动推荐该条目。\n' +'您可前往 User talk:WhitePhosphorus 回报出现问题的条目、时间和以下错误原因:' +code + '。\n请按下Ctrl+C或command+C来复制下面的代码并手动推荐:' },dialog_error_af: '您的编辑已被过滤器拦截。',dialog_error_format: '很抱歉因为无法识别新条目推荐候选页的格式,故未能自动推荐该条目。\n' +'您可前往 User talk:WhitePhosphorus 回报出现问题的条目和时间。\n' +'请按下Ctrl+C或command+C来复制下面的代码并手动推荐:'};break;default:msg = {link_title: '提交新條目推薦候選',edit_summary: '[[User:WhitePhosphorus/js/dykc.js|半自動提交]]新條目推薦候選',msg_question: '問題',msg_type: '類型',msg_loading_images: '正在加載條目中的圖片……',msg_loading_images_failed: '無法加載條目中的圖片!',msg_no_required_para: '您沒有填寫以下必填項目:\n\n',msg_are_you_sure: '\n\n確定要提交嗎?',msg_posting: '正在提交,請起身活動一下吧^_^',msg_post_complete: '提交完成。您可以前往',msg_dykc: '推薦頁',msg_close_this: '查看,或關閉此對話框留在本頁。',dialog_title: '提交新條目推薦候選',dialog_button_submit: '提交',dialog_button_cancel: '取消',dialog_button_preview: '預覽',dialog_question: '問題(必填):',dialog_image: '圖片(可選):',dialog_other_image: '使用下面的圖片',dialog_type: '類型(可選,建議用英文):',dialog_author: '主編(若非一人主編或主編非註冊用戶,請留空):',dialog_remarks: '其他說明(可選,如果填寫則需簽名):',dialog_preview: '預覽:',dialog_return: '單擊返回提交表單',dialog_warning_img_invalid: '警告:圖片不存在!',dialog_warning_img_not_in_commons: '警告:圖片不存在於維基共享資源,很可能是合理使用而不能用於首頁展示!',dialog_warning_img_unused: '警告:圖片未被條目使用,不能用於首頁展示!',dialog_warning_qus_no_marks: '警告:問題中沒有出現問號“?”,請加入之,或修正半角問號“?”。',dialog_warning_qus_not_bold: '警告:問題中沒有加粗條目名!',dialog_auto_formatting: '爲選中部分加粗、加鏈接',dialog_auto_bolding: '自動修復',dialog_warning_qus_no_links: '警告:問題中沒有到條目的內部鏈接,請檢查是否繁簡不同或使用了重新導向。',dialog_error: function(code) { return '很抱歉本工具出現問題,未能自動推薦該條目。\n' +'您可前往 User talk:WhitePhosphorus 回報出現問題的條目、時間和以下錯誤原因:' +code + '。\n請按下Ctrl+C或command+C來複制下面的代碼並手動推薦:' },dialog_error_af: '您的編輯已被過濾器攔截。',dialog_error_format: '很抱歉因爲無法識別新條目推薦候選頁的格式,故未能自动推荐该条目。\n' +'您可前往 User talk:WhitePhosphorus 回报出现问题的条目和时间。\n' +'请按下Ctrl+C或command+C来复制下面的代码并手动推荐:'};}var dialog = {dl: null,rst: null,config: {},$: {},loadJQueryObjs: function() {// Cache often-used JQuery objects.dialog.$ = {dykcDialog: $('#dykcDialog'),dykcQuestion: $('#dykcQuestion'),dykcImage: $('#dykcImage'),dykcOtherImage: $('#dykcOtherImage'),dykcType: $('#dykcType'),dykcAuthor: $('#dykcAuthor'),dykcRemarks: $('#dykcRemarks'),previewImage: $('#previewImage'),previewQuestion: $('#previewQuestion'),previewRemarks: $('#previewRemarks'),warning: $('p[id*="warning"]'),warningImg: $('p[id*="warningImg"]'),warningQus: $('p[id*="warningQus"]'),warningImgInvalid: $('#warningImgInvalid'),warningImgUnused: $('#warningImgUnused'),warningImgNotInCommons: $('#warningImgNotInCommons'),warningQusNoMarks: $('#warningQusNoMarks'),warningQusNotBold: $('#warningQusNotBold'),warningQusNoLinks: $('#warningQusNoLinks'),loadingArticleImages: $('#loadingArticleImages'),autoFormatting: $('#autoFormatting'),autoBolding: $('#autoBolding')};},updateConfig: function() {// Cache everything when the dialog is closed.dialog.$.dykcDialog.find("input[id*='dykc'], textarea[id*='dykc'], select[id*='dykc']").each(function(i) {dialog.config[this.id] = $(this).val();});dialog.$.dykcDialog.find("div[id*='preview'], li[id*='preview']").each(function(i) {dialog.config[this.id] = $(this).html();});dialog.$.warning.each(function(i) {dialog.config[this.id] = $(this).is(":visible");});},loadCSS: function() {dialog.$.dykcDialog.find("select").css("max-width", "97%").css('margin-left', '3%');dialog.$.dykcDialog.find("input, textarea").css("width", "97%").css('margin-left', '3%');dialog.$.previewQuestion.css('padding-right', '100px');dialog.$.previewRemarks.css('padding-right', '100px');dialog.$.dykcDialog.find("p[id*=warning]:not(a)").addClass('error');// Do not show that when web browser does not support the propertyif (dialog.$.dykcQuestion[0].selectionStart === undefined) {dialog.$.autoFormatting.hide();}},loadConfig: function() {// Load everything we cached before.dialog.$.warning.hide();for (var k in dialog.config) {if (dialog.config.hasOwnProperty(k)) {if (k.startsWith('preview')) {dialog.$[k].html(dialog.config[k]);} else if (k.startsWith('warning')) {if (dialog.config[k])dialog.$[k].show();elsedialog.$[k].hide();} else {dialog.$[k].val(dialog.config[k]);}}}// #previewRemarks is hidden by default.if (dialog.config.previewRemarks && dialog.config.previewRemarks.length)dialog.$.previewRemarks.show();if (article.images === null) {// The images are still loading.dialog.$.loadingArticleImages.show();dialog.$.dykcImage.hide();}dialog.loadCSS();},bindEvents: function() {// When question is modified, do not show the warnings.dialog.$.dykcQuestion.on('input selectionchange propertychange', function() {dialog.$.warningQus.hide();});dialog.$.dykcImage.on('change', function() {dialog.previewImage();});dialog.$.autoFormatting.on('click', function() {dialog.autoFormatting();});dialog.$.autoBolding.on('click', function() {dialog.autoBolding();});dialog.$.dykcOtherImage.on('keypress', function() {dialog.selectOtherImage();});},init: function() {dialog.loadJQueryObjs();dialog.bindEvents();dialog.loadConfig();},previewImage: function() {dialog.$.warningImg.hide();dialog.$.previewImage.html("");if (article.images !== null) {var index = dialog.$.dykcImage.val();if (index.length) {dialog.$.previewImage.html(article.images[parseInt(index)]);if (!img.isInCommons(article.images[parseInt(index)])) {dialog.$.warningImgNotInCommons.show();}} else {var image = $.trim(dialog.$.dykcOtherImage.val());if (!image.length)return null;var imageTitle = img.normalize(image, false);image = '[[File:' + imageTitle + '|80px]]';site.parse(image, {disablelimitreport: '1'}, function (data) {if (!img.isExists(data)) {dialog.$.warningImgInvalid.show();} else {if (!img.isInCommons(data))dialog.$.warningImgNotInCommons.show();data = $(data)[0].outerHTML;if (article.imageTitles.indexOf(imageTitle) === -1)dialog.$.warningImgUnused.show();dialog.$.previewImage.html(data);}});}}},previewRemarks: function() {dialog.$.previewRemarks.html("").hide();var text = $.trim(dialog.$.dykcRemarks.val());if (!text.length)return null;site.parse('{{Remark}}:' + text, {pst: '1',disablelimitreport: '1'}, function (data) {dialog.$.previewRemarks.html(data).show();});},previewQuestion: function() {var qusWikitext = dialog.$.dykcQuestion.val();site.parse(qusWikitext, {disablelimitreport: '1'}, function (qusHTML) {dialog.$.previewQuestion.html(qusHTML);dialog.$.warningQus.hide();var $qus = $(qusHTML);if (qusHTML.indexOf('?') === -1) {dialog.$.warningQusNoMarks.show();}var linkSelector = 'a[href="' + site.articlePage.replace('$1', encodeURI(article.title.replace(/ /g, '_'))) + '"]';if ($qus.find(linkSelector).length === 0) {dialog.$.warningQusNoLinks.show();} else if ($qus.find('b').find(linkSelector).length === 0) {dialog.$.warningQusNotBold.show();}});},// Called when the user types something in the input box #otherImage.// The user may want to manually specify an image so we select 'other_image' for him.selectOtherImage: function() {dialog.$.dykcImage.val("");dialog.$.previewImage.html("");dialog.$.warningImg.hide();},// Find a link like *[[title]]* and replace them with *'''[[title]]'''*.// Something like *''''foo''''* will be parsed to *'<b>foo</b>'* by MediaWiki.autoBolding: function() {var text = dialog.$.dykcQuestion.val(),escapedTitle = article.title.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),titleRe = new RegExp("(\\[\\[:?" + escapedTitle + "(\\|.*?)?\\]\\])");dialog.$.dykcQuestion.val(text.replace(titleRe, "'''$1'''"));dialog.$.warningQus.hide();},// Wrap selected text with *'''[[* and *]]'''*.autoFormatting: function() {var start = dialog.$.dykcQuestion[0].selectionStart,end = dialog.$.dykcQuestion[0].selectionEnd,qus = dialog.$.dykcQuestion.val();if (start !== undefined) {if (start === end)return null;var pre = qus.substring(0, start),tar = qus.substring(start, end),suf = qus.substring(end, qus.length);dialog.$.dykcQuestion.val(pre + "'''[[" + article.title + "|" + tar + "]]'''" + suf);dialog.$.warningQus.hide();// set cursor at the end of selected stringdialog.$.dykcQuestion[0].selectionStart =dialog.$.dykcQuestion[0].selectionEnd =end + 11 + article.title.length;}}};// Load all images used by the article.// When the dialog is loaded, those images will be listed in the select box.var loadArticleImages = function() {$.ajax({url: site.apiUrl,data: {action: 'query',prop: 'images|revisions',titles: article.title,rvprop: 'content',imlimit: 'max',  // 500 should be enough.format: 'json'}}).done(function (data) {var allImageTitles = [], revision = '';if (data && data.query) {var pages = data.query.pages;for (var pageid in pages) {var page = pages[pageid];if ('images' in page) {allImageTitles = page.images.map(function(x) { return x.title.substring(5, x.title.length); });}if (page.revisions && page.revisions.length && page.revisions[0]['*']) {revision = page.revisions[0]['*'];}}}// The filename (without prefix 'File:') must appear in article text.// Or if we failed to get the article text, do not filter anything.allImageTitles = !revision.length ? allImageTitles : allImageTitles.filter(function (e) {return ~revision.replace(/[ _]+/g, ' ').indexOf(e.substring(5, e.length));});var imageTitlesStr = '[[File:' + allImageTitles.join('|80px]]\n\n[[File:') + '|80px]]',filterArr = [];site.parse(imageTitlesStr, {disablelimitreport: '1'}, function (data) {if(!data) return;var $data = $(data);article.images = $data.find('p, div').toArray().map(function(e) {return e.outerHTML;}).filter(function(e, i) {filterArr[i] = img.isExists(e);return filterArr[i];});article.imageTitles = allImageTitles.filter(function(e, i) { return filterArr[i]; });$('#loadingArticleImages').hide();$('#dykcImage').show();}, function (code) {$('#loadingArticleImages').val(msg.msg_loading_images_failed + '(' + code + ')');});}).fail(function(jqXHR, textStatus, errorThrown) {console.log('Error when loading images of ' + article.title + ': ' + errorThrown);$('#loadingArticleImages').val(msg.msg_loading_images_failed + 'queryImages');});};var addDYKCLink = function() {$(mw.util.addPortletLink("p-tb","#",msg.link_title)).click(function(e) {e.preventDefault();// List images used by the article.var imageTitleArr = article.imageTitles.map(function (t, i) {return '<option value="' + i + '">' + t + '</option>';});// This is our html source code of the dialog box.// CSS is set in *dialog.loadCSS()* and some events are bound in *dialog.bindEvents()*.var html ='<div id="dykcDialog" style="line-height:2em">' +msg.dialog_question +'<div class="floatright"><a id="autoFormatting">' +msg.dialog_auto_formatting + '</a></div><br>' +'<textarea name="question" id="dykcQuestion" style="resize:vertical" rows=2></textarea>' +msg.dialog_image + '<br><span id="loadingArticleImages" style="display:none">' + msg.msg_loading_images + '</span>' +'<select name="image" id="dykcImage">' +imageTitleArr.join('') +'<option value="" selected="selected">' + msg.dialog_other_image + '</option>' +'</select><br>' +'<input name="otherImage" type="text" id="dykcOtherImage"><br>' +msg.dialog_type + '<br>' + '<input name="type" type="text" id="dykcType"><br>' +msg.dialog_author + '<br>' +'<input name="author" type="text" id="dykcAuthor" value="' + mw.config.get('wgUserName') + '"><br>' +msg.dialog_remarks + '<br>' + '<textarea name="remarks" id="dykcRemarks" style="resize:vertical" rows=4></textarea><br>' +msg.dialog_preview + '<br>' +'<div width="100%"><div id="previewImage" class="floatright"></div>' +'<ul><li id="previewQuestion"></li><ul><li id="previewRemarks" style="display:none"></li></ul></ul>' +'<p id="warningImgInvalid">' + msg.dialog_warning_img_invalid + '</p>' +'<p id="warningImgNotInCommons">' + msg.dialog_warning_img_not_in_commons + '</p>' +'<p id="warningImgUnused">' + msg.dialog_warning_img_unused + '</p>' +'<p id="warningQusNoMarks">' + msg.dialog_warning_qus_no_marks + '</p>' +'<p id="warningQusNotBold">' + msg.dialog_warning_qus_not_bold  +'<a id="autoBolding">&gt;&gt; ' + msg.dialog_auto_bolding + '</a>' + '</p>' +'<p id="warningQusNoLinks">' + msg.dialog_warning_qus_no_links + '</p>' +'</div></div>';if (dialog.dl) {if (!dialog.dl.dialog('isOpen'))dialog.dl.html(html).dialog("open");} else {dialog.dl = $(html).dialog({title: msg.dialog_title,minWidth: 515,minHeight: 175,beforeClose: dialog.updateConfig,buttons: [{text: msg.dialog_button_preview,click: function() {dialog.previewImage();dialog.previewQuestion();dialog.previewRemarks();}},{text: msg.dialog_button_submit,click: function() {dialog.updateConfig();var empty_para = [];if (!dialog.config.dykcQuestion.length)empty_para.push(msg.msg_question);if (empty_para.length) {if (!window.confirm(msg.msg_no_required_para +empty_para.join('\n') + msg.msg_are_you_sure)) {return null;}}var image = dialog.config.dykcOtherImage;if (dialog.config.dykcImage.length)image = article.imageTitles[parseInt(dialog.config.dykcImage)];site.post(image);}},{text: msg.dialog_button_cancel,click: function() { $(this).dialog('close'); }}]});}dialog.init();});};if (mw.config.get('wgCanonicalNamespace') === '' && mw.config.get('wgArticleId') !== 0) {loadArticleImages();addDYKCLink();}})(jQuery, mw);//</nowiki>