注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// 修改自 [[User:小躍/Vote-Template/Vote.js]]
// 更好看、功能更全面的快速投票器(多選一鍵投票、多票種組合投票)。
// 介面採用最新 OOJS 樣式。
// 
// 使用方式:在 [[Special:MyPage/common.js]] 鍵入如下內容:
// importScript('User:SuperGrey/_voter.js');
// 
// 近期更新:適配新UI。

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',
        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)) {
            VoteEdit(this.entrySelection.getValue(), this.labelSelection.getValue(), this.voteMessageInput.getValue());

            var dialog = this;
            return new OO.ui.Process(function() {
                dialog.close({
                    action: action
                });
            });
        }
    }
    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: 投票編輯編號 });
}
async function VoteEditNB(tracePage, destinationPage, 投票編輯編號, edittext, editsummary) {
    mw.notify('正在為「' + sectionTitlesQuery(投票編輯編號).label + '」投出一票⋯⋯');
    var api = new mw.Api();
    await api.get({
        'action': 'query',
        'titles': tracePage,
        'prop': 'revisions|info',
        'intoken': 'edit',
        'rvprop': 'content',
        'indexpageids': 1
    });

    await api.post({
        'action': 'edit',
        'title': destinationPage,
        'appendtext': '\n' + edittext,
        'section': 投票編輯編號,
        'summary': editsummary,
        'token': mw.user.tokens.get('csrfToken')
    });

    mw.notify('「' + sectionTitlesQuery(投票編輯編號).label + '」已完成投票。');
}
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) {
            await VoteEditNB(取得名稱, 取得名稱, 投票編輯編號, addIndent(VTReason, '**'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/_voter.js|Voter]])');
        }
    }
    if (取得名稱 == "Wikipedia:優良條目評選") {
        for (const 投票編輯編號 of voteIDs) {
            await VoteEditNB(取得名稱, 取得名稱 + '/提名區', 投票編輯編號, addIndent(VTReason, '*'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/_voter.js|Voter]])');
        }
    }
    if (取得名稱 == "Wikipedia:典范条目评选" || 取得名稱 == "Wikipedia:特色列表评选") {
        for (const 投票編輯編號 of voteIDs) {
            await VoteEditNB(取得名稱, 取得名稱 + '/提名区', 投票編輯編號, addIndent(VTReason, '*'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/_voter.js|Voter]])');
        }
    }
    if ((/^Wikipedia:(優良條目評選|典范条目评选|特色列表评选)\//i.test(取得名稱))) {
        for (const 投票編輯編號 of voteIDs) {
            await VoteEditNB(取得名稱, 取得名稱, 投票編輯編號, addIndent(VTReason, '*'), '/* ' + sectionTitlesQuery(投票編輯編號).label + ' */ 投票([[User:SuperGrey/_voter.js|Voter]])');
        }
    }

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

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