MediaWiki:Gadget-tutoring-enrollment.js
Nota: Depois de publicar, poderá ter de contornar a cache do seu navegador para ver as alterações.
- Firefox / Safari: Pressione Shift enquanto clica Recarregar, ou pressione Ctrl-F5 ou Ctrl-R (⌘-R no Mac)
- Google Chrome: Pressione Ctrl-Shift-R (⌘-Shift-R no Mac)
- Edge: Pressione Ctrl enquanto clica Recarregar, ou pressione Ctrl-F5.
/**
* Gadget para inscrição no programa de tutoria
*
* @author [[w:pt:User:Diego Queiroz]]
* @date 31/out/2014
*/
/* global mediaWiki, jQuery */
( function ( mw, $ ) {
// semáforo que mantém o número de chamadas assíncronas pendentes
var async_pending = 0,
// flags de depuração
permitir_inscricao_tutores = false, // (padrão: false)
pagina_tutoria = 'Wikipédia:Tutoria',
pagina_inscricao = pagina_tutoria + '/Inscritos',
pagina_adotados = pagina_tutoria + '/Adotados',
template_adocao_padrao = pagina_tutoria + '/Adoção padrão',
editnotice_adocao = pagina_tutoria + '/Editnotice adoção',
editnotice_inscricao = pagina_tutoria + '/Editnotice inscrição',
editnotice_inscricaoIP = pagina_tutoria + '/Editnotice inscriçãoIP',
editnotice_inscricaoTutor = pagina_tutoria + '/Editnotice inscriçãoTutor',
editnotice_fimTutoria = pagina_tutoria + '/Editnotice fimTutoria',
predefinicao_novato = 'Novo editor', // esse nome é utilizado em um regex, evitar caracteres "complicados"
// strings a serem formatadas
// campos:
// * {0} -> novato
// * {1} -> tutor
titulo_adocao = 'Adoção de "{0}" no programa de tutoria',
resumo_adocao = 'Adoção de [[Usuário(a):{0}|{0}]] por [[Usuário(a):{1}|{1}]]',
titulo_fim_tutoria = 'Encerramento da tutoria de "{0}"',
resumo_fim_tutoria = 'Encerramento da tutoria de [[Usuário(a):{0}|{0}]] por [[Usuário(a):{1}|{1}]]',
titulo_inscricao = 'Inscrição no programa de tutoria',
novo_titulo,
namespace = mw.config.get( 'wgNamespaceNumber' ),
usuario = mw.config.get( 'wgUserName' ),
novato;
function waitForAsync( done ) {
if ( async_pending > 0 ) {
// existem tarefas pendentes, aguarda 100 ms e checa novamente
setTimeout(function () {
waitForAsync(done);
}, 100);
} else {
// nenhuma tarefa pendente, executa o código
done && done();
}
}
function formatStr(str, obj) {
// função adaptada de http://stackoverflow.com/questions/2534803/string-format-in-javascript#2534828
return str.replace(/\{([^}\s]+)\}/g, function (m, p1) {
return obj[p1];
});
}
function getWikiText( title, ok, err ) {
async_pending++;
(new mw.Api()).get( {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
indexpageids: true,
titles: title
} )
.done( function ( data ) {
var q = data.query,
id = q && q.pageids && q.pageids[ 0 ],
pg = id && q.pages && q.pages[ id ],
rv = pg && pg.revisions;
if ( rv && rv[ 0 ] && rv[ 0 ][ '*' ] ) {
ok && ok( rv[ 0 ][ '*' ] );
}
async_pending--;
} )
.fail( function () {
err && err();
async_pending--;
});
}
function editPage( title, text, summary, ok, err ) {
async_pending++;
(new mw.Api()).post( {
action: 'edit',
title: title,
text: text,
summary: summary,
token: mw.user.tokens.get( 'csrfToken' )
} )
.done( function () {
ok && ok();
async_pending--;
})
.fail( function () {
err && err();
async_pending--;
});
}
function remove_inscricao(novato, tutor, pagina, resumo) {
getWikiText(pagina, function (txt) {
// ajusta o nome do usuário para ser incorporado ao regex (escapa caracteres "complicados")
novato = novato.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
var pattern = new RegExp('{{' + predefinicao_novato + ' *[|] *' + novato + ' *[|].*?}}\n?\n?', 'g');
txt = txt.replace(pattern, '');
editPage(pagina, txt, formatStr(resumo, [novato, tutor]) );
});
}
function inserir_adocao(novato, tutor, pagina, resumo) {
var conteudo = formatStr('\n{{subst:' + template_adocao_padrao + '|{0}|{1}}}', [novato, tutor]);
// FIXME: se houver erro na execução do script (ex. problemas na conexão)
// o conteúdo é inserido duas vezes
// Solução: Verificar antes se a adoção já não foi inserida
async_pending++;
(new mw.Api()).post( {
action: 'edit',
minor: false,
title: pagina,
appendtext: conteudo,
summary: formatStr(resumo, [novato, tutor]),
token: mw.user.tokens.get( 'csrfToken' )
} )
.done( function () {
// ok && ok();
async_pending--;
} )
.fail( function () {
// err && err();
async_pending--;
} );
}
function insere_conteudo(pagina, elemento) {
async_pending++;
(new mw.Api()).get( {
action: 'parse',
page: pagina
})
.done( function (data) {
var conteudoHTML = data.parse.text['*'];
$(elemento).prepend(conteudoHTML);
async_pending--;
} )
.fail( function () {
// err && err();
async_pending--;
});
}
function check_permission(user, permission, ifTrue, ifFalse, alwaysFalse) {
// parâmetro "alwaysFalse" é opcional e é utilizado para depuração somente
// força que "ifFalse" seja sempre executado
// independente das permissões do usuário
ifTrue = ifTrue || function () {};
ifFalse = ifFalse || function () {};
async_pending++;
(new mw.Api()).get( {
action: 'query',
list: 'users',
usprop: 'rights',
continue: '',
ususers: user
})
.done( function (data) {
var permissions = data.query.users[0].rights;
if ( !alwaysFalse && $.inArray(permission, permissions) != -1 ) {
ifTrue(permissions);
} else {
ifFalse(permissions);
}
async_pending--;
} )
.fail(function () {
// err && err();
async_pending--;
});
}
function getParameterByName(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'),
results = regex.exec(location.search);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
}
if (namespace == 3) { // namespace "User talk:"
// Nome do novato é o título da página
novato = mw.config.get( 'wgTitle' );
// parâmetro "&tutoring=end" passado na URL para diferenciar a incrição da finalização da tutoria
if ( getParameterByName('tutoring') != 'end' ) {
// Tutor está ADOTANDO um novato
novo_titulo = formatStr(titulo_adocao, [novato, usuario]);
// marca a caixa de seleção "Vigiar"
$( '#wpWatchthis' ).prop( 'checked', true );
// altera o texto do botão de salvar
$( '#wpSave' ).val( 'Confirmar adoção' );
// insere conteúdo da página de adoção
insere_conteudo(editnotice_adocao, '#mw-content-text');
// faz com que o botão salvar também exclua o usuário adotado da
// lista de inscritos
$( '#wpSave' ).click( function (e) {
remove_inscricao(novato, usuario, pagina_inscricao, resumo_adocao);
inserir_adocao(novato, usuario, pagina_adotados, resumo_adocao);
// sem as linhas a seguir, não funciona às vezes
// evita que a página seja salva antes de gravar as alterações assíncronas
e.preventDefault();
$(this)
.off(e)
.prop('disabled', true);
var thisSelector = '#' + this.id;
waitForAsync( function () {
$(thisSelector).prop('disabled', false);
// código sequenciado por "setTimeout" devido a
// http://bugs.jquery.com/ticket/14892
setTimeout(function () {
$(thisSelector).click();
setTimeout(function () {
$(thisSelector).prop('disabled', true);
}, 10);
}, 10);
} );
//
} );
} else {
// Tutor ENCERRANDO a tutoria
novo_titulo = formatStr(titulo_fim_tutoria, [novato, usuario]);
// altera o texto do botão de salvar
$( '#wpSave' ).val( 'Confirmar encerramento' );
// insere conteúdo do editnotice de fim de tutoria
insere_conteudo(editnotice_fimTutoria, '#mw-content-text');
$( '#wpSave' ).click( function (e) {
remove_inscricao(novato, usuario, pagina_adotados, resumo_fim_tutoria);
// colocar em algum lugar os Ex-tutorados?? (lista de ex-tutorados?)
// * inserir_adocao(novato, usuario, <<PAGINA>>, <<RESUMO>> );
// sem as linhas a seguir, não funciona às vezes
// evita que a página seja salva antes de gravar as alterações assíncronas
e.preventDefault();
$(this)
.off(e)
.prop('disabled', true);
var thisSelector = '#' + this.id;
waitForAsync( function () {
$(thisSelector).prop('disabled', false);
// código sequenciado por "setTimeout" devido a
// http://bugs.jquery.com/ticket/14892
setTimeout(function () {
$(thisSelector).click();
setTimeout(function () {
$(thisSelector).prop('disabled', true);
}, 10);
}, 10);
} );
//
} );
// altera classe dos botões
$( '#wpSave' ).addClass( 'mw-ui-button mw-ui-destructive' );
}
} else {
// esta parte do código é executado quando um usuário registrado
// está se INSCREVENDO na tutoria
novo_titulo = formatStr(titulo_inscricao, [usuario, '']);
// altera o texto do botão de salvar
$( '#wpSave' ).val( 'Confirmar inscrição' );
if ( usuario === null ) {
// IP tentando se inscrever na tutoria
// não permitir a inscrição e inserir mensagem personalizada
// desativa botão salvar
$('#wpSave').prop('disabled', true);
// insere conteúdo para usuários IPs
insere_conteudo(editnotice_inscricaoIP, '#mw-content-text');
} else {
// usuário registrado tentando se inscrever na tutoria
// determina o conteúdo a ser exibido de acordo com as permissões do usuário
check_permission(usuario, 'autoreviewer', function () {
// usuário é experiente (possui permissão de autorrevisor)
// *** observar que é verificada a PERMISSÃO e não o GRUPO ***
// *** logo, sysops e eliminadores possuem a permissão ***
// desativa botão salvar para impedir que tutores se inscrevam
$('#wpSave').prop('disabled', true);
// insere conteúdo para usuários experientes
insere_conteudo(editnotice_inscricaoTutor, '#mw-content-text');
}, function () {
// usuário é novato
// desmarca a caixa de seleção "Vigiar"
$( '#wpWatchthis' ).prop( 'checked', false );
// insere conteúdo para usuários novatos
insere_conteudo(editnotice_inscricao, '#mw-content-text');
}, permitir_inscricao_tutores); // força a execução do primeiro bloco se essa flag for "true"
}
}
// altera o comportamento do botão cancelar
$( '#mw-editform-cancel' ).click( function (e) {
e.preventDefault();
history.back();
} );
// altera o título da página e da aba no navegador
$( '#firstHeading' ).children( 'span' ).text( novo_titulo );
document.title = novo_titulo + document.title.replace(/[^–]*/, ' ');
// altera a propriedade "title" do botão salvar
$('#wpSave').prop('title', $('#wpSave').val() + ' [alt-shift-s]');
} ( mediaWiki, jQuery ) );