User:1F616EMO/TalkInvite.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/*
* Talk inviter (zhwiki)
*
* Use the following line to load this script:
* mw.loader.load( "https://zh.wikipedia.org/w/index.php?title=User:1F616EMO/TalkInvite.js&action=raw&ctype=text/javascript" ); // [[:w:zh:U:1F616EMO/TalkInvite]]
*
* This script is made by 1F616EMO on zhwiki, licensed under CC BY-SA 4.0.
*/
// <nowiki>
$.when(mw.loader.using([
'mediawiki.api',
'mediawiki.jqueryMsg',
'oojs-ui-core',
'oojs-ui-windows',
'ext.gadget.HanAssist', // adoption note: zhwiki specific
]), $.ready).then((require) => {
window.TalkInvite = window.TalkInvite || {};
const api = new mw.Api();
const { batchConv } = require('ext.gadget.HanAssist');
mw.messages.set(batchConv({
'talk-invite-button': {
hans: '邀请',
hant: '邀請'
},
'talk-invite-prompt': {
hans: '目标页面(留空以中断输入)',
hant: '目標頁面(留空以中斷輸入)'
},
'talk-invite-confirm': {
hans: '目标页面:$1。确定?',
hant: '目標頁面:$1。確定?'
},
'talk-invite-summary': {
hans: '邀请讨论 → [[$1|$2]] // [[U:1F616EMO/TalkInvite|TalkInvite]]',
hant: '邀請討論 → [[$1|$2]] // [[U:1F616EMO/TalkInvite|TalkInvite]]',
},
'talk-invite-declare-summary': {
hans: '已向$1发送讨论邀请 // [[U:1F616EMO/TalkInvite|TalkInvite]]',
hant: '已向$1發送討論邀請 // [[U:1F616EMO/TalkInvite|TalkInvite]]',
},
}));
window.TalkInvite.settings = {
TalkInviteFormat: '{{subst:User:1F616EMO/TalkInvite/template|1=$1|2=$2|thread=$3}}',
};
window.TalkInvite.invite = async function (target, source, heading, thread) {
const newBody = "\n" + window.TalkInvite.settings.TalkInviteFormat
.replace("$1", source)
.replace("$2", heading)
.replace("$3", thread);
const threadTitleAnchor = source + '#' + heading;
const threadAnchor = thread !== '' ? 'Special:gotocomment/' + thread : threadTitleAnchor;
const summary = mw.message('talk-invite-summary', threadAnchor, threadTitleAnchor).text();
await api.postWithToken('csrf', {
action: 'edit',
title: target,
appendtext: newBody,
summary: summary,
});
window.open(mw.util.getUrl(target));
};
window.TalkInvite.declareInvitations = async function (pageid, curid, sourcesection, targets) {
const targetLinks = targets.map((x) => '[[' + x + ']]').join('、');
const declareMessage = "\n:已向" + targetLinks + '發送討論邀請。<small>[[U:1F616EMO/TalkInvite|TalkInvite]]</small>~~~~';
const data = await api.get({
action: 'query',
prop: 'revisions',
pageids: pageid,
rvprop: 'ids|content',
rvlimit: 1,
rvslots: 'main',
rvsection: sourcesection,
});
const text = data['query']['pages'][pageid]['revisions'][0]['slots']['main']['*'].trim();
const submitText = text + declareMessage;
await api.postWithToken('csrf', {
action: 'edit',
pageid: pageid,
section: sourcesection,
text: submitText,
summary: mw.message('talk-invite-declare-summary', targetLinks).text(),
baserevid: curid,
nocreate: true,
});
window.location.reload();
};
const resolveRedirects = async function (targetpage) {
const redirect_req_data = await api.get({
action: 'query',
titles: targetpage,
redirects: true,
converttitles: true,
format: 'json',
});
const data_pages_first = Object.values(redirect_req_data.query.pages)[0];
targetpage = data_pages_first.title || targetpage;
const data_redirects = redirect_req_data.redirects;
if (data_redirects && data_redirects[0].from === targetpage)
targetpage = data_redirects[0].to;
return targetpage;
}
window.TalkInvite.askInvite = async function (heading, thread, sourcesection) {
const source = mw.config.get('wgPageName').replace(/_/g, ' ');
const pageid = mw.config.get('wgArticleId');
const curid = mw.config.get('wgCurRevisionId');
const waitTargets = [];
const targets = [];
while (true) {
const target = prompt(mw.message('talk-invite-prompt').text());
if (target === null) {
return;
} else if (target.trim() === '') {
break;
}
waitTargets.push(resolveRedirects(target.trim()));
// targets.push(target.trim());
}
if (waitTargets.length === 0) {
return;
}
for (let i = 0; i < waitTargets.length; i++) {
targets.push(await waitTargets[i]);
}
const targetText = targets.join('、');
if (!confirm(mw.message('talk-invite-confirm', targetText).text())) {
return;
}
const promises = [];
for (const target of targets) {
promises.push(window.TalkInvite.invite(target, source, heading, thread));
}
await Promise.all(promises);
await window.TalkInvite.declareInvitations(pageid, curid, sourcesection, targets);
};
mw.util.addCSS(`
.mw-editsection .talk-invite-editsection-link-group::before {
content: ' | ';
}
`);
mw.hook('wikipage.content').add(($content) => {
$content.find('.mw-heading2:not(.talk-invite-processed)').each(function () {
const $this = $(this);
$this.addClass('talk-invite-processed');
const $h2 = $this.find('h2').first();
const $editsection = $this.find('.mw-editsection');
if ($h2.length === 0 || $editsection.length === 0) {
return; // skip if no heading or edit section
}
const heading = $h2.attr('id') || $h2.text().trim();
const thread = $h2.attr('data-mw-thread-id') || '';
// Find section ID
const $editsectionlink = $editsection.find('a:first-of-type');
if ($editsectionlink.length === 0)
return;
const editHref = $editsectionlink.attr('href');
const sourcesection = mw.util.getParamValue('section', editHref);
$('<span>')
.addClass("talk-invite-editsection-link-group")
.append($("<a>")
.text(mw.message('talk-invite-button').plain())
.attr("href", "javascript:void(0)"))
.on('click', (e) => {
e.preventDefault();
window.TalkInvite.askInvite(heading, thread, sourcesection);
})
.insertBefore($editsection.find(".mw-editsection-bracket").last());
})
});
});
// </nowiki> nya~