MediaWiki:Gadget-ondemand-arbcomVoting.js: различия между версиями
Перейти к навигации
Перейти к поиску
Содержимое удалено Содержимое добавлено
Stjn (обсуждение | вклад) необъявленная зависимость |
Putnik (обсуждение | вклад) поддержка тёмной темы |
||
(не показаны 44 промежуточные версии 1 участника) | |||
Строка 2: | Строка 2: | ||
* Скрипт для выборов в Арбитражный комитет (ВП:АК) |
* Скрипт для выборов в Арбитражный комитет (ВП:АК) |
||
* |
* |
||
* Авторы: Kalan, Serhio Magpie |
* Авторы: Kalan, Serhio Magpie, stjn |
||
*/ |
*/ |
||
(function () { |
$(function () { |
||
var containerEl = document.getElementById( 'voting-container' ); |
|||
// Не запускать без элемента-триггера |
|||
if ( |
if ( containerEl === null ) { |
||
mw.log.warn( 'arbcomVoting: Aborted because no voting container was detected.' ); |
|||
return; |
|||
} |
|||
var wgUserName = mw.config.get( 'wgUserName' ); |
|||
if ( wgUserName === null ) { |
|||
mw.log.warn( 'arbcomVoting: Not logged in.' ); |
|||
return; |
return; |
||
} |
} |
||
/******* COMMON ******* */ |
/******* COMMON ******* */ |
||
function tstamp(t) { |
|||
return !t.getUTCFullYear() ? null : // Safari + Chrome |
|||
function en(e) { return encodeURIComponent(e) } |
|||
(t.getUTCFullYear()+":0"+(t.getUTCMonth()+1)+":0"+t.getUTCDate()+":0"+ |
|||
function el(e) { return document.createElement(e) } |
|||
t.getUTCHours() +":0"+ t.getUTCMinutes() +":0"+t.getUTCSeconds()) |
|||
function tstamp(t) { return !t.getUTCFullYear() ? null : // Safari + Chrome |
|||
.replace(/:0?(\d\d)/g, '$1'); |
|||
(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] } } |
function ch(o) { for (var i in o) { return o[i] } } |
||
/******* VARIABLES *******/ |
/******* VARIABLES *******/ |
||
var data = require('./ondemand-arbcomVoting.json'); |
var data = require( './ondemand-arbcomVoting.json' ); |
||
var |
var wgNamespaceNumber = mw.config.get( 'wgNamespaceNumber' ); |
||
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 votes = {}; |
||
var saving = null; |
var saving = null; |
||
var api; |
var api; |
||
var |
var statusEl; |
||
var btnEl; |
|||
/******* MAIN *******/ |
/******* MAIN *******/ |
||
Строка 42: | Строка 45: | ||
function votingStart() { |
function votingStart() { |
||
$( '.voting-container' ).addClass( 'active' ); |
|||
statusEl. |
statusEl.textContent = data.strings.statuscriteria; |
||
btnEl.setDisabled(true); |
btnEl.setDisabled(true); |
||
btnEl.$element.css( 'display', 'none' ); |
btnEl.$element.css( 'display', 'none' ); |
||
Строка 81: | Строка 84: | ||
function votingCriteriaFail() { |
function votingCriteriaFail() { |
||
statusEl. |
statusEl.textContent = ''; |
||
$( '#voting-msg-criteriafail' ).show(); |
|||
} |
} |
||
function votingContinue() { |
function votingContinue() { |
||
statusEl. |
statusEl.textContent = data.strings.loadingvotes; |
||
// latest contributions in ns:4 |
// latest contributions in ns:4 |
||
api.get({ |
api.get({ |
||
Строка 93: | Строка 97: | ||
'uclimit': 500, |
'uclimit': 500, |
||
'ucuser': wgUserName, |
'ucuser': wgUserName, |
||
'ucend': tstamp(data.config.start), |
'ucend': tstamp( data.config.start ), |
||
'ucdir': 'older' |
'ucdir': 'older' |
||
'prop': 'revisions', |
|||
'rvprop': 'content' |
|||
}).done(votingDraw); |
}).done(votingDraw); |
||
} |
|||
function onClick( e ) { |
|||
e.preventDefault(); |
|||
var button = e.currentTarget; |
|||
var span = button.querySelector( 'span' ); |
|||
var tr = button.parentNode.parentNode; |
|||
var candidate = button.dataset.candidate; |
|||
var type = button.dataset.type; |
|||
var active = Boolean( button.getAttribute( 'aria-checked' ) ); |
|||
var option = data.options[ type ]; |
|||
// Update other button first |
|||
var otherButton = tr.querySelector( `.vote-button[aria-checked="true"]` ); |
|||
var otherType = otherButton && otherButton.dataset.type; |
|||
if ( otherButton ) { |
|||
var otherVote = otherType === 'support' ? 1 : -1; |
|||
otherButton.setAttribute( 'aria-checked', false ); |
|||
} |
|||
// Change vote |
|||
var vote = type === 'support' ? 1 : -1; |
|||
var sameVote = votes[ candidate ].value === vote; |
|||
votes[ candidate ].value = ( sameVote ? 0 : vote ); |
|||
button.setAttribute( 'aria-checked', !sameVote ); |
|||
// Update table row |
|||
tr.className = !sameVote ? 'vote-' + type : ''; |
|||
} |
|||
function addVoteButton( candidate, type, previousVote ) { |
|||
var option = data.options[ type ]; |
|||
var didVote = previousVote === ( type === 'support' ? 1 : -1 ); |
|||
var votedOpposite = previousVote === ( type === 'support' ? -1 : 1 ); |
|||
var voteType = votedOpposite ? 'changevote' : 'novote'; |
|||
var button = document.createElement( 'button' ); |
|||
button.className = 'vote-button skin-invert'; |
|||
button.setAttribute( 'role', 'switch' ); |
|||
button.setAttribute( 'type', 'button' ); |
|||
button.setAttribute( 'data-candidate', candidate ); |
|||
button.setAttribute( 'data-type', type ); |
|||
if ( didVote ) { |
|||
button.setAttribute( 'data-voted', true ); |
|||
} |
|||
button.setAttribute( 'aria-checked', didVote ); |
|||
button.addEventListener( 'click', onClick ); |
|||
var span = document.createElement( 'span' ); |
|||
span.textContent = option[ voteType ]; |
|||
if ( votedOpposite ) { |
|||
span.textContent = span.textContent.replace( '%candidate%', candidate ); |
|||
} |
|||
button.title = span.textContent; |
|||
button.appendChild( span ); |
|||
return button; |
|||
} |
} |
||
function votingDraw(d) { |
function votingDraw(d) { |
||
statusEl. |
statusEl.textContent = ''; |
||
btnEl.setLabel(data.strings.savebutton); |
btnEl.setLabel(data.strings.savebutton); |
||
btnEl.setDisabled(false); |
btnEl.setDisabled(false); |
||
Строка 107: | Строка 166: | ||
btnEl.$element.css( 'display', '' ); |
btnEl.$element.css( 'display', '' ); |
||
var |
var co = ( d.query && d.query.usercontribs ) || []; |
||
var co = query.usercontribs; |
|||
// retrieving votes, according to contributions, only latest ones are valid |
// retrieving votes, according to contributions, only latest ones are valid |
||
for (i=0; i<data.candidates.length; i++) { |
for ( var i = 0; i < data.candidates.length; i++ ) { |
||
votes[data.candidates[i]] = {'orig':0, 'value':0}; |
votes[ data.candidates [ i ] ] = { 'orig': 0, 'value': 0 }; |
||
} |
} |
||
for (var i=co.length-1; i>=0; i--) { |
for ( var i = co.length - 1; i >= 0; i-- ) { |
||
var match = false; |
|||
var m = co[i].title.indexOf(data.config.votepath) === 0; |
|||
if ( co[ i ].title.startsWith( data.config.votepath ) ) { |
|||
if (m) { |
|||
match = co[ i ].title.match( /\/([+-])\/(.*?)$/ ); |
|||
} |
} |
||
if ( |
if ( match ) { |
||
var hasSummary = co[ i ].comment === data.strings.summary; |
|||
votes[m[2]] = { 'orig' : m[1]=='+' ? +1 : -1, 'value': 0 }; |
|||
if ( hasSummary ) { |
|||
votes[ match[ 2 ] ] = { |
|||
'orig': match[ 1 ] === '+' ? +1 : -1, |
|||
'value': 0 |
|||
}; |
|||
} |
|||
} |
} |
||
} |
} |
||
var div1 = document.createElement( 'div' ); |
|||
// drawing |
|||
var div1 = el('div'); |
|||
div1.id = 'voting-standard'; |
div1.id = 'voting-standard'; |
||
var help = document.createElement( 'p' ); |
|||
div1.innerHTML = data.strings.votinghelp; |
|||
help.textContent = data.strings.votinghelp; |
|||
var tab = el('table'); |
|||
div1.appendChild( help ); |
|||
var tab = document.createElement( 'table' ); |
|||
var tr, img, td1, td2, td3, lin; |
|||
tab.className = 'voting-table'; |
|||
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; |
|||
var caption = document.createElement( 'caption' ); |
|||
td3.appendChild(lin); |
|||
caption.textContent = data.strings.votebutton; |
|||
tab.appendChild( caption ); |
|||
for ( var candidate in votes ) { |
|||
tr.appendChild(td1); |
|||
if ( candidate.match( /^_[srl]$/ ) ) { |
|||
tr.appendChild(td2); |
|||
continue; |
|||
tab.appendChild(tr); |
|||
} |
} |
||
var tr = document.createElement( 'tr' ); |
|||
var th = document.createElement( 'th' ); |
|||
th.setAttribute( 'scope', 'row' ); |
|||
var lin = document.createElement('a'); |
|||
lin.href = mw.util.getUrl( data.config.talkpath + candidate ); |
|||
lin.target = '_blank'; |
|||
lin.textContent = candidate; |
|||
lin.title = data.strings.questionsTooltip.replace( '%candidate%', candidate ); |
|||
th.appendChild( lin ); |
|||
tr.appendChild( th ); |
|||
// Support button |
|||
var td1 = document.createElement( 'td' ); |
|||
td1.appendChild( addVoteButton( candidate, 'support', votes[ candidate ].orig ) ); |
|||
tr.appendChild( td1 ); |
|||
// Oppose button |
|||
var td2 = document.createElement( 'td' ); |
|||
td2.appendChild( addVoteButton( candidate, 'oppose', votes[ candidate ].orig ) ); |
|||
tr.appendChild( td2 ); |
|||
tab.appendChild( tr ); |
|||
} |
} |
||
div1.appendChild(tab); |
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. |
statusEl.textContent = ''; |
||
$( '#voting-msg-justbeforesave' ).show(); |
|||
statusEl.parentNode.insertBefore(div1, statusEl); |
statusEl.parentNode.insertBefore(div1, statusEl); |
||
} |
} |
||
function showThankYou() { |
|||
containerEl.innerHTML = ''; |
|||
$( '.voting-msg' ).hide(); |
|||
$( '#voting-msg-thankyou' ).show(); |
|||
} |
|||
function votingSave() { |
function votingSave() { |
||
if (!saving) { |
if (!saving) { |
||
var div = |
var div = document.createElement('div'); |
||
div. |
div.className = 'voting-saving'; |
||
div. |
div.textContent = data.strings.saveprog; |
||
div.insertAdjacentHTML( 'afterbegin', '<div class="voting-progress"><div class="voting-progress-progress" style="width:0%"> </div></div>' ); |
|||
statusEl.parentNode.appendChild(div); |
|||
statusEl.parentNode.appendChild( div ); |
|||
btnEl.setDisabled(true); |
|||
btnEl.setDisabled( true ); |
|||
document.getElementById('voting-standard').style.visibility = 'hidden'; |
|||
$( '#voting-standard' ).hide(); |
|||
saving = {'cursor': 0, 'pages': []}; |
saving = { 'cursor': 0, 'pages': [] }; |
||
for (var i in votes) { |
for (var i in votes) { |
||
Строка 206: | Строка 267: | ||
votingSave(); |
votingSave(); |
||
} else { |
} else { |
||
showThankYou(); |
|||
document.getElementById('voting-container').innerHTML = data.strings.thankyou; |
|||
} |
} |
||
} else { |
} else { |
||
Строка 216: | Строка 277: | ||
} |
} |
||
document. |
document.querySelector( '.voting-progress-progress' ).style.width = 100*(saving.cursor+1)/saving.pages.length + '%'; |
||
api.postWithToken('edit', { |
api.postWithToken('edit', { |
||
Строка 222: | Строка 283: | ||
'notminor': 1, |
'notminor': 1, |
||
'unwatch': 1, |
'unwatch': 1, |
||
'assert': 'user', |
|||
'summary': data.strings.summary, |
'summary': data.strings.summary, |
||
'title': saving.pages[saving.cursor].page, |
'title': saving.pages[saving.cursor].page, |
||
Строка 229: | Строка 291: | ||
if (!saving.pages[saving.cursor]) { |
if (!saving.pages[saving.cursor]) { |
||
saving.cursor = -1; |
saving.cursor = -1; |
||
showThankYou(); |
|||
document.getElementById('voting-container').innerHTML = data.strings.thankyou; |
|||
} |
} |
||
} |
} |
||
} |
} |
||
mw.loader.using(['mediawiki.api', 'mediawiki.util', 'oojs', 'oojs-ui']).done(function () { |
|||
// 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.api', 'oojs', 'oojs-ui']).done(function () { |
|||
api = new mw.Api(); |
api = new mw.Api(); |
||
Строка 263: | Строка 308: | ||
// Prepare pages paths |
// Prepare pages paths |
||
data.config.pagepath = data.config.pagepath.replace('%config.path%', data.config.path); |
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.talkpagepath = mw.util.getUrl( data.config.talkpagepath.replace('%config.path%', data.config.path) ); |
||
data.config.talkpath = data.config.talkpath.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.votepath = data.config.votepath.replace('%config.path%', data.config.path); |
||
data.config.voteexceptionspath = data.config.voteexceptionspath.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 |
// Init |
||
containerEl = document.getElementById('voting-container'); |
|||
if ( containerEl ) { |
if ( containerEl ) { |
||
containerEl.innerHTML = ''; |
containerEl.innerHTML = ''; |
||
statusEl = |
statusEl = document.createElement('div'); |
||
statusEl. |
statusEl.className = 'voting-status voting-msg'; |
||
containerEl.appendChild(statusEl); |
containerEl.appendChild( statusEl ); |
||
$( '.voting-msg a' ).attr( 'target', '_blank' ); |
|||
btnEl = new OO.ui.ButtonWidget( { |
btnEl = new OO.ui.ButtonWidget( { |
||
Строка 287: | Строка 331: | ||
} |
} |
||
} ); |
} ); |
||
} |
}); |
Текущая версия от 13:25, 1 августа 2024
/*
* Скрипт для выборов в Арбитражный комитет (ВП:АК)
*
* Авторы: Kalan, Serhio Magpie, stjn
*/
$(function () {
var containerEl = document.getElementById( 'voting-container' );
if ( containerEl === null ) {
mw.log.warn( 'arbcomVoting: Aborted because no voting container was detected.' );
return;
}
var wgUserName = mw.config.get( 'wgUserName' );
if ( wgUserName === null ) {
mw.log.warn( 'arbcomVoting: Not logged in.' );
return;
}
/******* COMMON ******* */
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 = require( './ondemand-arbcomVoting.json' );
var wgNamespaceNumber = mw.config.get( 'wgNamespaceNumber' );
var votes = {};
var saving = null;
var api;
var statusEl;
var btnEl;
/******* MAIN *******/
function votingLength( date, days ) {
var result = new Date( date );
result.setDate( result.getDate() + days );
return result;
}
function votingStart() {
$( '.voting-container' ).addClass( 'active' );
statusEl.textContent = 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.textContent = '';
$( '#voting-msg-criteriafail' ).show();
}
function votingContinue() {
statusEl.textContent = 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'
}).done(votingDraw);
}
function onClick( e ) {
e.preventDefault();
var button = e.currentTarget;
var span = button.querySelector( 'span' );
var tr = button.parentNode.parentNode;
var candidate = button.dataset.candidate;
var type = button.dataset.type;
var active = Boolean( button.getAttribute( 'aria-checked' ) );
var option = data.options[ type ];
// Update other button first
var otherButton = tr.querySelector( `.vote-button[aria-checked="true"]` );
var otherType = otherButton && otherButton.dataset.type;
if ( otherButton ) {
var otherVote = otherType === 'support' ? 1 : -1;
otherButton.setAttribute( 'aria-checked', false );
}
// Change vote
var vote = type === 'support' ? 1 : -1;
var sameVote = votes[ candidate ].value === vote;
votes[ candidate ].value = ( sameVote ? 0 : vote );
button.setAttribute( 'aria-checked', !sameVote );
// Update table row
tr.className = !sameVote ? 'vote-' + type : '';
}
function addVoteButton( candidate, type, previousVote ) {
var option = data.options[ type ];
var didVote = previousVote === ( type === 'support' ? 1 : -1 );
var votedOpposite = previousVote === ( type === 'support' ? -1 : 1 );
var voteType = votedOpposite ? 'changevote' : 'novote';
var button = document.createElement( 'button' );
button.className = 'vote-button skin-invert';
button.setAttribute( 'role', 'switch' );
button.setAttribute( 'type', 'button' );
button.setAttribute( 'data-candidate', candidate );
button.setAttribute( 'data-type', type );
if ( didVote ) {
button.setAttribute( 'data-voted', true );
}
button.setAttribute( 'aria-checked', didVote );
button.addEventListener( 'click', onClick );
var span = document.createElement( 'span' );
span.textContent = option[ voteType ];
if ( votedOpposite ) {
span.textContent = span.textContent.replace( '%candidate%', candidate );
}
button.title = span.textContent;
button.appendChild( span );
return button;
}
function votingDraw(d) {
statusEl.textContent = '';
btnEl.setLabel(data.strings.savebutton);
btnEl.setDisabled(false);
btnEl.off('click').on('click', votingSave);
btnEl.$element.css( 'display', '' );
var co = ( d.query && d.query.usercontribs ) || [];
// retrieving votes, according to contributions, only latest ones are valid
for ( var 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 match = false;
if ( co[ i ].title.startsWith( data.config.votepath ) ) {
match = co[ i ].title.match( /\/([+-])\/(.*?)$/ );
}
if ( match ) {
var hasSummary = co[ i ].comment === data.strings.summary;
if ( hasSummary ) {
votes[ match[ 2 ] ] = {
'orig': match[ 1 ] === '+' ? +1 : -1,
'value': 0
};
}
}
}
var div1 = document.createElement( 'div' );
div1.id = 'voting-standard';
var help = document.createElement( 'p' );
help.textContent = data.strings.votinghelp;
div1.appendChild( help );
var tab = document.createElement( 'table' );
tab.className = 'voting-table';
var caption = document.createElement( 'caption' );
caption.textContent = data.strings.votebutton;
tab.appendChild( caption );
for ( var candidate in votes ) {
if ( candidate.match( /^_[srl]$/ ) ) {
continue;
}
var tr = document.createElement( 'tr' );
var th = document.createElement( 'th' );
th.setAttribute( 'scope', 'row' );
var lin = document.createElement('a');
lin.href = mw.util.getUrl( data.config.talkpath + candidate );
lin.target = '_blank';
lin.textContent = candidate;
lin.title = data.strings.questionsTooltip.replace( '%candidate%', candidate );
th.appendChild( lin );
tr.appendChild( th );
// Support button
var td1 = document.createElement( 'td' );
td1.appendChild( addVoteButton( candidate, 'support', votes[ candidate ].orig ) );
tr.appendChild( td1 );
// Oppose button
var td2 = document.createElement( 'td' );
td2.appendChild( addVoteButton( candidate, 'oppose', votes[ candidate ].orig ) );
tr.appendChild( td2 );
tab.appendChild( tr );
}
div1.appendChild(tab);
statusEl.textContent = '';
$( '#voting-msg-justbeforesave' ).show();
statusEl.parentNode.insertBefore(div1, statusEl);
}
function showThankYou() {
containerEl.innerHTML = '';
$( '.voting-msg' ).hide();
$( '#voting-msg-thankyou' ).show();
}
function votingSave() {
if (!saving) {
var div = document.createElement('div');
div.className = 'voting-saving';
div.textContent = data.strings.saveprog;
div.insertAdjacentHTML( 'afterbegin', '<div class="voting-progress"><div class="voting-progress-progress" style="width:0%"> </div></div>' );
statusEl.parentNode.appendChild( div );
btnEl.setDisabled( true );
$( '#voting-standard' ).hide();
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 {
showThankYou();
}
} else {
if (saving.cursor === -5) {
saving.cursor = 0;
}
if (saving.cursor === -1) {
return;
}
document.querySelector( '.voting-progress-progress' ).style.width = 100*(saving.cursor+1)/saving.pages.length + '%';
api.postWithToken('edit', {
'action': 'edit',
'notminor': 1,
'unwatch': 1,
'assert': 'user',
'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;
showThankYou();
}
}
}
mw.loader.using(['mediawiki.api', 'mediawiki.util', 'oojs', 'oojs-ui']).done(function () {
api = new mw.Api();
// 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 = mw.util.getUrl( 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);
// Init
if ( containerEl ) {
containerEl.innerHTML = '';
statusEl = document.createElement('div');
statusEl.className = 'voting-status voting-msg';
containerEl.appendChild( statusEl );
$( '.voting-msg a' ).attr( 'target', '_blank' );
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));
}
} );
});