MediaWiki:Gadget-friendlytalkback.js

MediaWiki系统消息页面
/**
 * SPDX-License-Identifier: CC-BY-SA-4.0
 * _addText: '{{Twinkle Header}}'
 *
 * @base <https://git.qiuwen.wiki/InterfaceAdmin/Twinkle>
 * @source <https://github.com/TopRealm/Twinkle>
 */
/**
 * +--------------------------------------------------------+
 * |         === WARNING: GLOBAL GADGET FILE ===            |
 * +--------------------------------------------------------+
 * |      All changes should be made in the repository,     |
 * |              otherwise they will be lost.              |
 * +--------------------------------------------------------+
 * |      Changes to this page may affect many users.       |
 * |  Please discuss changes at talk page before editing.   |
 * +--------------------------------------------------------+
 */
/* <nowiki> */
/* Twinkle.js - friendlytalkback.js */
(function ($) {
    /**
     * friendlytalkback.js: Talkback module
     * Mode of invocation: Tab ("TB")
     * Active on: Any page with relevant user name (userspace, contribs, etc.) except IP ranges
     * Config directives in: FriendlyConfig
     */
    Twinkle.talkback = function () {
        if (!mw.config.get('wgRelevantUserName')) {
            return;
        }
        Twinkle.addPortletLink(Twinkle.talkback.callback, '通告', 'friendly-talkback', wgULS('回复通告', '回覆通告'));
    };
    Twinkle.talkback.callback = function () {
        if (mw.config.get('wgRelevantUserName') === mw.config.get('wgUserName') &&
            !confirm(wgULS('虽然但是,你真的要回复你自己吗?', '雖然但是,你真的要回覆你自己嗎?'))) {
            return;
        }
        var Window = new Morebits.simpleWindow(600, 350);
        Window.setTitle(wgULS('回复通告', '回覆通告'));
        Window.setScriptName('Twinkle');
        Window.addFooterLink(wgULS('关于{{talkback}}', '關於{{talkback}}'), 'Template:Talkback');
        Window.addFooterLink(wgULS('通告设置', '通告設定'), 'H:TW/PREF#talkback');
        Window.addFooterLink(wgULS('Twinkle帮助', 'Twinkle說明'), 'H:TW/DOC#talkback');
        var form = new Morebits.quickForm(Twinkle.talkback.evaluate);
        form.append({
            type: 'radio',
            name: 'tbtarget',
            list: [
                {
                    label: wgULS('回复:我的讨论页', '回覆:我的討論頁'),
                    value: 'mytalk',
                    checked: 'true',
                },
                {
                    label: wgULS('回复:其他用户的讨论页', '回覆:其他使用者的討論頁'),
                    value: 'usertalk',
                },
                {
                    label: wgULS('回复:其它页面', '回覆:其它頁面'),
                    value: 'other',
                },
                {
                    label: wgULS('邀请讨论', '邀請討論'),
                    value: 'see',
                },
                {
                    label: '通告板通知',
                    value: 'notice',
                },
                {
                    label: wgULS('“有新邮件”', '「有新郵件」'),
                    value: 'mail',
                },
            ],
            event: Twinkle.talkback.changeTarget,
        });
        form.append({
            type: 'field',
            label: '工作区',
            name: 'work_area',
        });
        var previewlink = document.createElement('a');
        $(previewlink).on('click', function () {
            Twinkle.talkback.preview(result); // |result| is defined below
        });
        previewlink.style.cursor = 'pointer';
        previewlink.textContent = wgULS('预览', '預覽');
        form.append({
            type: 'div',
            id: 'talkbackpreview',
            label: [previewlink],
        });
        form.append({
            type: 'div',
            id: 'friendlytalkback-previewbox',
            style: 'display: none',
        });
        form.append({
            type: 'submit',
        });
        var result = form.render();
        Window.setContent(result);
        Window.display();
        result.previewer = new Morebits.wiki.preview($(result).find('div#friendlytalkback-previewbox').last()[0]);
        // We must init the
        var evt = document.createEvent('Event');
        evt.initEvent('change', true, true);
        result.tbtarget[0].dispatchEvent(evt);
        // Check whether the user has opted out from talkback
        var query = {
            action: 'query',
            prop: 'extlinks',
            titles: "User talk:".concat(mw.config.get('wgRelevantUserName')),
            elquery: 'userjs.invalid/noTalkback',
            ellimit: '1',
        };
        var ysarxiv_api = new Morebits.wiki.api(wgULS('抓取退出通告信息', '抓取退出通告資訊'), query, Twinkle.talkback.callback.optoutStatus);
        ysarxiv_api.post();
    };
    Twinkle.talkback.optout = '';
    Twinkle.talkback.callback.optoutStatus = function (apiobj) {
        var $el = $(apiobj.getXML()).find('el');
        if ($el.length) {
            Twinkle.talkback.optout =
                mw.config.get('wgRelevantUserName') + wgULS('不希望收到回复通告', '不希望收到回覆通告');
            var url = $el.text();
            var reason = mw.util.getParamValue('reason', url);
            Twinkle.talkback.optout += reason ? "\uFF1A".concat(Morebits.string.appendPunctuation(reason)) : '。';
        }
        $('#twinkle-talkback-optout-message').text(Twinkle.talkback.optout);
    };
    var prev_page = '';
    var prev_section = '';
    var prev_message = '';
    Twinkle.talkback.changeTarget = function (e) {
        var value = e.target.values;
        var root = e.target.form;
        var old_area = Morebits.quickForm.getElements(root, 'work_area')[0];
        if (root.section) {
            prev_section = root.section.value;
        }
        if (root.message) {
            prev_message = root.message.value;
        }
        if (root.page) {
            prev_page = root.page.value;
        }
        var work_area = new Morebits.quickForm.element({
            type: 'field',
            label: wgULS('回复通告信息', '回覆通告資訊'),
            name: 'work_area',
        });
        root.previewer.closePreview();
        switch (value) {
            case 'mytalk':
            /* falls through */
            default:
                work_area.append({
                    type: 'div',
                    label: '',
                    style: 'color: #f00',
                    id: 'twinkle-talkback-optout-message',
                });
                work_area.append({
                    type: 'input',
                    name: 'section',
                    label: wgULS('章节(可选)', '章節(可選)'),
                    tooltip: wgULS('您留言的章节标题,留空则不会产生章节链接。', '您留言的章節標題,留空則不會產生章節連結。'),
                    value: prev_section,
                });
                break;
            case 'usertalk':
                work_area.append({
                    type: 'div',
                    label: '',
                    style: 'color: #f00',
                    id: 'twinkle-talkback-optout-message',
                });
                work_area.append({
                    type: 'input',
                    name: 'page',
                    label: wgULS('用户(必填)', '使用者(必填)'),
                    tooltip: wgULS('您留言页面的用户名,必填。', '您留言頁面的使用者名稱,必填。'),
                    value: prev_page,
                    required: true,
                });
                work_area.append({
                    type: 'input',
                    name: 'section',
                    label: wgULS('章节(可选)', '章節(可選)'),
                    tooltip: wgULS('您留言的章节标题,留空则不会产生章节链接。', '您留言的章節標題,留空則不會產生章節連結。'),
                    value: prev_section,
                });
                break;
            case 'notice': {
                var noticeboard_1 = work_area.append({
                    type: 'select',
                    name: 'noticeboard',
                    label: '通告板:',
                });
                $.each(Twinkle.talkback.noticeboards, function (value, data) {
                    noticeboard_1.append({
                        type: 'option',
                        label: data.label,
                        value: value,
                        selected: !!data.defaultSelected,
                    });
                });
                work_area.append({
                    type: 'input',
                    name: 'section',
                    label: wgULS('章节(可选)', '章節(可選)'),
                    tooltip: wgULS('章节标题,留空则不会产生章节链接。', '章節標題,留空則不會產生章節連結。'),
                    value: prev_section,
                });
                break;
            }
            case 'other':
                work_area.append({
                    type: 'div',
                    label: '',
                    style: 'color: #f00',
                    id: 'twinkle-talkback-optout-message',
                });
                work_area.append({
                    type: 'input',
                    name: 'page',
                    label: wgULS('完整页面名', '完整頁面名'),
                    tooltip: wgULS('您留下消息的完整页面名,例如“LIB_talk:首页”。', '您留下訊息的完整頁面名,例如「LIB_talk:首頁」。'),
                    value: prev_page,
                    required: true,
                });
                work_area.append({
                    type: 'input',
                    name: 'section',
                    label: wgULS('章节(可选)', '章節(可選)'),
                    tooltip: wgULS('您留言的章节标题,留空则不会产生章节链接。', '您留言的章節標題,留空則不會產生章節連結。'),
                    value: prev_section,
                });
                break;
            case 'mail':
                work_area.append({
                    type: 'input',
                    name: 'section',
                    label: wgULS('电子邮件主题(可选)', '電子郵件主題(可選)'),
                    tooltip: wgULS('您发出的电子邮件的主题。', '您發出的電子郵件的主題。'),
                });
                break;
            case 'see':
                work_area.append({
                    type: 'input',
                    name: 'page',
                    label: wgULS('完整页面名', '完整頁面名'),
                    tooltip: wgULS('您留下消息的完整页面名,例如“LIB_talk:首页”。', '您留下訊息的完整頁面名,例如「LIB_talk:首頁」。'),
                    value: prev_page,
                    required: true,
                });
                work_area.append({
                    type: 'input',
                    name: 'section',
                    label: wgULS('章节(可选)', '章節(可選)'),
                    tooltip: wgULS('您留言的章节标题,留空则不会产生章节链接。', '您留言的章節標題,留空則不會產生章節連結。'),
                    value: prev_section,
                });
                break;
        }
        if (value !== 'notice') {
            work_area.append({
                type: 'textarea',
                label: wgULS('附加信息(可选):', '附加資訊(可選):'),
                name: 'message',
                tooltip: wgULS('会在回复通告模板下出现的消息,您的签名会被加在最后。', '會在回覆通告模板下出現的訊息,您的簽名會被加在最後。'),
            });
        }
        work_area = work_area.render();
        root.replaceChild(work_area, old_area);
        if (root.message) {
            root.message.value = prev_message;
        }
        $('#twinkle-talkback-optout-message').text(Twinkle.talkback.optout);
    };
    Twinkle.talkback.noticeboards = {
        affp: {
            label: "LIB:AF/FP\uFF08".concat(wgULS('过滤器处理/报告', '過濾器處理/報告'), "\uFF09"),
            title: wgULS('过滤器错误报告有新回应', '過濾器錯誤報告有新回應'),
            content: "".concat(wgULS('您的[[LIB_talk:过滤器处理/报告|过滤器错误报告]]已有回应,请前往查看。', '您的[[LIB_talk:过滤器处理/报告|過濾器錯誤報告]]已有回應,請前往查看。'), "--~~~~"),
            editSummary: wgULS('有关[[LIB_talk:过滤器处理/报告|过滤器错误报告]]的通知', '有關[[LIB_talk:过滤器处理/报告|過濾器錯誤報告]]的通知'),
            defaultSelected: true,
        },
    };
    Twinkle.talkback.evaluate = function (e) {
        var form = e.target;
        var tbtarget = form.getChecked('tbtarget')[0];
        var page;
        var message;
        var section = form.section.value;
        var editSummary;
        if (tbtarget === 'notice') {
            page = form.noticeboard.value;
            editSummary = Twinkle.talkback.noticeboards[page].editSummary;
        }
        else {
            // usertalk, other, see
            page = form.page ? form.page.value : mw.config.get('wgUserName');
            if (form.message) {
                message = form.message.value.trim();
            }
            if (tbtarget === 'mail') {
                editSummary = wgULS('通知:有新邮件', '通知:有新郵件');
            }
            else if (tbtarget === 'see') {
                editSummary = "".concat(wgULS('请看看', '請看看'), "[[:").concat(page).concat(section ? "#".concat(section) : '', "]]").concat(wgULS('上的讨论', '上的討論'));
            }
            else {
                // tbtarget one of mytalk, usertalk, other
                editSummary = "".concat(wgULS('回复通告', '回覆通告'), "\uFF08[[:");
                if (tbtarget !== 'other' && !new RegExp("^\\s*".concat(Morebits.namespaceRegex(3), ":"), 'i').test(page)) {
                    editSummary += 'User talk:';
                }
                editSummary += "".concat(page + (section ? "#".concat(section) : ''), "]])");
            }
        }
        Morebits.simpleWindow.setButtonsEnabled(false);
        Morebits.status.init(form);
        var fullUserTalkPageName = "".concat(mw.config.get('wgFormattedNamespaces')[mw.config.get('wgNamespaceIds').user_talk], ":").concat(mw.config.get('wgRelevantUserName'));
        Morebits.wiki.actionCompleted.redirect = fullUserTalkPageName;
        Morebits.wiki.actionCompleted.notice = wgULS('回复通告完成,将在几秒内刷新页面', '回覆通告完成,將在幾秒內重新整理頁面');
        var text = "\n\n".concat(Twinkle.talkback.getNoticeWikitext(tbtarget, page, section, message)[0]);
        var talkpage = new Morebits.wiki.page(fullUserTalkPageName, wgULS('加入回复通告', '加入回覆通告'));
        talkpage.setEditSummary(editSummary);
        talkpage.setChangeTags(Twinkle.changeTags);
        talkpage.setAppendText(text);
        talkpage.setCreateOption('recreate');
        talkpage.setMinorEdit(Twinkle.getPref('markTalkbackAsMinor'));
        talkpage.setFollowRedirect(true);
        talkpage.append();
    };
    Twinkle.talkback.preview = function (form) {
        var tbtarget = form.getChecked('tbtarget')[0];
        var section = form.section.value;
        var page;
        var message;
        if (tbtarget === 'notice') {
            page = form.noticeboard.value;
        }
        else {
            // usertalk, other, see
            page = form.page ? form.page.value : mw.config.get('wgUserName');
            if (form.message) {
                message = form.message.value.trim();
            }
        }
        var noticetext = Twinkle.talkback.getNoticeWikitext(tbtarget, page, section, message)[0];
        form.previewer.beginRender(noticetext, "User_talk:".concat(mw.config.get('wgRelevantUserName'))); // Force wikitext/correct username
    };
    Twinkle.talkback.getNoticeWikitext = function (tbtarget, page, section, message) {
        var text;
        var title;
        var content;
        if (tbtarget === 'notice') {
            title = Twinkle.talkback.noticeboards[page].title;
            content = Morebits.string.safeReplace(Twinkle.talkback.noticeboards[page].content, '$SECTION', section);
            text = "== ".concat(title, " ==\n").concat(content);
        }
        else if (tbtarget === 'see') {
            title = page + wgULS('的相关讨论', '的相關討論');
            content = "{{subst:Please see|location=".concat(page).concat(section ? "#".concat(section) : '', "|more=").concat(message.trim(), "}}");
            text = "{{subst:Please see|location=".concat(page).concat(section ? "#".concat(section) : '', "|more=").concat(message.trim(), "}}");
        }
        else {
            text = '==';
            if (tbtarget === 'mail') {
                title = Twinkle.getPref('mailHeading');
                content = "{{You've got mail|subject=".concat(section, "|ts=~~~~~}}");
                text += "".concat(Twinkle.getPref('mailHeading'), "==\n{{You've got mail|subject=").concat(section);
            }
            else {
                // tbtarget one of mytalk, usertalk, other
                // clean talkback heading: strip section header markers that were erroneously suggested in the documentation
                title = Twinkle.getPref('talkbackHeading').replace(/^\s*=+\s*(.*?)\s*=+$\s*/, '$1');
                content = "{{talkback|".concat(page).concat(section ? "|".concat(section) : '');
                text += "".concat(Twinkle.getPref('talkbackHeading').replace(/^\s*=+\s*(.*?)\s*=+$\s*/, '$1'), "==\n{{talkback|").concat(page).concat(section ? "|".concat(section) : '');
            }
            content += '|ts=~~~~~}}';
            text += '|ts=~~~~~}}';
            if (message) {
                content += "\n".concat(message);
                text += "\n".concat(message, "  ~~~~");
            }
            else if (Twinkle.getPref('insertTalkbackSignature')) {
                text += '\n~~~~';
            }
        }
        return [text, title, content];
    };
    Twinkle.addInitCallback(Twinkle.talkback, 'talkback');
})(jQuery);

/* </nowiki> */