跳转到内容

User:SuperGrey/gadgets/voter/main.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// Main page: [[User:SuperGrey/gadgets/voter]]

var 取得名稱 = mw.config.get('wgPageName');
var ceaseRunning = true;

if (取得名稱 == 'Wikipedia:新条目推荐/候选') {
    ceaseRunning = false;
    var labelValidVotes = [{
        data: '支持',
        label: '支持'
    },
    {
        data: '反對',
        label: '反對'
    },
    {
        data: '不合要求',
        label: '不合要求'
    },
    {
        data: '問題不當',
        label: '問題不當'
    }
    ];
}
if (取得名稱 == "Wikipedia:優良條目評選" || (/^Wikipedia:優良條目評選\//i.test(取得名稱))) {
    ceaseRunning = false;
    var labelValidVotes = [{
        data: 'yesGA',
        label: '符合優良條目標準'
    },
    {
        data: 'noGA',
        label: '不符合優良條目標準'
    }
    ];
}
if (取得名稱 == "Wikipedia:典范条目评选" || (/^Wikipedia:典范条目评选\//i.test(取得名稱))) {
    ceaseRunning = false;
    var labelValidVotes = [{
        data: 'yesFA',
        label: '符合典範條目標準'
    },
    {
        data: 'noFA',
        label: '不符合典範條目標準'
    }
    ];
}
if (取得名稱 == "Wikipedia:特色列表评选" || (/^Wikipedia:特色列表评选\//i.test(取得名稱))) {
    ceaseRunning = false;
    var labelValidVotes = [{
        data: 'yesFL',
        label: '符合特色列表標準'
    },
    {
        data: 'noFL',
        label: '不符合特色列表標準'
    }
    ];
}

var labelInvalidVotes = [{
    data: '中立',
    label: '中立'
},
{
    data: '意見',
    label: '意見'
},
{
    data: '建議',
    label: '建議'
},
{
    data: '疑問',
    label: '疑問'
},
{
    data: '同上',
    label: '同上'
},
{
    data: '提醒',
    label: '提醒'
}
];

if (ceaseRunning) {
    throw new Error(); // 非目標頁面,直接停止執行。
}
console.log("[Voter] Voter 已載入,當前頁面為 " + 取得名稱 + "。");
mw.loader.load(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows']);


function 取得投票編輯編號(childid) {
    var 投票編輯編號 = 0;
    if (取得名稱 == 'Wikipedia:新条目推荐/候选') {
        if ($('div.mw-heading.mw-heading4:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').match('editsource')) {
            投票編輯編號 = $('div.mw-heading.mw-heading4:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').split("&")[1].split("=")[1];
        } else {
            投票編輯編號 = $('div.mw-heading.mw-heading4:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').split("&")[2].split("=")[1];
        }
    }
    if (取得名稱 == "Wikipedia:優良條目評選" || 取得名稱 == "Wikipedia:典范条目评选" || 取得名稱 == "Wikipedia:特色列表评选") {
        if ($('div.mw-heading.mw-heading3:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').match('editsource')) {
            投票編輯編號 = $('div.mw-heading.mw-heading3:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').split("&")[1].split("=")[1].substring(2);
        } else {
            投票編輯編號 = $('div.mw-heading.mw-heading3:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').split("&")[2].split("=")[1].substring(2);
        }
    }
    if ((/^Wikipedia:(優良條目評選|典范条目评选|特色列表评选)\//i.test(取得名稱))) {
        if ($('div.mw-heading.mw-heading3:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').match('editsource')) {
            投票編輯編號 = $('div.mw-heading.mw-heading3:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').split("&")[1].split("=")[1];
        } else {
            投票編輯編號 = $('div.mw-heading.mw-heading3:nth-child(' + childid.toString() + ') > span.mw-editsection > a').attr('href').split("&")[2].split("=")[1];
        }
    }
    return +投票編輯編號;
}

var sectionTitles = [];

if (取得名稱 == "Wikipedia:新条目推荐/候选") {
    for (var 投票child編號 = 1; 投票child編號 < 300; 投票child編號++) {
        if (!!$('div.mw-heading.mw-heading4:nth-child(' + 投票child編號.toString() + ')').nextUntil('div.mw-heading.mw-heading4', 'ul').find('li .anchor').attr('id')) {
            var 投票編輯編號 = 取得投票編輯編號(投票child編號);
            $('<span class="mw-editsection-bracket">|</span> <a onclick="voteedit(' + 投票編輯編號 + ')">投票</a>').insertAfter($('div.mw-heading.mw-heading4:nth-child(' + 投票child編號.toString() + ') > span.mw-editsection > a'));
            sectionTitles.push({
                data: 投票編輯編號,
                label: $('div.mw-heading.mw-heading4:nth-child(' + 投票child編號.toString() + ')').nextUntil('div.mw-heading.mw-heading4', 'ul').find('li .anchor').attr('id').replace(/_/g, ' ')
            });
        }
    }
}
if (取得名稱 == "Wikipedia:優良條目評選" || 取得名稱 == "Wikipedia:典范条目评选" || 取得名稱 == "Wikipedia:特色列表评选" || (/^Wikipedia:(優良條目評選|典范条目评选|特色列表评选)\//i.test(取得名稱))) {
    for (var 投票child編號 = 1; 投票child編號 < 300; 投票child編號++) {
        if (!!$('div.mw-heading.mw-heading3:nth-child(' + 投票child編號.toString() + ') > h3').attr('id')) {
            var 投票編輯編號 = 取得投票編輯編號(投票child編號);
            $('<span class="mw-editsection-bracket">|</span> <a onclick="voteedit(' + 投票編輯編號 + ')">投票</a>').insertAfter($('div.mw-heading.mw-heading3:nth-child(' + 投票child編號.toString() + ') > span.mw-editsection > a'));
            sectionTitles.push({
                data: 投票編輯編號,
                label: $('div.mw-heading.mw-heading3:nth-child(' + 投票child編號.toString() + ') > h3').attr('id').replace(/_/g, ' ')
            });
        }
    }
}
console.log("[Voter] 已識別可投票事項共 " + sectionTitles.length.toString() + " 項。");

// 檢查 OO.ui 是否正確加載。若加載失敗則刷新。
if (!OO.ui) {
    location.reload();
}

function VoteDialog(config) {
    VoteDialog.super.call(this, config);
}
OO.inheritClass(VoteDialog, OO.ui.ProcessDialog);

VoteDialog.static.name = 'voteDialog';
VoteDialog.static.title = '投票助手';

VoteDialog.static.actions = [{
    flags: ['primary', 'progressive'],
    label: '儲存投票',
    action: 'save'
},
{
    flags: 'safe',
    label: '取消'
}
];


VoteDialog.prototype.initialize = function () {
    VoteDialog.super.prototype.initialize.call(this);
    this.panel = new OO.ui.PanelLayout({
        padded: true,
        expanded: false
    });
    this.content = new OO.ui.FieldsetLayout();

    this.entrySelection = new OO.ui.MenuTagMultiselectWidget({
        options: sectionTitles
    });
    this.fieldEntrySelection = new OO.ui.FieldLayout(this.entrySelection, {
        label: '投票條目:',
        align: 'top'
    });

    this.labelSelection = new OO.ui.MenuTagMultiselectWidget({
        options: labelValidVotes.concat(labelInvalidVotes)
    });
    this.fieldLabelSelection = new OO.ui.FieldLayout(this.labelSelection, {
        label: '投票模板:',
        align: 'top'
    });

    this.voteMessageInput = new OO.ui.MultilineTextInputWidget({
        autosize: true,
        rows: 1,
        maxRows: 10
    });
    this.fieldVoteMessageInput = new OO.ui.FieldLayout(this.voteMessageInput, {
        label: '投票理由:',
        align: 'top'
    });

    this.content.addItems([this.fieldEntrySelection, this.fieldLabelSelection, this.fieldVoteMessageInput]);
    this.panel.$element.append(this.content.$element);
    this.$body.append(this.panel.$element);

    this.voteMessageInput.connect(this, { 'resize': 'onVoteMessageInputResize' });
};

VoteDialog.prototype.onVoteMessageInputResize = function () {
    this.updateSize();
};

VoteDialog.prototype.getBodyHeight = function () {
    return this.panel.$element.outerHeight(true);
};

function sectionTitlesQuery(sectionID) {
    return sectionTitles.find(obj => obj.data === sectionID);
}

VoteDialog.prototype.getSetupProcess = function (data) {
    data = data || {};
    return VoteDialog.super.prototype.getSetupProcess.call(this, data)
        .next(function () {
            this.entrySelection.setValue(sectionTitlesQuery(data.sectionID));  // 投票條目
            this.labelSelection.setValue(this.labelSelection.getAllowedValues()[0]);  // 投票模板
        }, this);
};

VoteDialog.prototype.getActionProcess = function (action) {
    if (action === 'save') {
        if ((!!this.entrySelection.getValue().length) && (!!this.labelSelection.getValue().length)) {
            var dialog = this;
            return new OO.ui.Process(async function () {
                var response = await VoteEdit(this.entrySelection.getValue(), this.labelSelection.getValue(), this.voteMessageInput.getValue());
                if (!response) {
                    dialog.close({
                        action: action
                    });
                }
            }, this);
        }
    }
    return VoteDialog.super.prototype.getActionProcess.call(this, action);
};

VoteDialog.prototype.getTeardownProcess = function (data) {
    return VoteDialog.super.prototype.getTeardownProcess.call(this, data)
        .first(function () {
            // does nothing
        }, this);
};

var windowManager = new OO.ui.WindowManager();
$(document.body).append(windowManager.$element);

var voteDialog = new VoteDialog();

windowManager.addWindows([voteDialog]);



function voteedit(投票編輯編號) {
    event.preventDefault();

    if (!windowManager) {
        // OO.ui 未正確加載,直接刷新。
        voteF5(sectionTitlesQuery(投票編輯編號).label);
    }
    windowManager.openWindow(voteDialog, { sectionID: 投票編輯編號 });
}

function titleVariants(title) {
    var title_spaceReplacedByUnderscore = title.replace(/ /g, '_');
    var title_underscoreReplacedBySpace = title.replace(/_/g, ' ');
    return [title, title_spaceReplacedByUnderscore, title_underscoreReplacedBySpace, title_spaceReplacedByUnderscore[0].toUpperCase() + title_spaceReplacedByUnderscore.slice(1), title_underscoreReplacedBySpace[0].toUpperCase() + title_underscoreReplacedBySpace.slice(1)];
}

function textMatchTitleVariants(text, title) {
    return titleVariants(title).some(titleVariant => text.includes(titleVariant));
}

async function VoteEditNB(tracePage, destinationPage, 投票編輯編號, edittext, editsummary) {
    var section_title = sectionTitlesQuery(投票編輯編號).label;
    mw.notify('正在為「' + section_title + '」投出一票⋯⋯');
    var api = new mw.Api();
    var response = await api.get({
        'action': 'query',
        'titles': tracePage,
        'prop': 'revisions|info',
        'rvslots': '*',
        'rvprop': 'content',
        'rvsection': 投票編輯編號,
        'indexpageids': 1
    });
    var section_text = response.query.pages[response.query.pageids[0]].revisions[0].slots.main['*'];

    // If the section_title is not found in the section_text, then halt with an error.
    if (section_text !== undefined && !textMatchTitleVariants(section_text, section_title)) {
        mw.notify('在該章節找不到名為「' + section_title + '」的提名,可能發生編輯衝突,請刷新頁面後重試。');
        return true;
    }

    await api.post({
        'action': 'edit',
        'title': destinationPage,
        'appendtext': '\n' + edittext,
        'section': 投票編輯編號,
        'summary': editsummary,
        'token': mw.user.tokens.get('csrfToken')
    });
    mw.notify('「' + section_title + '」已完成投票。');
    return false;
}
function addIndent(str, indent) {
    return str.replace(/^/gm, indent);
}

async function VoteEdit(voteIDs, voteLabels, voteMessage) {
    event.preventDefault();
    var VTReason = '';
    if (voteLabels != '') {
        VTReason += voteLabels.map(str => `{{${str}}}`).join(';');
    }
    if (voteMessage != '') {
        VTReason += ':' + voteMessage;
    } else {
        VTReason += '。';
    }
    VTReason += '--~~' + '~~';

    if (取得名稱 == 'Wikipedia:新条目推荐/候选') {
        for (const 投票編輯編號 of voteIDs) {
            if (await VoteEditNB(取得名稱, 取得名稱, 投票編輯編號, addIndent(VTReason, '**'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/gadgets/voter|Voter]])'))
                return true;
        }
    }
    if (取得名稱 == "Wikipedia:優良條目評選") {
        for (const 投票編輯編號 of voteIDs) {
            if (await VoteEditNB(取得名稱, 取得名稱 + '/提名區', 投票編輯編號, addIndent(VTReason, '*'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/gadgets/voter|Voter]])'))
                return true;
        }
    }
    if (取得名稱 == "Wikipedia:典范条目评选" || 取得名稱 == "Wikipedia:特色列表评选") {
        for (const 投票編輯編號 of voteIDs) {
            if (await VoteEditNB(取得名稱, 取得名稱 + '/提名区', 投票編輯編號, addIndent(VTReason, '*'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/gadgets/voter|Voter]])'))
                return true;
        }
    }
    if ((/^Wikipedia:(優良條目評選|典范条目评选|特色列表评选)\//i.test(取得名稱))) {
        for (const 投票編輯編號 of voteIDs) {
            if (await VoteEditNB(取得名稱, 取得名稱, 投票編輯編號, addIndent(VTReason, '*'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/gadgets/voter|Voter]])'))
                return true;
        }
    }

    setTimeout(function () { voteF5(sectionTitlesQuery(voteIDs[0]).label) }, 1000);
    return false;
}

function voteF5(entryName) {
    location.href = mw.util.getUrl(取得名稱 + '#' + entryName);
    location.reload();
}