跳转到内容

User:1F616EMO/TalkInvite.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ 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~