MediaWiki:Gadget-ondemand-arbcomVoting.js: различия между версиями
Перейти к навигации
Перейти к поиску
Содержимое удалено Содержимое добавлено
Stjn (обсуждение | вклад) надо будет переделать потом Метка: отменено |
Stjn (обсуждение | вклад) 2 правки возвращены к версии 136285287 Stjn: не уверен, что в допотопном коде всё будет верно работать, поэтому отменю Метка: ручная отмена |
||
Строка 11: | Строка 11: | ||
/******* COMMON ******* */ |
/******* COMMON ******* */ |
||
function en(e) { return encodeURIComponent(e) } |
|||
function el(e) { return document.createElement(e) } |
function el(e) { return document.createElement(e) } |
||
function tstamp(t) { return !t.getUTCFullYear() ? null : // Safari + Chrome |
function tstamp(t) { return !t.getUTCFullYear() ? null : // Safari + Chrome |
||
Строка 21: | Строка 22: | ||
var data = {}; // MediaWiki:Script/Voting.json |
var data = {}; // MediaWiki:Script/Voting.json |
||
var wgServer = mw.config.get('wgServer'); |
|||
var wgScript = mw.config.get('wgScript'); |
|||
var wgAPIPath = wgServer + mw.config.get('wgScriptPath') + '/api.php?format=json&'; |
|||
var wgUserName = mw.config.get('wgUserName'); |
var wgUserName = mw.config.get('wgUserName'); |
||
var wgNamespaceNumber = mw.config.get('wgNamespaceNumber'); |
var wgNamespaceNumber = mw.config.get('wgNamespaceNumber'); |
||
Строка 130: | Строка 134: | ||
td1 = el('td'); |
td1 = el('td'); |
||
img = el('img'); |
img = el('img'); |
||
img.alt = ' |
img.alt = '+'; |
||
img.width = img.height = 39; |
img.width = img.height = 39; |
||
img.src = data.icons.up + (votes[i].orig == 1 ? data.icons.suppinact : data.icons.supp); |
img.src = data.icons.up + (votes[i].orig == 1 ? data.icons.suppinact : data.icons.supp); |
||
lin = el('a'); |
lin = el('a'); |
||
lin.href = '#'; |
lin.href = '#'; |
||
lin.title = |
lin.title = '+'; |
||
lin.appendChild(img); |
lin.appendChild(img); |
||
td1.appendChild(lin); |
td1.appendChild(lin); |
||
Строка 141: | Строка 145: | ||
td2 = el('td'); |
td2 = el('td'); |
||
img = el('img'); |
img = el('img'); |
||
img.alt = ' |
img.alt = '−'; |
||
img.width = img.height = 39; |
img.width = img.height = 39; |
||
img.src = data.icons.up + (votes[i].orig == -1 ? data.icons.oppinact : data.icons.opp); |
img.src = data.icons.up + (votes[i].orig == -1 ? data.icons.oppinact : data.icons.opp); |
||
lin = el('a'); |
lin = el('a'); |
||
lin.href = '#'; |
lin.href = '#'; |
||
lin.title = |
lin.title = '-'; |
||
lin.appendChild(img); |
lin.appendChild(img); |
||
td2.appendChild(lin); |
td2.appendChild(lin); |
||
Строка 153: | Строка 157: | ||
td3.className = 'talklink'; |
td3.className = 'talklink'; |
||
lin = el('a'); |
lin = el('a'); |
||
lin.href = |
lin.href = wgServer + wgScript + '?title=' + encodeURI(data.config.talkpath + i); |
||
lin.target = '_blank'; |
lin.target = '_blank'; |
||
lin.title = 'Вопросы ' + i + ' (откроется в новой вкладке)'; |
|||
lin.innerHTML = i; |
lin.innerHTML = i; |
||
Строка 171: | Строка 174: | ||
var imgs = div1.getElementsByTagName('img'); |
var imgs = div1.getElementsByTagName('img'); |
||
for (i=0; i<imgs.length; i++) { |
for (i=0; i<imgs.length; i++) { |
||
imgs[i].parentNode. |
imgs[i].parentNode.onclick = oncl; |
||
imgs[i].parentNode.addEventListener( 'keydown', onkeydown ); |
|||
imgs[i].parentNode.setAttribute( 'role', 'button' ); |
|||
} |
} |
||
Строка 232: | Строка 233: | ||
// onclick() for round buttons |
// onclick() for round buttons |
||
function oncl( |
function oncl() { |
||
e.preventDefault(); |
|||
var imgs = this.parentNode.parentNode.getElementsByTagName('img'); |
var imgs = this.parentNode.parentNode.getElementsByTagName('img'); |
||
var link = this.parentNode.parentNode.getElementsByTagName('a')[2]; |
var link = this.parentNode.parentNode.getElementsByTagName('a')[2]; |
||
var ca = link.innerHTML; |
var ca = link.innerHTML; |
||
var ti = this.title; |
var ti = this.title; |
||
var vo = ti==' |
var vo = ti=='+'?1:-1; |
||
votes[ca].value = (votes[ca].value==vo) ? 0 : vo; |
votes[ca].value = (votes[ca].value==vo) ? 0 : vo; |
||
Строка 245: | Строка 245: | ||
link.className = ['opp', '', 'supp'][votes[ca].value + 1]; |
link.className = ['opp', '', 'supp'][votes[ca].value + 1]; |
||
} |
|||
return false; |
|||
// onkeydown for round buttons |
|||
function onkeydown( e ) { |
|||
if ( [ 'Space', 'Enter' ].includes( e.code ) ) { |
|||
e.preventDefault(); |
|||
this.click(); |
|||
} |
|||
} |
} |
||
Версия от 20:51, 1 марта 2024
/*
* Скрипт для выборов в Арбитражный комитет (ВП:АК)
*
* Авторы: Kalan, Serhio Magpie (эта версия).
* История правок старого скрипта:
* https://ru.wikipedia.org/wiki/MediaWiki:Script/Voting-backup.js
*/
(function () {
/******* COMMON ******* */
function en(e) { return encodeURIComponent(e) }
function el(e) { return document.createElement(e) }
function tstamp(t) { return !t.getUTCFullYear() ? null : // Safari + Chrome
(t.getUTCFullYear()+":0"+(t.getUTCMonth()+1)+":0"+t.getUTCDate()+":0"+
t.getUTCHours() +":0"+ t.getUTCMinutes() +":0"+t.getUTCSeconds())
.replace(/:0?(\d\d)/g, '$1') }
function ch(o) { for (var i in o) { return o[i] } }
/******* VARIABLES *******/
var data = {}; // MediaWiki:Script/Voting.json
var wgServer = mw.config.get('wgServer');
var wgScript = mw.config.get('wgScript');
var wgAPIPath = wgServer + mw.config.get('wgScriptPath') + '/api.php?format=json&';
var wgUserName = mw.config.get('wgUserName');
var wgNamespaceNumber = mw.config.get('wgNamespaceNumber');
var votes = {};
var saving = null;
var api = new mw.Api();
var containerEl, statusEl, btnEl;
/******* MAIN *******/
function votingLength( date, days ) {
var result = new Date( date );
result.setDate( result.getDate() + days );
return result;
}
function votingStart() {
containerEl.className = 'active';
statusEl.innerHTML = data.strings.statuscriteria;
btnEl.setDisabled(true);
btnEl.$element.css( 'display', 'none' );
api.get({
'action': 'query',
'list': 'users',
'usprop': ['registration', 'editcount'],
'prop': 'revisions',
'rvprop': 'content',
'ususers': wgUserName,
'titles': data.config.voteexceptionspath
}).done(votingStartContinue);
}
function votingStartContinue(d) {
query = d.query;
pages = query.pages;
userinfo = query.users[0];
if ((// a valid voter must be a non-anonymous user
typeof userinfo === 'undefined' || typeof userinfo.missing !== 'undefined' ||
// who is not blocked
userinfo.blockedby ||
// whose editcount is at least data.config.criteria.count
userinfo.editcount < data.config.criteria.count ||
// and who is registered no later than data.config.criteria.registration
// "null" means "before 2005-12-29", user creation was not logged before then
(userinfo.registration !== null && userinfo.registration > data.config.criteria.registration)) &&
// exemptions
('\n' + ch(pages).revisions[0]['*'] + '\n').indexOf('\n* %\n'.replace('%', wgUserName)) == -1
) {
votingCriteriaFail();
} else {
votingContinue();
}
}
function votingCriteriaFail() {
statusEl.innerHTML = data.strings.criteriafail;
}
function votingContinue() {
statusEl.innerHTML = data.strings.loadingvotes;
// latest contributions in ns:4
api.get({
'action': 'query',
'list': 'usercontribs',
'ucnamespace': wgNamespaceNumber,
'uclimit': 500,
'ucuser': wgUserName,
'ucend': tstamp(data.config.start),
'ucdir': 'older',
'prop': 'revisions',
'rvprop': 'content'
}).done(votingDraw);
}
function votingDraw(d) {
statusEl.innerHTML = '';
btnEl.setLabel(data.strings.savebutton);
btnEl.setDisabled(false);
btnEl.off('click').on('click', votingSave);
btnEl.$element.css( 'display', '' );
var query = d.query;
var co = query.usercontribs;
// retrieving votes, according to contributions, only latest ones are valid
for (i=0; i<data.candidates.length; i++) {
votes[data.candidates[i]] = {'orig':0, 'value':0};
}
for (var i=co.length-1; i>=0; i--) {
var m = co[i].title.indexOf(data.config.votepath) === 0;
if (m) {
m = co[i].title.match(/\/([+-])\/(.*?)$/);
}
if (m) {
votes[m[2]] = { 'orig' : m[1]=='+' ? +1 : -1, 'value': 0 };
}
}
// drawing
var div1 = el('div');
div1.id = 'voting-standard';
div1.innerHTML = data.strings.votinghelp;
var tab = el('table');
var tr, img, td1, td2, td3, lin;
for (i in votes) {
if (!i.match(/^_[srl]$/)) {
tr = el('tr');
td1 = el('td');
img = el('img');
img.alt = '+';
img.width = img.height = 39;
img.src = data.icons.up + (votes[i].orig == 1 ? data.icons.suppinact : data.icons.supp);
lin = el('a');
lin.href = '#';
lin.title = '+';
lin.appendChild(img);
td1.appendChild(lin);
td2 = el('td');
img = el('img');
img.alt = '−';
img.width = img.height = 39;
img.src = data.icons.up + (votes[i].orig == -1 ? data.icons.oppinact : data.icons.opp);
lin = el('a');
lin.href = '#';
lin.title = '-';
lin.appendChild(img);
td2.appendChild(lin);
td3 = el('td');
td3.className = 'talklink';
lin = el('a');
lin.href = wgServer + wgScript + '?title=' + encodeURI(data.config.talkpath + i);
lin.target = '_blank';
lin.innerHTML = i;
td3.appendChild(lin);
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tab.appendChild(tr);
}
}
div1.appendChild(tab);
// IE has problems inserting the table
div1.innerHTML += '';
var imgs = div1.getElementsByTagName('img');
for (i=0; i<imgs.length; i++) {
imgs[i].parentNode.onclick = oncl;
}
statusEl.innerHTML = data.strings.justbeforesave;
statusEl.parentNode.insertBefore(div1, statusEl);
}
function votingSave() {
if (!saving) {
var div = el('div');
div.id = 'voting-saving';
div.innerHTML = '<div id="voting-progress"><div id="voting-progress-progress" style="width:0%"> </div></div>' + data.strings.saveprog;
statusEl.parentNode.appendChild(div);
btnEl.setDisabled(true);
document.getElementById('voting-standard').style.visibility = 'hidden';
saving = {'cursor': 0, 'pages': []};
for (var i in votes) {
if (votes[i].value != 0 && votes[i].orig != votes[i].value) {
saving.pages[saving.cursor++] = {
'text': '\n# [[user:' + wgUserName + '|' + wgUserName + ']] ~' + '~~' + '~~\n',
'page': data.config.votepath + (votes[i].value==1?'+':'-') + '/' + i
};
}
}
saving.cursor = -5;
if (saving.pages.length) {
votingSave();
} else {
document.getElementById('voting-container').innerHTML = data.strings.thankyou;
}
} else {
if (saving.cursor === -5) {
saving.cursor = 0;
}
if (saving.cursor === -1) {
return;
}
document.getElementById('voting-progress-progress').style.width = 100*(saving.cursor+1)/saving.pages.length + '%';
api.postWithToken('edit', {
'action': 'edit',
'notminor': 1,
'unwatch': 1,
'summary': data.strings.summary,
'title': saving.pages[saving.cursor].page,
'appendtext': saving.pages[saving.cursor].text
}).done(votingSave);
saving.cursor++;
if (!saving.pages[saving.cursor]) {
saving.cursor = -1;
document.getElementById('voting-container').innerHTML = data.strings.thankyou;
}
}
}
// onclick() for round buttons
function oncl() {
var imgs = this.parentNode.parentNode.getElementsByTagName('img');
var link = this.parentNode.parentNode.getElementsByTagName('a')[2];
var ca = link.innerHTML;
var ti = this.title;
var vo = ti=='+'?1:-1;
votes[ca].value = (votes[ca].value==vo) ? 0 : vo;
imgs[0].src = data.icons.up + (votes[ca].value== 1 ?data.icons.suppact:(votes[ca].orig== 1 ?data.icons.suppinact:data.icons.supp));
imgs[1].src = data.icons.up + (votes[ca].value==-1 ?data.icons.oppact :(votes[ca].orig==-1 ?data.icons.oppinact :data.icons.opp));
link.className = ['opp', '', 'supp'][votes[ca].value + 1];
return false;
}
mw.loader.using(['mediawiki.util', 'oojs', 'oojs-ui']).done(function () {
// Add styles
mw.loader.load('//ru.wikipedia.org/ruwiki/w/index.php?title=MediaWiki:Voting.css&action=raw&ctype=text/css', 'text/css');
// Load configuration
$.getJSON( mw.util.wikiScript(), {
title: 'MediaWiki:Script/Voting.json',
action: 'raw'
} ).done( function (ans) {
data = ans;
// Prepare dates
data.config.start = new Date(data.config.start);
if ( typeof data.config.votelength !== 'undefined' ) {
data.config.end = votingLength( data.config.start, data.config.votelength );
} else {
data.config.end = new Date( data.config.end );
}
// Prepare pages paths
data.config.pagepath = data.config.pagepath.replace('%config.path%', data.config.path);
data.config.talkpagepath = data.config.talkpagepath.replace('%config.path%', data.config.path);
data.config.talkpath = data.config.talkpath.replace('%config.path%', data.config.path);
data.config.votepath = data.config.votepath.replace('%config.path%', data.config.path);
data.config.voteexceptionspath = data.config.voteexceptionspath.replace('%config.path%', data.config.path);
// Prepare strings
data.strings.justbeforesave = data.strings.justbeforesave.replace('%config.talkpagepath%', data.config.talkpagepath);
// Init
containerEl = document.getElementById('voting-container');
if ( containerEl ) {
containerEl.innerHTML = '';
statusEl = el('div');
statusEl.id = 'voting-status';
containerEl.appendChild(statusEl);
btnEl = new OO.ui.ButtonWidget( {
label: data.strings.votebutton,
flags: ['primary', 'progressive'],
id: 'voting-button'
} );
btnEl.on('click', votingStart);
containerEl.appendChild(btnEl.$element.get(0));
}
} );
} );
})();